Fresh IDE . Changes On Branch ffeeb8d93709bf87
Not logged in

This repository is a mirror!

The original is located on: https://fresh.flatassembler.net/fossil/repo/fresh
If you want to follow the project, please update your remote-url

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch NewWidgets Through [ffeeb8d937] Excluding Merge-Ins

This is equivalent to a diff from 10fcf3a92e to ffeeb8d937

2015-11-21
17:14
Mouse selection for TEdit control and also caret problems fixed (?). check-in: a209b18030 user: johnfound tags: NewWidgets
11:37
Work on TEdit. Procedure BlendSolidRect has been implemented. check-in: ffeeb8d937 user: johnfound tags: NewWidgets
2015-11-20
21:24
Some trick with the message processing in order to stop keyboard buffer overflow on slow machines. check-in: 8cc10ecdd8 user: johnfound tags: NewWidgets
2015-05-26
18:36
A branch for experiments with new architecture for the GUI widgets. The idea is to not use the OS provided windows, but to make our own windows structure and to keep the OS provided windows only for the top-level windows. This solution will be biger and more complex, but will be faster, more portable and allows full featured GUI even for systems with rudimentary windows features. check-in: 681971e932 user: johnfound tags: NewWidgets
2015-03-11
12:44
Work on the font and text handling in Linux using FreeType library. Closed-Leaf check-in: 10fcf3a92e user: johnfound tags: FreshLibGUI
2015-02-24
18:04
Fixed some issues with font rendering in all modes: mono, gray, lcd and rgba(not tested). The blending of the alpha values is now properly implemented. Some MMX optimizations. check-in: 6fc7f25125 user: johnfound tags: FreshLibGUI

Changes to freshlib/TestFreshLib.fpr.

cannot compute difference between binary files

Added freshlib/_doc/CheckListFresh3.txt.






























1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Legend:

[+] - Fully implemented (more or less).
[?] - Partially implemented/work in progress.
[ ] - Not even started.

Needed GUI controls in order to start work on Fresh IDE 3.0:

  [+]   TForm
  [+]   TSplitGrid
  [+]   TAction (and Action lists)
  [+]   TButton
  [+]   TCheckbox
  [?]   TTreeView
  [ ]   TabControl
  [?]   TSourceEditor
  [ ]   TToolbar
  [?]   TMenu
  [ ]   TMenuBar
  [ ]   TStatusbar
  [+]   TProgressbar
  [ ]   TListView, TListbox or other kind of table/grid control with columns.
  [?]   TEdit - line editor
  [ ]   THint

  [+]   General message dialog.
  [ ]   Open/Save dialogs.
  [ ]   Color selection dialog. (not so important).
  [ ]   Font select dialog.

Changes to freshlib/data/all.asm.
1
2
3

4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
11



+







include 'i18n.asm'
include 'arrays.asm'
include 'strlib.asm'
include 'base64.asm'
include 'uconfig.asm'
include 'memstream.asm'
include 'markdown.asm'
include 'hashes.asm'

include 'bitstream.asm'
include 'bytestream.asm'
Changes to freshlib/data/arrays.asm.
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675

676
677
678
679
680
649
650
651
652
653
654
655

656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674

675
676
677
678
679
680







-
+


















-
+





; Frees all elements of the list calling
; [FreeProc] on every element.
; (proc FreeProc, ptrItem)
; Frees the array of items
;--------------------------------------------
proc ListFree, .ptrList, .FreeProc
begin
        push    edi ebx
        pushad

        mov     edi, [.ptrList]
        mov     ebx, [edi+TArray.count]

        cmp     [.FreeProc], 0
        je      .endwhile

.freeloop:
        dec     ebx
        js      .endwhile

        stdcall [.FreeProc], [edi+4*ebx+TArray.array]
        jmp     .freeloop

.endwhile:
        stdcall FreeMem, edi

.finish:
        pop     ebx edi
        popad
        return
endp


endmodule
Added freshlib/data/base64.asm.











































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: OS independent string manipulation library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Author of this library is Decard (Mateusz Tymek)
;
;_________________________________________________________________________________________

module "Base64 library"

if used base64_table
  base64_table db "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
               db "abcdefghijklmnopqrstuvwxyz"
               db "0123456789+/"
end if


; calculates size of base64 stream after encoding

proc Base64Size, .DataLen
begin
        push    ebx ecx edx

        mov     eax, [.DataLen]
        mov     ebx, eax
        add     eax, 2

        xor     edx, edx

        mov     ecx, 3
        div     ecx

        add     ebx, 3

        sub     ebx, edx

        mov     eax, ebx

        xor     edx, edx
        div     ecx
        shl     eax, 2

        pop     edx ecx ebx
        return
endp


; encodes given buffer into base64 stream

proc EncodeBase64, .pData, .Length
begin
        push    ecx edx esi edi

        mov     esi, [.pData]
        mov     ecx, [.Length]

        stdcall StrNew
        mov     edi, eax

        stdcall Base64Size, ecx
        stdcall StrSetCapacity, edi, eax

        push    edi

        stdcall StrPtr, edi
        mov     edi, eax

        push    edi

.loop:
        mov     edx, [esi]
        cmp     ecx, 3
        jae     .remainder_ok
        and     edx, 0xffff
        cmp     ecx, 2
        jae     .remainder_ok
        and     edx, 0xff

.remainder_ok:
        bswap   edx

        mov     eax, edx
        shr     eax, 26
        and     eax, 111111b
        mov     al, [base64_table+eax]
        mov     [edi], al
        inc     edi

        mov     eax, edx
        shr     eax, 20
        and     eax, 111111b
        mov     al, [base64_table+eax]
        mov     [edi], al
        inc     edi
        dec     ecx
        jz      .r2

        mov     eax, edx
        shr     eax, 14
        and     eax, 111111b
        mov     al, [base64_table+eax]
        mov     [edi], al
        inc     edi
        dec     ecx
        jz      .r1

        mov     eax, edx
        shr     eax, 8
        and     eax, 111111b
        mov     al, [base64_table+eax]
        mov     [edi], al
        inc     edi

        add     esi, 3
        dec     ecx
        jnz     .loop
        jmp     .finish

.r2:
        mov     byte [edi], '-'
        inc     edi

.r1:
        mov     byte [edi], '-'
        inc     edi

.finish:
        mov     byte [edi], 0

        mov     ecx, edi
        pop     edi

        sub     ecx, edi    ; string length.
        mov     [edi+string.len], ecx

        pop     eax             ; string handle

        pop     edi esi edx ecx
        return
endp





; decodes base64 stream into given buffer

proc DecodeBase64, .hString
.decode_table rb 0x100
.ret          dd ?
begin
        push    ebx ecx edx esi edi

        xor     eax, eax
        mov     ebx, 63

.make_table:
        mov     al, [base64_table+ebx]
        mov     [.decode_table+eax], bl
        dec     ebx
        jns     .make_table

        mov     [.decode_table+'-'], 0

        stdcall StrPtr, [.hString]
        mov     esi, eax

        stdcall StrLen, [.hString]
        mov     ecx, eax

        lea     eax, [ecx+4]
        stdcall GetMem, eax
        lea     edi, [eax+4]
        mov     [.ret], edi

        xor     ebx, ebx
        xor     eax, eax

.load_dword:
        mov     edx, [esi]
        bswap   edx
        add     esi, 4
        mov     al, dl
        mov     al, [.decode_table+eax]
        shrd    ebx, eax, 6
        shr     edx, 8
        mov     al, dl
        mov     al, [.decode_table+eax]
        shrd    ebx, eax, 6
        shr     edx, 8
        mov     al, dl
        mov     al, [.decode_table+eax]
        shrd    ebx, eax, 6
        shr     edx, 8
        mov     al, dl
        mov     al, [.decode_table+eax]
        shrd    ebx, eax, 6
        bswap   ebx

        mov     [edi], ebx
        add     edi, 3
        sub     ecx, 4
        js      .exit_loop      ; this jump should be never taken
        jnz     .load_dword     ; (src_size should be a multiple of four)

.exit_loop:
        sub     edi, 2
        cmp     byte [edi], 0
        je      .size_ok

        inc     edi
        cmp     byte [edi], 0
        je      .size_ok

        inc     edi

.size_ok:
        mov     eax, [.ret]
        sub     edi, eax
        mov     [eax-4], edi

        pop     edi esi edx ecx ebx
        return
endp



endmodule
Changes to freshlib/data/deflate.asm.
101
102
103
104
105
106
107

108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137

138


139

140
141
142
143
144
145
146
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150







+




+


-












-
+










+
-
+
+

+








@@:

; read 2 bit header BTYPE
        mov     edx, eax
        shr     eax, 2
        and     edx, 3

        sub     ch, 2

        dec     edx
        js      .uncompressed     ; BTYPE == 0 uncompressed type

        mov     [.b_type], edx    ; 0 if fixed tree; <>0 if dynamic tree
        jnz     .dynamic_tree


; BTYPE == 1 compressed with fixed huffman tree.

; load the fixed huffman tree for literal/lengths.
        pushad

        lea     edi, [.lengths]
        lea     esi, [.TreeFixed]
        mov     ebx, edi

        xor     eax, eax
        xor     ecx, ecx
        mov     dl, 4
        mov     dl, 4      ; edx == 0 here.

.loop_fx:
        lodsw
        mov     cl, ah
        rep stosb
        dec     edx
        jnz     .loop_fx

        sub     edi, ebx
        lea     eax, [.len_tree]

        stdcall __tree_by_lengths2, ebx, edi, eax
        stdcall __tree_by_lengths, ebx, edi, eax

        popad

        jmp     .decode


.dynamic_tree:
        dec     edx
        jnz     .error3           ; BTYPE == 3 invalid block type

219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237







-
+







        rol     eax, cl

@@:
        dec     edx
        jnz     .loop_hc

        lea     ebx, [.ll_tree]
        stdcall __tree_by_lengths2, edi, 19, ebx
        stdcall __tree_by_lengths, edi, 19, ebx
        jnz     .error6

; now create the two remaining huffman trees: for literal/lengths and for distances.

; First the literal/lengths huffman tree

        mov     edx, [.LLCount]
270
271
272
273
274
275
276




277
278
279
280
281
282
283
284
285


286
287
288
289
290
291
292
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302







+
+
+
+









+
+







        xor     edx, [.len_tree+4*edx]
        jns     .bitloop1

        not     edx

        cmp     edx, 255
        ja      .copy_from_older        ; if EDX <= 255 then it is simple encoded byte, so store it.


;        OutputValue "Literal: ", edx, 16, 2


; Store literal value.
        mov     [edi], dl
        inc     edi
        jmp     .decode



.copy_from_older:
;        OutputValue "Length code:", edx, 10, 3

        sub     edx, 257
        js      .next_block             ; if EDX == 256 then end of block flag.

; The code is a length code. Compute the length of string to be copied from the previous decoded data.

; Compute the additional length and the extra bit count.
; 2^n(4 + edx mod 4)
314
315
316
317
318
319
320


321
322
323
324
325
326
327
328
329
330
331
332
333



334
335
336
337
338
339
340
341
342






343
344




345
346
347
348
349
350
351
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355


356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
372
373







+
+













+
+
+







-
-
+
+
+
+
+
+

-
+
+
+
+







        or      edx, -1
        shl     edx, cl
        not     edx

        and     edx, eax
        shr     eax, cl

;        OutputValue "Additional value:", edx, 10, 2

        sub     ch, cl
        jg      .length_ok

        add     esi, 2

        mov     cl, ch
        mov     eax, [esi]
        add     ch, $10
        rol     eax, cl

.length_ok:
        lea     ebx, [ebx+edx+3]


;        OutputValue "Copy length:", ebx, 10, 3

; ... so now decode the distance code

        cmp     [.b_type], 0
        jne     .decode_dist  ; when there is fixed huffman table, then the distances are encoded with 5 bit fixed code

; read fixed 5 bit distance.

        mov     edx, eax
        shr     eax, 5
        mov     cl, 5
        xor     edx, edx

.bitloop4:
        shr     eax, 1
        rcl     edx, 1

        and     edx, $1f
        dec     cl
        jnz     .bitloop4

;        OutputValue "Distance code:", edx, 10, 2

        sub     ch, 5
        jg      .compute_distance

        add     esi, 2

        mov     cl, ch
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494
501
502
503
504
505
506
507

508

509
510
511
512
513
514
515







-
+
-







        not     [.final]          ; Tricky makes CF=1 on exit.

.next_block:
        mov     [.pCurrent], edi
        cmp     [.final], 0
        je      .main_loop

; free the memory and exit!
; exit!
;        stdcall FreeMem;  , [.p_len_tree] ; argument is already in the stack!

        shl     [.final], 1      ; If normal end [.final] is always 1; If error, [.final] is $ffffffff or $fffffffe

        popad
        return


618
619
620
621
622
623
624
625

626
627
628
629
630
631
632
639
640
641
642
643
644
645

646
647
648
649
650
651
652
653







-
+







        jnz     .rep_loop

; next length
        cmp     edi, [.p_lengths_end]
        jb      .loop_len
        ja      .errordl

        stdcall __tree_by_lengths2   ; the arguments are already in the stack.
        stdcall __tree_by_lengths   ; the arguments are already in the stack.
        retn

; The assembly way of error handling. ;)
.errordl:
        add     esp, 3*4 + 4 ; pushed arguments and the return address.
        jmp     .error

657
658
659
660
661
662
663
664

665
666
667
668
669
670
671
678
679
680
681
682
683
684

685
686
687
688
689
690
691
692







-
+







;         and contains NOT-ed symbol value instead of index in the array.
;
;   ZF=0  Error. The provided length list describes not valid Huffman tree.
;         In this case no values are filled in the tree.
;
; The comments in the code are according to the RFC-1951
;
proc __tree_by_lengths2, .pLengths, .count, .pTree
proc __tree_by_lengths, .pLengths, .count, .pTree

.bl_count  rd DEFLATE_MAX_BITS + 1
.next_code rd DEFLATE_MAX_BITS + 1      ; keep immediately after .bl_count

begin
        pushad

Changes to freshlib/data/strlib.asm.
2351
2352
2353
2354
2355
2356
2357
2358

2359
2360
2361
2362
2363
2364
2365
2351
2352
2353
2354
2355
2356
2357

2358
2359
2360
2361
2362
2363
2364
2365







-
+







endp



;_______________________________________________________________________
; proc StrClipQuotes
;   First removes the spaced from the beginning and from the end of the
;   string. Then chech whether the string is quoted string - i.e. starts
;   string. Then check whether the string is quoted string - i.e. starts
;   and ends with equal characters single or double quote. If so, removes
;   them as well.
;
; Arguments:
;   hString - string to be processed
; Returns:
;   CF=1 - invalid string handle.
2739
2740
2741
2742
2743
2744
2745


2746

2747
2748
2749
2750
2751
2752
2753
2739
2740
2741
2742
2743
2744
2745
2746
2747

2748
2749
2750
2751
2752
2753
2754
2755







+
+
-
+









; UTF-8 support functions.
; Some of the above functions also need some revision in order to support
; utf-8 strings properly.




;  Bug - on [.len]=-1 sometimes in Linux returns error on normal strings.
;!  Bug - on [.len]=-1 sometimes in Linux returns error on normal strings.

proc StrLenUtf8, .hString, .len
.maxptr dd ?
begin
        push    esi ecx edx

        stdcall StrPtr, [.hString]
Changes to freshlib/equates/KolibriOS/_geometry.inc.
21
22
23
24
25
26
27








21
22
23
24
25
26
27
28
29
30
31
32
33
34
35







+
+
+
+
+
+
+
+
ends

struct POINT
  .x  dd ?
  .y  dd ?
ends


struct TBounds
  .x      dd ?
  .y      dd ?
  .width  dd ?
  .height dd ?
ends

Added freshlib/equates/KolibriOS/_libFT.inc.

































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: FreeType library constants and structures.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


FT_FACE_FLAG_SCALABLE           = $0001
FT_FACE_FLAG_FIXED_SIZES        = $0002
FT_FACE_FLAG_FIXED_WIDTH        = $0004
FT_FACE_FLAG_SFNT               = $0008
FT_FACE_FLAG_HORIZONTAL         = $0010
FT_FACE_FLAG_VERTICAL           = $0020
FT_FACE_FLAG_KERNING            = $0040
FT_FACE_FLAG_FAST_GLYPHS        = $0080
FT_FACE_FLAG_MULTIPLE_MASTERS   = $0100
FT_FACE_FLAG_GLYPH_NAMES        = $0200
FT_FACE_FLAG_EXTERNAL_STREAM    = $0400
FT_FACE_FLAG_HINTER             = $0800
FT_FACE_FLAG_CID_KEYED          = $1000
FT_FACE_FLAG_TRICKY             = $2000


FT_LOAD_DEFAULT                         =  $0
FT_LOAD_NO_SCALE                        =  $1
FT_LOAD_NO_HINTING                      =  $2
FT_LOAD_RENDER                          =  $4
FT_LOAD_NO_BITMAP                       =  $8
FT_LOAD_VERTICAL_LAYOUT                 =  $10
FT_LOAD_FORCE_AUTOHINT                  =  $20
FT_LOAD_CROP_BITMAP                     =  $40          ; deprecated, ignored
FT_LOAD_PEDANTIC                        =  $80
FT_LOAD_ADVANCE_ONLY                    =  $100
FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH     =  $200         ; deprecated, ignored
FT_LOAD_NO_RECURSE                      =  $400
FT_LOAD_IGNORE_TRANSFORM                =  $800
FT_LOAD_MONOCHROME                      =  $1000
FT_LOAD_LINEAR_DESIGN                   =  $2000
FT_LOAD_SBITS_ONLY                      =  $4000
FT_LOAD_NO_AUTOHINT                     =  $8000
FT_LOAD_COLOR                           =  $100000

FT_ADVANCE_FLAG_FAST_ONLY               =  $20000000


FT_RENDER_MODE_NORMAL = 0
FT_RENDER_MODE_LIGHT  = 1
FT_RENDER_MODE_MONO   = 2
FT_RENDER_MODE_LCD    = 3
FT_RENDER_MODE_LCD_V  = 4
FT_RENDER_MODE_MAX    = 5

struc FT_LOAD_TARGET x {
  . = (x and 15) shl 16
}

FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET  FT_RENDER_MODE_NORMAL
FT_LOAD_TARGET_LIGHT  FT_LOAD_TARGET  FT_RENDER_MODE_LIGHT
FT_LOAD_TARGET_MONO   FT_LOAD_TARGET  FT_RENDER_MODE_MONO
FT_LOAD_TARGET_LCD    FT_LOAD_TARGET  FT_RENDER_MODE_LCD
FT_LOAD_TARGET_LCD_V  FT_LOAD_TARGET  FT_RENDER_MODE_LCD_V



FT_PIXEL_MODE_NONE  = 0
FT_PIXEL_MODE_MONO  = 1
FT_PIXEL_MODE_GRAY  = 2
FT_PIXEL_MODE_GRAY2 = 3
FT_PIXEL_MODE_GRAY4 = 4
FT_PIXEL_MODE_LCD   = 5
FT_PIXEL_MODE_LCD_V = 6
FT_PIXEL_MODE_BGRA  = 7


struct FT_Generic
  .data         dd ?
  .finalizer    dd ?    ; pointer to procedure with one argument.
ends

struct FT_BBox
  .xMin         dd ?
  .yMin         dd ?
  .xMax         dd ?
  .yMax         dd ?
ends

struct FT_Vector
  .x dd ?
  .y dd ?
ends

struct FT_Bitmap
  .rows         dd ?
  .width        dd ?
  .pitch        dd ?
  .buffer       dd ?    ; pointer to the buffer.
  .num_grays    dw ?
  .pixel_mode   db ?
  .palette_mode db ?
  .palette      dd ?    ; pointer to the palette.
ends




struct FT_Outline
  .n_contours  dw  ?
  .n_points    dw  ?
  .points      dd  ?    ; pointer to array of FT_Vector elements.
  .tags        dd  ?    ; pointer to byte array.
  .contours    dd  ?    ; pointer to word array.
  .flags       dd  ?
ends



struct  FT_Glyph_Metrics
  .width        dd ?
  .height       dd ?
  .horiBearingX dd ?
  .horiBearingY dd ?
  .horiAdvance  dd ?

  .vertBearingX dd ?
  .vertBearingY dd ?
  .vertAdvance  dd ?
ends



struct FT_GlyphSlot
  .library      dd ?
  .face         dd ?    ; parent FT_Face object
  .next         dd ?    ; pointer tp FT_GlyphSlot
  .reserved     dd ?
  .generic      FT_Generic

  .metrics      FT_Glyph_Metrics
  .linearHoriAdvance dd ?
  .linearVertAdvance dd ?

  .advance      FT_Vector

  .format       dd ?

  .bitmap       FT_Bitmap
  .bitmap_left  dd ?
  .bitmap_top   dd ?

  .outline      FT_Outline

  .num_subglyphs dd ?
  .subglyphs     dd ?   ; pointer to array of FT_SubGlyphRec elements.

  .control_data  dd ?
  .control_len   dd ?

  .lsb_delta     dd ?
  .rsb_delta     dd ?

  .other         dd ?
  .internal      dd ?   ; pointer to FT_Slot_InternalRec
ends


struct FT_FaceRec
  .num_faces    dd ?
  .face_index   dd ?
  .face_flags   dd ?
  .style_flags  dd ?
  .num_glyphs   dd ?
  .family_name  dd ?
  .style_name   dd ?

  .num_fixed_sizes dd ?
  .available_sizes dd ?

  .num_charmaps dd ?
  .charmaps     dd ?
  .generic      FT_Generic

; scalable fonts members down to .underline_thickness

  .bbpx                 FT_BBox

  .units_per_EM         dw ?
  .ascender             dw ?
  .descender            dw ?
  .height               dw ?

  .max_advance_width    dw ?
  .max_advance_height   dw ?

  .underline_position   dw ?
  .underline_thickness  dw ?


  .glyph        dd  ?   ; pointer to FT_GlyphSlot
  .size         dd  ?   ; pointer to FT_Size
  .charmap      dd  ?   ; pointer to FT_CharMap

; down is the private part.

ends


struct FT_GlyphRec
  .library      dd      ?
  .clazz        dd      ?
  .format       dd      ?
  .advance      FT_Vector
ends


struct FT_BitmapGlyphRec
  .root         FT_GlyphRec
  .left         dd ?
  .top          dd ?
  .bitmap       FT_Bitmap
ends


FT_SIZE_REQUEST_TYPE_NOMINAL    = 0
FT_SIZE_REQUEST_TYPE_REAL_DIM   = 1
FT_SIZE_REQUEST_TYPE_BBOX       = 2
FT_SIZE_REQUEST_TYPE_CELL       = 3
FT_SIZE_REQUEST_TYPE_SCALES     = 4


struct FT_Size_RequestRec
  .type            dd  ?
  .width           dd  ?
  .height          dd  ?
  .horiResolution  dd  ?
  .vertResolution  dd  ?
ends


struct FT_Size_Metrics
  .x_ppem       dw      ?       ; horizontal pixels per EM
  .y_ppem       dw      ?       ; vertical pixels per EM

  .x_scale      dd      ?       ; scaling values used to convert font
  .y_scale      dd      ?       ; units to 26.6 fractional pixels

  .ascender     dd      ?       ; ascender in 26.6 frac. pixels
  .descender    dd      ?       ; descender in 26.6 frac. pixels
  .height       dd      ?       ; text height in 26.6 frac. pixels
  .max_advance  dd      ?       ; max horizontal advance, in 26.6 pixels
ends


struct FT_SizeRec
  .face         dd  ?           ; parent face object
  .generic      FT_Generic      ; generic pointer for client uses
  .metrics      FT_Size_Metrics ; size metrics
  .internal:
ends


struct FTC_ScalerRec
  .face_id dd ?
  .width   dd ?
  .height  dd ?
  .pixel   dd ?
  .x_res   dd ?
  .y_res   dd ?
ends


struct FTC_ImageType
  .face_id  dd  ?
  .width    dd  ?
  .height   dd  ?
  .flags    dd  ?
ends




interface FT_Face_Requester, .face_id, .library, .request_data, .pFace
Changes to freshlib/equates/KolibriOS/_network.inc.
25
26
27
28
29
30
31






32
33
34
35
36
37
38
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44







+
+
+
+
+
+







SO_KEEPALIVE            = 1 shl 4
SO_OOBINLINE            = 1 shl 5
SO_REUSEADDR            = 1 shl 6
SO_REUSEPORT            = 1 shl 7
SO_USELOOPBACK          = 1 shl 8
SO_BINDTODEVICE         = 1 shl 9
SO_BLOCK                = 1 shl 10

SO_RCVBUF = 0
SO_SNDBUF = 0
SO_RCVTIMEO = 0
SO_SNDTIMEO = 0
SO_LINGER = 0

; Socket level
SOL_SOCKET              = 0

; Socket States
SS_NOFDREF              = 0x001       ; no file table ref any more
SS_ISCONNECTED          = 0x002       ; socket connected to a peer
Changes to freshlib/equates/KolibriOS/_syscalls.inc.















1
2
3
4
5
6
7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license.           |
;|_______________________________________________________________________________________|
;
;  Description: KolibriOS system functions and related constants.
;
;  Target OS: KolibriOS
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


sys_drawwindow          =   0     ;  DrawWindow
syscall_setpixel        =   1     ;  SetPixel
sys_getkey              =   2     ;  GetKey
sys_clock               =   3     ;  GetTime
sys_writetext           =   4     ;  WriteText
sys_delay_hs            =   5     ;  DelayHs
sys_openramdiskfile     =   6     ;  OpenRamdiskFile
Changes to freshlib/equates/KolibriOS/allequates.inc.
12
13
14
15
16
17
18

12
13
14
15
16
17
18
19







+
;  Notes:
;_________________________________________________________________________________________


include '_syscalls.inc'
include '_geometry.inc'
include '_network.inc'
include '_libFT.inc'
Changes to freshlib/equates/Linux/_XLib.inc.
419
420
421
422
423
424
425








426
427
428
429
430
431
432
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440







+
+
+
+
+
+
+
+







GCClipYOrigin   =       40000h
GCClipMask      =       80000h
GCDashOffset    =       100000h
GCDashList      =       200000h
GCArcMode       =       400000h

GCLastBit       =       22

struct XRectangle
  .x       dw  ?
  .y       dw  ?
  .width   dw  ?
  .height  dw  ?
ends


GCAll = (1 shl (GCLastBit+1)) -1

struct XGCValues
  .function    dd ?                     ;  logical operation
  .plane_mask  dd ?                     ;  plane mask
  .foreground  dd ?                     ;  foreground pixel
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140

























































































































1141
1142
1143
1144
1145
1146
1147
1021
1022
1023
1024
1025
1026
1027

























































































































1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







struct XEvent
  .xany XAnyEvent
  .pad  rb 24*4 - sizeof.XAnyEvent

  virtual at .xany
  . XAnyEvent
  end virtual


  virtual at .xany
  .xkey XKeyEvent
  end virtual

  virtual at .xany
  .xbutton XButtonEvent
  end virtual

  virtual at .xany
  .xmotion XMotionEvent
  end virtual

  virtual at .xany
  .xcrossing XCrossingEvent
  end virtual

  virtual at .xany
  .xfocus XFocusChangeEvent
  end virtual

  virtual at .xany
  .xexpose XExposeEvent
  end virtual

  virtual at .xany
  .xgraphicsexpose XGraphicsExposeEvent
  end virtual

  virtual at .xany
  .xnoexpose XNoExposeEvent
  end virtual

  virtual at .xany
  .xvisibility XVisibilityEvent
  end virtual

  virtual at .xany
  .xcreatewindow XCreateWindowEvent
  end virtual

  virtual at .xany
  .xdestroywindow XDestroyWindowEvent
  end virtual

  virtual at .xany
  .xunmap XUnmapEvent
  end virtual

  virtual at .xany
  .xmap XMapEvent
  end virtual

  virtual at .xany
  .xmaprequest XMapRequestEvent
  end virtual

  virtual at .xany
  .xreparent XReparentEvent
  end virtual

  virtual at .xany
  .xconfigure XConfigureEvent
  end virtual

  virtual at .xany
  .xgravity XGravityEvent
  end virtual

  virtual at .xany
  .xresizerequest XResizeEvent
  end virtual

  virtual at .xany
  .xconfigurerequest XConfigureRequestEvent
  end virtual

  virtual at .xany
  .xcirculate XCirculateEvent
  end virtual

  virtual at .xany
  .xcirculaterequest XCirculateRequestEvent
  end virtual

  virtual at .xany
  .xproperty XPropertyEvent
  end virtual

  virtual at .xany
  .xselectionclear XSelectionClearEvent
  end virtual

  virtual at .xany
  .xselectionrequest XSelectionRequestEvent
  end virtual

  virtual at .xany
  .xselection XSelectionEvent
  end virtual

  virtual at .xany
  .xcolormap XColormapEvent
  end virtual

  virtual at .xany
  .xclient XClientMessageEvent
  end virtual

  virtual at .xany
  .xmapping XMappingEvent
  end virtual

  virtual at .xany
  .xerror XErrorEvent
  end virtual

  virtual at .xany
  .xkeymap XKeymapEvent
  end virtual
;
;
;  virtual at .xany
;  .xkey XKeyEvent
;  end virtual
;
;  virtual at .xany
;  .xbutton XButtonEvent
;  end virtual
;
;  virtual at .xany
;  .xmotion XMotionEvent
;  end virtual
;
;  virtual at .xany
;  .xcrossing XCrossingEvent
;  end virtual
;
;  virtual at .xany
;  .xfocus XFocusChangeEvent
;  end virtual
;
;  virtual at .xany
;  .xexpose XExposeEvent
;  end virtual
;
;  virtual at .xany
;  .xgraphicsexpose XGraphicsExposeEvent
;  end virtual
;
;  virtual at .xany
;  .xnoexpose XNoExposeEvent
;  end virtual
;
;  virtual at .xany
;  .xvisibility XVisibilityEvent
;  end virtual
;
;  virtual at .xany
;  .xcreatewindow XCreateWindowEvent
;  end virtual
;
;  virtual at .xany
;  .xdestroywindow XDestroyWindowEvent
;  end virtual
;
;  virtual at .xany
;  .xunmap XUnmapEvent
;  end virtual
;
;  virtual at .xany
;  .xmap XMapEvent
;  end virtual
;
;  virtual at .xany
;  .xmaprequest XMapRequestEvent
;  end virtual
;
;  virtual at .xany
;  .xreparent XReparentEvent
;  end virtual
;
;  virtual at .xany
;  .xconfigure XConfigureEvent
;  end virtual
;
;  virtual at .xany
;  .xgravity XGravityEvent
;  end virtual
;
;  virtual at .xany
;  .xresizerequest XResizeEvent
;  end virtual
;
;  virtual at .xany
;  .xconfigurerequest XConfigureRequestEvent
;  end virtual
;
;  virtual at .xany
;  .xcirculate XCirculateEvent
;  end virtual
;
;  virtual at .xany
;  .xcirculaterequest XCirculateRequestEvent
;  end virtual
;
;  virtual at .xany
;  .xproperty XPropertyEvent
;  end virtual
;
;  virtual at .xany
;  .xselectionclear XSelectionClearEvent
;  end virtual
;
;  virtual at .xany
;  .xselectionrequest XSelectionRequestEvent
;  end virtual
;
;  virtual at .xany
;  .xselection XSelectionEvent
;  end virtual
;
;  virtual at .xany
;  .xcolormap XColormapEvent
;  end virtual
;
;  virtual at .xany
;  .xclient XClientMessageEvent
;  end virtual
;
;  virtual at .xany
;  .xmapping XMappingEvent
;  end virtual
;
;  virtual at .xany
;  .xerror XErrorEvent
;  end virtual
;
;  virtual at .xany
;  .xkeymap XKeymapEvent
;  end virtual
ends


;       Misc.           Structures

struct   XKeyboardControl
        .key_click_percent              rd    1
Changes to freshlib/equates/Linux/_geometry.inc.
8
9
10
11
12
13
14









15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37












+
+
+
+
+
+
+
+
+













-
+
-
-
-
-
-
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


struct TBounds
  .x      dd ?
  .y      dd ?
  .width  dd ?
  .height dd ?
ends



struct RECT
  .left   dd ?
  .top    dd ?
  .right  dd ?
  .bottom dd ?
ends

struct POINT
  .x  dd ?
  .y  dd ?
ends

struct XRectangle

  .x       dw  ?
  .y       dw  ?
  .width   dw  ?
  .height  dw  ?
ends
Changes to freshlib/equates/Linux/_libFT.inc.
43
44
45
46
47
48
49



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77







+
+
+

















+







FT_LOAD_NO_RECURSE                      =  $400
FT_LOAD_IGNORE_TRANSFORM                =  $800
FT_LOAD_MONOCHROME                      =  $1000
FT_LOAD_LINEAR_DESIGN                   =  $2000
FT_LOAD_SBITS_ONLY                      =  $4000
FT_LOAD_NO_AUTOHINT                     =  $8000
FT_LOAD_COLOR                           =  $100000

FT_ADVANCE_FLAG_FAST_ONLY               =  $20000000


FT_RENDER_MODE_NORMAL = 0
FT_RENDER_MODE_LIGHT  = 1
FT_RENDER_MODE_MONO   = 2
FT_RENDER_MODE_LCD    = 3
FT_RENDER_MODE_LCD_V  = 4
FT_RENDER_MODE_MAX    = 5

struc FT_LOAD_TARGET x {
  . = (x and 15) shl 16
}

FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET  FT_RENDER_MODE_NORMAL
FT_LOAD_TARGET_LIGHT  FT_LOAD_TARGET  FT_RENDER_MODE_LIGHT
FT_LOAD_TARGET_MONO   FT_LOAD_TARGET  FT_RENDER_MODE_MONO
FT_LOAD_TARGET_LCD    FT_LOAD_TARGET  FT_RENDER_MODE_LCD
FT_LOAD_TARGET_LCD_V  FT_LOAD_TARGET  FT_RENDER_MODE_LCD_V



FT_PIXEL_MODE_NONE  = 0
FT_PIXEL_MODE_MONO  = 1
FT_PIXEL_MODE_GRAY  = 2
FT_PIXEL_MODE_GRAY2 = 3
FT_PIXEL_MODE_GRAY4 = 4
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
207
208
209
210
211
212
213








214
215
216
217
218
219
220







-
-
-
-
-
-
-
-







  .size         dd  ?   ; pointer to FT_Size
  .charmap      dd  ?   ; pointer to FT_CharMap

; down is the private part.

ends


struct FTC_ImageType
  .face_id  dd  ?
  .width    dd  ?
  .height   dd  ?
  .flags    dd  ?
ends


struct FT_GlyphRec
  .library      dd      ?
  .clazz        dd      ?
  .format       dd      ?
  .advance      FT_Vector
ends
275
276
277
278
279
280
281








282
283
284
285
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289







+
+
+
+
+
+
+
+




  .width   dd ?
  .height  dd ?
  .pixel   dd ?
  .x_res   dd ?
  .y_res   dd ?
ends


struct FTC_ImageType
  .face_id  dd  ?
  .width    dd  ?
  .height   dd  ?
  .flags    dd  ?
ends




interface FT_Face_Requester, .face_id, .library, .request_data, .pFace
Changes to freshlib/equates/Linux/_linux.inc.
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
662
663
664
665
666
667
668

669
670
671
672
673
674
675
676







-
+









; Signal values
; default action is: "Term" - terminate; "Core" - terminate with core dump; "Ign" - ignore; "Stop" - stop the process; "Cont" - continue the process.

macro signal name, value {
  name = value
  .mask = 1 shl value
  name#.mask = 1 shl value
}

signal SIGHUP   ,  1    ; Term    Hangup detected on controlling terminal or death of controlling process
signal SIGINT   ,  2    ; Term    Interrupt from keyboard
signal SIGQUIT  ,  3    ; Core    Quit from keyboard
signal SIGILL   ,  4    ; Core    Illegal Instruction
signal SIGTRAP  ,  5    ; Core    Trace/breakpoint trap
Changes to freshlib/equates/Win32/_GDI32.INC.
44
45
46
47
48
49
50










































51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








+







  .biCompression   dd ?
  .biSizeImage     dd ?
  .biXPelsPerMeter dd ?
  .biYPelsPerMeter dd ?
  .biClrUsed       dd ?
  .biClrImportant  dd ?
ends


struct CIEXYZ
  .ciexyzX      dd ?
  .ciexyzY      dd ?
  .ciexyzZ      dd ?
ends


struct CIEXYZTRIPLE
  .ciexyzRed   CIEXYZ
  .ciexyzGreen CIEXYZ
  .ciexyzBlue  CIEXYZ
ends


struct BITMAPV4HEADER
  .biSize          dd ?
  .biWidth         dd ?
  .biHeight        dd ?
  .biPlanes        dw ?
  .biBitCount      dw ?
  .biCompression   dd ?
  .biSizeImage     dd ?
  .biXPelsPerMeter dd ?
  .biYPelsPerMeter dd ?
  .biClrUsed       dd ?
  .biClrImportant  dd ?

  .RedMask         dd ?
  .GreenMask       dd ?
  .BlueMask        dd ?
  .AlphaMask       dd ?
  .CSType          dd ?
  .Endpoints       CIEXYZTRIPLE
  .GamaRed         dd ?
  .GammaGreen      dd ?
  .GammaBlue       dd ?
ends




struct BITMAPFILEHEADER
  .bfType      dw ?
  .bfSize      dd ?
  .bfReserved1 dw ?
  .bfReserved2 dw ?
  .bfOffBits   dd ?
ends


struct TEXTMETRIC
  .tmHeight           dd ?
  .tmAscent           dd ?
  .tmDescent          dd ?
  .tmInternalLeading  dd ?
  .tmExternalLeading  dd ?
76
77
78
79
80
81
82


83
84
85
86
87
88


89
90
91
92
93
94
95
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142







+
+






+
+







  .tmItalic           db ?
  .tmUnderlined       db ?
  .tmStruckOut        db ?
  .tmPitchAndFamily   db ?
  .tmCharSet          db ?
  .__align            rb 7
ends



struct LOGBRUSH
  .lbStyle dd ?
  .lbColor dd ?
  .lbHatch dd ?
ends



struct LOGPEN
  .lopnStyle dd ?
  .lopnWidth POINT
  .lopnColor dd ?
ends

Changes to freshlib/equates/Win32/_USER32.INC.
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347






















348
349
350
351
352
353
354
320
321
322
323
324
325
326





















327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







WS_TILEDWINDOW      = WS_OVERLAPPEDWINDOW
WS_TILED            = WS_OVERLAPPED
WS_ICONIC           = WS_MINIMIZE
WS_SIZEBOX          = WS_THICKFRAME

; Extended Window Styles

WS_EX_DLGMODALFRAME    = 00001h
WS_EX_DRAGOBJECT       = 00002h
WS_EX_NOPARENTNOTIFY   = 00004h
WS_EX_TOPMOST          = 00008h
WS_EX_ACCEPTFILES      = 00010h
WS_EX_TRANSPARENT      = 00020h
WS_EX_MDICHILD         = 00040h
WS_EX_TOOLWINDOW       = 00080h
WS_EX_WINDOWEDGE       = 00100h
WS_EX_CLIENTEDGE       = 00200h
WS_EX_CONTEXTHELP      = 00400h
WS_EX_RIGHT            = 01000h
WS_EX_LEFT             = 00000h
WS_EX_RTLREADING       = 02000h
WS_EX_LTRREADING       = 00000h
WS_EX_LEFTSCROLLBAR    = 04000h
WS_EX_RIGHTSCROLLBAR   = 00000h
WS_EX_CONTROLPARENT    = 10000h
WS_EX_STATICEDGE       = 20000h
WS_EX_APPWINDOW        = 40000h
WS_EX_LAYERED          = 80000h
WS_EX_DLGMODALFRAME    = 00000001h
WS_EX_DRAGOBJECT       = 00000002h
WS_EX_NOPARENTNOTIFY   = 00000004h
WS_EX_TOPMOST          = 00000008h
WS_EX_ACCEPTFILES      = 00000010h
WS_EX_TRANSPARENT      = 00000020h
WS_EX_MDICHILD         = 00000040h
WS_EX_TOOLWINDOW       = 00000080h
WS_EX_WINDOWEDGE       = 00000100h
WS_EX_CLIENTEDGE       = 00000200h
WS_EX_CONTEXTHELP      = 00000400h
WS_EX_RIGHT            = 00001000h
WS_EX_LEFT             = 00000000h
WS_EX_RTLREADING       = 00002000h
WS_EX_LTRREADING       = 00000000h
WS_EX_LEFTSCROLLBAR    = 00004000h
WS_EX_RIGHTSCROLLBAR   = 00000000h
WS_EX_CONTROLPARENT    = 00010000h
WS_EX_STATICEDGE       = 00020000h
WS_EX_APPWINDOW        = 00040000h
WS_EX_LAYERED          = 00080000h
WS_EX_NOACTIVATE       = 08000000h
WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE or WS_EX_CLIENTEDGE
WS_EX_PALETTEWINDOW    = WS_EX_WINDOWEDGE or WS_EX_TOOLWINDOW or WS_EX_TOPMOST

; MDI client style bits

MDIS_ALLCHILDSTYLES = 1

Added freshlib/equates/Win32/_geometry.inc.






















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Different geometry structures.
;
;  Target OS: Windows
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


struct TBounds
  .x      dd ?
  .y      dd ?
  .width  dd ?
  .height dd ?
ends

Changes to freshlib/equates/Win32/allequates.inc.
10
11
12
13
14
15
16

17
18
19
20
21
22
23
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24







+







;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

CRLF equ 13, 10

include '_geometry.inc'
include '_kernel32.inc'
include '_user32.inc'
include '_gdi32.inc'
include '_comctl32.inc'
include '_comdlg32.inc'
include '_shell32.inc'
include '_wsock32.inc'
Changes to freshlib/equates/allequates.inc.
8
9
10
11
12
13
14


15
16
17
18











19
20
21
22
23
24
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37







+
+




+
+
+
+
+
+
+
+
+
+
+






;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

; Very generic constants!

TRUE = 1
FALSE = 0

NULL = 0

regEDI = 0
regESI = 1
regEBP = 2
regESP = 3
regEBX = 4
regEDX = 5
regECX = 6
regEAX = 7



include '%TargetOS%/allequates.inc'

include '_sqlite3.inc'
include '_zlib1.inc'
include '_sdl.inc'
Deleted freshlib/graphics/Dummy/backbuffer.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37





































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Provides raster bitmap, to be used for double buffer painting.
;
;  Target OS: Dummy
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________



proc CreateBackBuffer, .hwin, .width, .height
begin
        stc
        return
endp



proc DestroyBackBuffer, .pBackBuffer
begin
        stc
        return
endp



proc DrawBackBuffer, .context, .pBackBuffer, .x, .y
begin
        stc
        return
endp
Deleted freshlib/graphics/Dummy/context.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75











































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Context is a object that represents drawing surface in FreshLib
;
;  Target OS: Dummy
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


cmClear       =    0
cmAnd         =    0
cmAndReverse  =    0
cmCopy        =    0
cmAndInverted =    0
cmNoOp        =    0
cmXor         =    0
cmOr          =    0
cmNor         =    0
cmEquiv       =    0
cmInvert      =    0
cmXorReverse  =    0
cmCopyInverted =   0
cmOrInverted   =   0
cmNand         =   0
cmSet          =   0


proc AllocateContext, .raster
begin
        stc
        return
endp




proc ReleaseContext, .context
begin
        return
endp



proc  SetDrawMode, .context, .mode
begin
        return
endp




proc SetLineStyle, .context, .pLineStyle
begin
        return
endp






proc SetClipRectangle, .context, .pBounds
begin
        return
endp




Deleted freshlib/graphics/KolibriOS/backbuffer.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37





































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Provides raster bitmap, to be used for double buffer painting.
;
;  Target OS: KolibriOS
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________



proc CreateBackBuffer, .hwin, .width, .height
begin
        stc
        return
endp



proc DestroyBackBuffer, .pBackBuffer
begin
        stc
        return
endp



proc DrawBackBuffer, .context, .pBackBuffer, .x, .y
begin
        stc
        return
endp
Deleted freshlib/graphics/KolibriOS/context.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105









































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Context is a object that represents drawing surface in FreshLib
;
;  Target OS: KolibriOS
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


cmCopy        =    0
cmInverted    =    1
cmXor         =    2
cmAnd         =    1 ; ????

struct TKolibriContext
  .CurrentColor   dd ?
  .CurentDrawMode dd ?
ends


proc AllocateContext, .raster
begin
        push    ebx

        stdcall GetMem, sizeof.TContext
        jc      .error
        mov     ebx, eax

        mov     eax, [.raster]
        mov     [ebx+TContext.raster], eax

        stdcall GetMem, sizeof.TKolibriContext
        mov     [ebx+TContext.handle], eax
        mov     [eax+TKolibriContext.CurrentColor], 0
        mov     [eax+TKolibriContext.CurentDrawMode], cmCopy

        mov     eax, ebx
.exit:
        pop     ebx
        clc
        return

.error:
        DebugMsg 'Error allocating context.'
        xor     eax, eax
        pop     ebx
        stc
        return
endp




proc ReleaseContext, .context
begin
        push    eax
        mov     eax, [.context]
        mov     eax, [eax+TContext.handle]
        stdcall FreeMem, eax
        stdcall FreeMem, [.context]
        pop     eax
        clc
        return
endp



proc  SetDrawMode, .context, .mode
begin
        push    eax

        mov     eax, [.context]
        mov     eax, [eax+TContext.handle]

        push    [.mode]
        pop     [eax+TKolibriContext.CurentDrawMode]

        pop     eax
        return
endp




proc SetLineStyle, .context, .pLineStyle
begin
        return
endp



proc SetClipRectangle, .context, .pBounds
begin
        return
endp




Changes to freshlib/graphics/KolibriOS/fonts.asm.
9
10
11
12
13
14
15















16

17
18










19
20
21
22
23




24

25
26
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+

-
+
+
+
+
+
+
+
+
+
+




-
+
+
+
+

+


;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________



; needed for FreeType support.

proc FTCRequester as FT_Face_Requester
begin



        return
endp





proc FontCreate, .fontface, .size, .weight, .flags
body FontCreate
begin
        stc

        return
endp




body FontDestroy
begin

        return
endp


proc FontDestroy, .font



body GetFontMetrics
begin

        return
endp
Changes to freshlib/graphics/KolibriOS/images.asm.
9
10
11
12
13
14
15





16
17



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
9
10
11
12
13
14
15
16
17
18
19
20


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42







+
+
+
+
+
-
-
+
+
+














-
+




;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


struct TImage
  .width   dd ?  ; width in pixels.
  .height  dd ?  ; height in pixels.
  .pPixels dd ?  ; pointer to the pixel memory.
ends
; only 16, 24 and 32 bpp are supported.
; It is stupid to support palleted modes and even 24bpp is not good...



body CreateImage
begin
        stc
        return
endp


body DestroyImage
begin
        return
endp



body DrawImage
body DrawImageRect
begin
        return
endp

Changes to freshlib/graphics/KolibriOS/text.asm.
9
10
11
12
13
14
15



16









































































































17









18




































































































































































































19
20
21
22
23

24









25




































































26
27
28
29
30
31
32
































33

34
35




























36


37

38



39


40









































































































41



42
43
44
45

















































































































46




47


48
49
50













































































































51


52






















































53

























































54
55
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420

421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454


455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604




605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725



726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837

838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951







+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





+
-
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+

+

+
+
+

+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+

+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


iglobal
  var flagFreeTypeLoadFlags = FT_LOAD_RENDER or FT_LOAD_TARGET_LCD or FT_LOAD_NO_AUTOHINT or FT_LOAD_COLOR
endg


uglobal
  var FTC_CMapCache_Lookup = 0
  var FTC_ImageCache_LookupScaler = 0

endg



body DrawDecomposedString      ;, .pImage, .pArray, .x, .y, .font, .color
.scaler  FTC_ScalerRec
.glyph   dd ?

.startX  dd ?
begin
        pushad

        mov     edx, [.font]
        xor     ecx, ecx

        mov     [.scaler.face_id], edx
        mov     [.scaler.width], ecx

        mov     eax, [edx+__TFont.height]
        inc     ecx

        mov     [.scaler.height], eax
        mov     [.scaler.pixel], ecx    ; ecx = 1

        mov     eax, [.x]
        mov     [.startX], eax

        mov     esi, [.pArray]
        xor     edi, edi
        dec     edi

.char_loop:
        inc     edi
        cmp     edi, [esi+TArray.count]
        jae     .finish

        cmp     word [esi+TArray.array+8*edi+TTextChar.width], 0
        je      .char_ok

        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, [esi+TArray.array+8*edi+TTextChar.code]

        lea     ecx, [.scaler]
        lea     edx, [.glyph]
        cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0

        test    eax, eax
        jnz     .char_ok

        mov     ebx, [.glyph]
        mov     ecx, [.x]
        mov     edx, [.y]

        add     ecx, [ebx+FT_BitmapGlyphRec.left]
        sub     edx, [ebx+FT_BitmapGlyphRec.top]

        lea     eax, [ebx+FT_BitmapGlyphRec.bitmap]
        stdcall __DrawGlyph, [.pImage], eax, ecx, edx, [.color]

        movzx   eax, word [esi+TArray.array+8*edi+TTextChar.width]
        add     [.x], eax

.char_ok:
; check for new line.
        movzx   eax, word [esi+TArray.array+8*edi+TTextChar.height]
        test    eax, eax
        jz      .char_loop

        add     [.y], eax
        mov     eax, [.startX]
        mov     [.x], eax
        jmp     .char_loop


.finish:
        popad
        return
endp




; Draws the string on the image using the specified font and color.
; The string is drawn in one line. The control symbols are not
; processed. The tabs are not expanded or replaced with spaces.
;
; Arguments:
;    .pImage  - pointer to the image where to draw the text.
;    .pString - pointer to a UTF-8 string.
;    .len     - how many bytes from the string to be drawn. If -1, the whole string will be drawn.
;    .x       - X coordinate, where to start drawing.
;    .y       - Y coordinate of the baseline where to draw the string.
;    .font    - the font to be used.
;    .color   - ARGB color to draw the glyphs.
;
;;;;;;;; Returns:
;;;;;;;;    EAX - the width of the string in pixels.
;;;;;;;;    EBX - the ascender of the string. It is negative.
;;;;;;;;    EDX - the height of the string in pixels.


proc DrawString, .context, .ptrString, .len, .x, .y, .font, .color
body DrawString ;, .pImage, .pString, .len, .x, .y, .font, .color

.scaler  FTC_ScalerRec
.glyph   dd ?

.miny    dd ?
.maxy    dd ?
.startX  dd ?

begin
        pushad

        mov     edx, [.font]
        xor     ecx, ecx

        mov     [.scaler.face_id], edx
        mov     [.scaler.width], ecx

        mov     eax, [edx+__TFont.height]
        inc     ecx

        mov     [.scaler.height], eax
        mov     [.scaler.pixel], ecx    ; ecx = 1

        ror     ecx, 1                  ; ecx = $80000000
        mov     [.maxy], ecx
        dec     ecx
        mov     [.miny], ecx            ; ecx = $7fffffff

        mov     eax, [.x]
        mov     [.startX], eax

        mov     esi, [.pString]

.char_loop:

        stdcall DecodeUtf8, [esi]
        jc      .finish

        add     esi, edx

        sub     [.len], edx
        jb      .finish

        test    eax, eax
        jz      .finish

        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax

        lea     ecx, [.scaler]
        lea     edx, [.glyph]
        cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0

        test    eax, eax
        jnz     .char_loop

        mov     ebx, [.glyph]

        mov     ecx, [.x]
        mov     edx, [.y]

        add     ecx, [ebx+FT_BitmapGlyphRec.left]
        sub     edx, [ebx+FT_BitmapGlyphRec.top]

        cmp     edx, [.miny]
        jge     @f
        mov     [.miny], edx
@@:
        mov     eax, edx
        add     eax, [ebx+FT_BitmapGlyphRec.bitmap.rows]
        cmp     eax, [.maxy]
        jle     @f
        mov     [.maxy], eax
@@:
        lea     eax, [ebx+FT_BitmapGlyphRec.bitmap]
        stdcall __DrawGlyph, [.pImage], eax, ecx, edx, [.color]

        mov     eax, [ebx+FT_BitmapGlyphRec.root.advance.x]
        sar     eax, 16        ; format 16.16 fixed decimal point.
        add     [.x], eax

        jmp     .char_loop


.finish:
;        mov     eax, [.x]
;        mov     edx, [.maxy]
;        mov     ebx, [.miny]
;        sub     eax, [.startX]
;        sub     edx, ebx
;        sub     ebx, [.y]

;        mov     [esp+4*regEAX], eax
;        mov     [esp+4*regEBX], ebx
;        mov     [esp+4*regEDX], edx

        popad
        return
endp



; returns:
;   EAX - array with decomposed string.
;   EDX - maximal bearing_Y of the string.
;   ECX - maximal descender of the string.

body TextDecompose      ;, .hString, .font

  .scaler  FTC_ScalerRec
  .glyph   dd ?

  .miny    dd ?
  .maxy    dd ?

begin
        pushad

        mov     edx, [.font]
        xor     ecx, ecx

        mov     [.scaler.face_id], edx
        mov     [.scaler.width], ecx

        mov     eax, [edx+__TFont.height]
        inc     ecx

        mov     [.scaler.height], eax
        mov     [.scaler.pixel], ecx    ; ecx = 1

        ror     ecx, 1                  ; ecx = $80000000
        mov     [.maxy], ecx
        dec     ecx
        mov     [.miny], ecx            ; ecx = $7fffffff

        stdcall StrPtr, [.hString]
        mov     esi, eax

        stdcall CreateArray, sizeof.TTextChar
        mov     edi, eax

.char_loop:
        stdcall DecodeUtf8, [esi]
        jc      .finish

        add     esi, edx
        mov     ebx, eax

        test    eax, eax
        jz      .end

        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax

        lea     ecx, [.scaler]
        lea     edx, [.glyph]
        cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0

        xor     ecx, ecx

        test    eax, eax
        jnz     .glyph_size_ok  ; zero width glyph ????

        mov     ecx, [.glyph]

        mov     eax, [ecx+FT_BitmapGlyphRec.top]
        neg     eax

        cmp     eax, [.miny]
        jge     @f
        mov     [.miny], eax
@@:

        add     eax, [ecx+FT_BitmapGlyphRec.bitmap.rows]
        cmp     eax, [.maxy]
        jle     @f
        mov     [.maxy], eax
@@:
        mov     ecx, [ecx+FT_BitmapGlyphRec.root.advance.x]  ; format 16.16 fixed decimal point.
        sar     ecx, 16   ; format 16.16


.glyph_size_ok:

        stdcall AddArrayItems, edi, 1
        mov     edi, edx
        mov     dword [eax+TTextChar.width], ecx
        mov     [eax+TTextChar.code],  ebx
        jmp     .char_loop

.end:
        clc

.finish:
        mov     [esp+4*regEAX], edi

        mov     eax, [.miny]
        neg     eax
        mov     ecx, [.maxy]

        mov     [esp+4*regEDX], eax
        mov     [esp+4*regECX], ecx

        add     ecx, eax
        mov     [edi+TArray.lparam], ecx

        popad
        return
endp



; Returns an array with the widths from the begining of the text to the every character inside the string.
proc DrawStringOpaque, .context, .ptrString, .len, .x, .y, .font, .color, .background


proc GetTextWidthsArray, .hString, .font

  .scaler  FTC_ScalerRec
  .glyph   dd ?

  .x       dd ?

begin
        pushad

        mov     edx, [.font]
        xor     ecx, ecx

        mov     [.scaler.face_id], edx
        mov     [.scaler.width], ecx

        mov     eax, [edx+__TFont.height]
        inc     ecx

        mov     [.scaler.height], eax
        mov     [.scaler.pixel], ecx    ; ecx = 1


        stdcall StrPtr, [.hString]
        mov     esi, eax

        stdcall CreateArray, 4
        mov     edi, eax

        xor     ebx, ebx

.char_loop:
        stdcall DecodeUtf8, [esi]
        jc      .finish

        add     esi, edx
        test    eax, eax
        jz      .end

        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax

        lea     ecx, [.scaler]
        lea     edx, [.glyph]
        cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0

        test    eax, eax
        jnz     .glyph_size_ok  ; zero width glyph ????


        mov     ecx, [.glyph]
        mov     ecx, [ecx+FT_BitmapGlyphRec.root.advance.x]  ; format 16.16 fixed decimal point.

        add     ebx, ecx


.glyph_size_ok:

        stdcall AddArrayItems, edi, 1
        mov     edi, edx

        mov     edx, ebx
        sar     edx, 16         ; format 16.16
        mov     [eax], edx
        jmp     .char_loop

.end:
        clc

.finish:
        mov     [esp+4*regEAX], edi
        popad
        return

.error:
        stc
        popad
        return
endp




proc DrawColoredString, .context, .ptrString, .pCharAttr, .str_len_bytes, .x, .y, .char_offs, .fontwidth, .fontheight







; Computes the width and height of the text.
;
; Arguments:
;    .pString - pointer to a UTF-8 string.
;    .len     - how many bytes from the string to be used. If -1 the whole string will be scanned.
;    .font    - the font to be used for the computations.
;
; Returns:
;    EAX - the width of the string in pixels.
;    EBX - the ascender of the string. It is negative.
;    EDX - the height of the string in pixels.


body GetTextBounds      ;, .pString, .len, .font

.scaler  FTC_ScalerRec
.glyph   dd ?

.x       dd ?

.miny    dd ?
.maxy    dd ?

.charlen dd ?

begin
        pushad
        return
endp

        mov     edx, [.font]
        xor     ecx, ecx

        mov     [.scaler.face_id], edx
        mov     [.scaler.width], ecx

        mov     [.x], ecx

        mov     eax, [edx+__TFont.height]
        inc     ecx

        mov     [.scaler.height], eax
        mov     [.scaler.pixel], ecx    ; ecx = 1

        ror     ecx, 1                  ; ecx = $80000000
        mov     [.maxy], ecx
        dec     ecx
        mov     [.miny], ecx            ; ecx = $7fffffff

        mov     esi, [.pString]

.char_loop:
        stdcall DecodeUtf8, [esi]
        jc      .finish

        add     esi, edx
        mov     [.charlen], edx

        test    eax, eax
        jz      .finish

        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax

        lea     ecx, [.scaler]
        lea     edx, [.glyph]
        cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags],  eax, edx, 0

        test    eax, eax
        jnz     .char_loop

        mov     ebx, [.glyph]

        sub     eax, [ebx+FT_BitmapGlyphRec.top]                ; eax = 0 here
        mov     edx, eax
        add     edx, [ebx+FT_BitmapGlyphRec.bitmap.rows]

        cmp     eax, [.miny]
        jge     @f
        mov     [.miny], eax
@@:
        cmp     edx, [.maxy]
        jle     @f
        mov     [.maxy], edx
@@:

        mov     eax, [ebx+FT_GlyphRec.advance.x]
        sar     eax, 16        ; format 16.16 fixed decimal point.
        add     [.x], eax

        mov     eax, [.charlen]
        sub     [.len], eax
        ja      .char_loop


.finish:
        mov     eax, [.x]
        mov     edx, [.maxy]
        mov     ebx, [.miny]
        sub     edx, ebx

        mov     [esp+4*regEAX], eax
        mov     [esp+4*regEBX], ebx
        mov     [esp+4*regEDX], edx

        popad
        return
endp







proc __DrawGlyph, .pImage, .pFTBitmap, .x, .y, .color
.spitch   dd ?
.dpitch   dd ?

.drect   RECT
.srect   RECT

.pixel_mode dd ?

.sstart dd ?
.dstart dd ?

.xsize  dd ?

.bpp    dd ?
.bit_ofs dd ?

begin
        pushad

        stdcall __fix_color, [.color], regEAX
        mov     [.color], eax

        mov     ebx, [.pImage]
        mov     edi, [.pFTBitmap]

; the glyph pixel mode handling.
        movzx   eax, [edi+FT_Bitmap.pixel_mode]
        cmp     eax, FT_PIXEL_MODE_BGRA
        ja      .finish

        mov     [.pixel_mode], eax
        movzx   eax, [.bpp_const+eax]
        mov     [.bpp], eax

; Clip the glyph to the image surface.

        mov     eax, [ebx+TImage.width]
        mov     ecx, [ebx+TImage.height]
        mov     [.drect.right], eax
        mov     [.drect.bottom], ecx
        xor     eax, eax
        mov     [.drect.left], eax
        mov     [.drect.top], eax

        mov     eax, [.x]
        mov     ecx, [.y]
        mov     [.srect.left], eax
        mov     [.srect.top], ecx

        mov     eax, [edi+FT_Bitmap.width]
        cmp     [.pixel_mode], FT_PIXEL_MODE_LCD
        jne     @f

        cdq
        mov     ecx, 3
        div     ecx

@@:
        add     eax, [.srect.left]
        mov     [.srect.right], eax

        mov     eax, [.srect.top]
        add     eax, [edi+FT_Bitmap.rows]
        mov     [.srect.bottom], eax
proc GetTextBounds, .context, .ptrString, .len, .font
begin
        return
endp

        lea     eax, [.srect]
        lea     ecx, [.drect]
        stdcall RectIntersect, ecx, eax, ecx
        jc      .finish                         ; the rectangles does not intersect!

        mov     eax, [.drect.left]
        mov     ecx, [.drect.top]
        sub     eax, [.x]
        sub     ecx, [.y]
        mov     [.srect.left], eax
        mov     [.srect.top], ecx

        mov     eax, [.drect.right]
        mov     ecx, [.drect.bottom]
        sub     eax, [.drect.left]
        sub     ecx, [.drect.top]
        mov     [.srect.right], eax     ; width!
        mov     [.srect.bottom], ecx    ; height!

; End of clipping code - [.srect] contains the rectangle of the glyph that have to be drawn (left, top, width, height).
; [.drect] contains the destination rectangle. Both have the same size.

        mov     ecx, [edi+FT_Bitmap.pitch]
        mov     [.spitch], ecx

; glyph pixel pointer

        mov     esi, [edi+FT_Bitmap.buffer]
        test    esi, esi
        jz      .finish

        mov     eax, [.srect.top]
        mov     ecx, [.srect.left]

        imul    eax, [.spitch]
        imul    ecx, [.bpp]
        mov     [.bit_ofs], ecx
        shr     ecx, 3          ; byte offs
        and     [.bit_ofs], 7          ; bit offs

        add     esi, ecx
        add     esi, eax

; TImage destination pixel pointer

        mov     edi, [ebx+TImage.pPixels]

        mov     ecx, [ebx+TImage.width]
        mov     eax, [.drect.top]
        imul    eax, ecx
        add     eax, [.drect.left]
        lea     edi, [edi+4*eax]    ; in bytes.

        shl     ecx, 2
        mov     [.dpitch], ecx


; prepare MMX constants

        pxor    mm0, mm0        ; mm0 = 0000 0000 0000 0000
        pcmpeqw mm1, mm1                                        ; mm1 = ffff ffff ffff ffff
        psrlw   mm1, 15                                         ; mm1 = 0001 0001 0001 0001
        psllw   mm1, 8          ; mm1 = 0100 0100 0100 0100

        movq    mm2, mm1                                        ; mm2 = 0001 0001 0001 0001
        psllq   mm2, 48         ; mm2 = 0100 0000 0000 0000


.loopy:

        mov     [.sstart], esi
        mov     [.dstart], edi

        mov     eax, [.srect.right]     ; width!
        mov     [.xsize], eax

        cmp     [.pixel_mode], FT_PIXEL_MODE_BGRA
        je      .loopx32

        cmp     [.pixel_mode], FT_PIXEL_MODE_LCD
        je      .loopx24

        cmp     [.pixel_mode], FT_PIXEL_MODE_GRAY
        je      .loopx8

        cmp     [.pixel_mode], FT_PIXEL_MODE_MONO
        jne     .finish

        lodsd
        bswap   eax
        mov     ch, 32
        mov     cl, byte [.bit_ofs]
        shl     eax, cl
        sub     ch, cl

.loopx1:
        shl     eax, 1
        dec     ch
        jnz     @f

        lodsd
        bswap   eax
        mov     ch, 32

@@:
        jnc     .next_x

        movd    mm7, [.color]        ; source pixel.
        movd    mm6, [edi]           ; destination pixel.

        movq    mm5, mm7
        psrlq   mm5, 24                 ; alpha source

        punpckldq mm5, mm5              ;
        punpcklbw mm6, mm0              ; byte to word destination pixel
        packssdw  mm5, mm5              ; mm5 = As, As, As, As
        punpcklbw mm7, mm0              ; byte to word source pixel

        movq    mm4, mm1
        psubw   mm4, mm5                ; mm4 = Bs Bs Bs Bs     (Bs = $100 - As)
; returns:
;       eax - x offset of the baseline of the string.
;       edx - y offset of the baseline of the string.

        psrlq   mm5, 16                 ; mm5 = 0  As As As
        por     mm5, mm2                ; mm5 = $100 As As As

        pmullw  mm6, mm4                ; mm6 = Cd = Cd * (256-As) = Cd * Bs   (For alpha Ad = Ad*Bs)
        pmullw  mm7, mm5                ; Cs = Cs * As                   (For alpha As = $100*As )

        paddusw mm6, mm7                ; Cd = Cs + Cd                   (For alpha Ad = $100*As + Ad*Bs)
        psrlw   mm6, 8                  ; Cd = Cd/256                    (For alpha Ad = As + Ad*Bs/$100)

        packuswb mm6, mm0               ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
        movd     [edi], mm6

.next_x:
        add     edi, 4
        dec     [.xsize]
        jnz     .loopx1
        jmp     .nexty



.loopx8:
        movzx     eax, byte [esi]         ; intensity
        add       esi, 1

        movd      mm6, [.color]
        movd      mm7, eax

        punpcklbw mm6, mm0              ; byte to word color.
        punpckldq mm7, mm7              ;
        packssdw  mm7, mm7              ; mm7 = I, I, I, I

        pmullw    mm7, mm6              ; mm7 is the color to blend = Cs*256

        movd      mm6, [edi]            ; Destination color
        punpcklbw mm6, mm0              ; byte to word destination pixel

        movq      mm5, mm7
        psrlq     mm5, 56               ; alpha source
        punpckldq mm5, mm5
        packssdw  mm5, mm5              ; mm5 = As, As, As, As

        movq    mm4, mm1
        psubw   mm4, mm5                ; mm4 = Bs Bs Bs Bs     (Bs = $100 - As)

        pmullw  mm6, mm4                ; mm6 = Cd = Cd * (256-As) = Cd * Bs
        paddusw mm6, mm7                ; Cd = 256*Cs + Cd*(256-As)
        psrlw   mm6, 8                  ; Cd = Cd/256

        packuswb mm6, mm0               ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
        movd     [edi], mm6

        add     edi, 4

        dec     [.xsize]
        jnz     .loopx8
        jmp     .nexty


.loopx24:

        movzx   eax, byte [esi]
        movzx   edx, byte [esi+1]

        lea     eax, [eax+2*edx]
        movzx   edx, byte [esi+2]

        add     eax, edx
        shr     eax, 2          ; grayscale.

        movd      mm6, [.color]
        movd      mm7, eax

        punpcklbw mm6, mm0              ; byte to word color.
        punpckldq mm7, mm7              ;
        packssdw  mm7, mm7              ; mm7 = I, I, I, I

        pmullw    mm7, mm6              ; mm7 is the color to blend = Cs*256

        movd      mm6, [edi]            ; Destination color
        punpcklbw mm6, mm0              ; byte to word destination pixel

        movq      mm5, mm7
        psrlq     mm5, 56               ; alpha source
        punpckldq mm5, mm5
        packssdw  mm5, mm5              ; mm5 = As, As, As, As

        movq    mm4, mm1
        psubw   mm4, mm5                ; mm4 = Bs Bs Bs Bs     (Bs = $100 - As)

        pmullw  mm6, mm4                ; mm6 = Cd = Cd * (256-As) = Cd * Bs
        paddusw mm6, mm7                ; Cd = 256*Cs + Cd*(256-As)
        psrlw   mm6, 8                  ; Cd = Cd/256

        packuswb mm6, mm0               ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
        movd     [edi], mm6


        add     esi, 3
        add     edi, 4

        dec     [.xsize]
        jnz     .loopx24
        jmp     .nexty


.loopx32:
        movd    mm7, [esi]              ; source pixel.
        movd    mm6, [edi]              ; destination pixel.

        movq    mm5, mm7
        psrlq   mm5, 24                 ; alpha source
proc GetTextOffset, .context, .ptrString, .len, .font

        punpckldq mm5, mm5              ;
        punpcklbw mm6, mm0              ; byte to word destination pixel
        packssdw  mm5, mm5              ; mm5 = As, As, As, As
        punpcklbw mm7, mm0              ; byte to word source pixel

        movq    mm4, mm1
        psubw   mm4, mm5                ; mm4 = Bs Bs Bs Bs     (Bs = $100 - As)

        psrlq   mm5, 16                 ; mm5 = 0  As As As
        por     mm5, mm2                ; mm5 = $100 As As As

        pmullw  mm6, mm4                ; mm6 = Cd = Cd * (256-As) = Cd * Bs   (For alpha Ad = Ad*Bs)
        pmullw  mm7, mm5                ; Cs = Cs * As                   (For alpha As = $100*As )

        paddusw mm6, mm7                ; Cd = Cs + Cd                   (For alpha Ad = $100*As + Ad*Bs)
        psrlw   mm6, 8                  ; Cd = Cd/256                    (For alpha Ad = As + Ad*Bs/$100)

        packuswb mm6, mm0               ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
        movd     [edi], mm6

        add     edi, 4
        add     esi, 4

        dec     [.xsize]
        jnz     .loopx32
        jmp     .nexty


.nexty:
        mov     esi, [.sstart]
        add     esi, [.spitch]

        mov     edi, [.dstart]
        add     edi, [.dpitch]

        dec     [.srect.bottom]         ; height
        jnz     .loopy


.finish:
        emms
        popad
        return

.bpp_const db 0, 1, 8, 2, 4, 24, 8, 32

endp



; the colors must be pre-multiplied ARGB.

proc _BlendPixel, .dstColor, .srcColor
begin
        pushad

        movzx   ecx, byte [.srcColor+3]      ; As
        mov     ebx, $ff
        mov     esi, ebx

        sub     ebx, ecx                     ; 1 - As

        movzx   eax, byte [.dstColor+3]      ; Ad
        imul    ecx, esi
        mul     ebx
        add     eax, ecx
        adc     edx, 0
        div     esi

        mov     byte [esp+4*regEAX+3], al


        movzx   eax, byte [.dstColor]       ; Bd
        movzx   ecx, byte [.srcColor]       ; Bs

        imul    ecx, esi
        mul     ebx
        add     eax, ecx
        adc     edx, 0
        div     esi

        mov     byte [esp+4*regEAX], al



        movzx   eax, byte [.dstColor+1]       ; Gd
        movzx   ecx, byte [.srcColor+1]       ; Gs

        imul    ecx, esi
        mul     ebx
        add     eax, ecx
        adc     edx, 0
        div     esi

        mov     byte [esp+4*regEAX+1], al



        movzx   eax, byte [.dstColor+2]       ; Rd
        movzx   ecx, byte [.srcColor+2]       ; Rs

        imul    ecx, esi
        mul     ebx
        add     eax, ecx
        adc     edx, 0
        div     esi

        mov     byte [esp+4*regEAX+2], al


        popad
        return
endp
Deleted freshlib/graphics/Linux/backbuffer.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

























































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Provides raster bitmap, to be used for double buffer painting.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________



proc CreateBackBuffer, .hwin, .width, .height
begin
        push    ebx ecx edx

        stdcall GetMem, sizeof.TBackBuffer
        mov     ebx, eax

        mov     ecx, [.width]
        mov     edx, [.height]

        xor     eax, eax
        inc     eax

        cmp     ecx, eax
        jge     @f
        mov     ecx, eax
@@:
        cmp     edx, eax
        jge     @f
        mov     edx, eax
@@:
        mov     [ebx+TBackBuffer.width], ecx
        mov     [ebx+TBackBuffer.height], edx

        cinvoke XCreatePixmap, [hApplicationDisplay], [.hwin], [ebx+TBackBuffer.width], [ebx+TBackBuffer.height], $20
        test    eax, eax
        js      .error

        mov     [ebx+TBackBuffer.raster], eax
        mov     eax, ebx
        clc
        pop     edx ecx ebx
        return

.error:
        stdcall FreeMem, ebx
        xor     eax, eax
        stc
        pop     edx ecx ebx
        return
endp




proc DestroyBackBuffer, .pBackBuffer
begin
        push    eax ecx edx
        mov     eax, [.pBackBuffer]
        push    eax
        cinvoke XFreePixmap, [hApplicationDisplay], [eax+TBackBuffer.raster]
        stdcall FreeMem ; from the stack
        pop     edx ecx eax
        return
endp






proc DrawBackBuffer, .context, .pBackBuffer, .x, .y
begin
        push    eax ecx edx
        mov     eax, [.pBackBuffer]
        mov     ecx, [.context]

        cinvoke XCopyArea, [hApplicationDisplay], [eax+TBackBuffer.raster], [ecx+TContext.raster], [ecx+TContext.handle], 0, 0, [eax+TBackBuffer.width], [eax+TBackBuffer.height], [.x], [.y]

        pop     edx ecx eax
        return
endp

Deleted freshlib/graphics/Linux/context.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190






























































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Context is a object that represents drawing surface in FreshLib
;
;  Target OS: Linux
;
;  Dependencies: memory.asm
;
;  Notes:
;_________________________________________________________________________________________

uses libX11

cmClear       =       GXclear
cmAnd         =       GXand
cmAndReverse  =       GXandReverse
cmCopy        =       GXcopy
cmAndInverted =       GXandInverted
cmNoOp        =       GXnoop
cmXor         =       GXxor
cmOr          =       GXor
cmNor         =       GXnor
cmEquiv       =       GXequiv
cmInvert      =       GXinvert
cmOrReverse  =       GXorReverse
cmCopyInverted =      GXcopyInverted
cmOrInverted   =      GXorInverted
cmNand         =      GXnand
cmSet          =      GXset


image_pointer_context = 2

proc AllocateContext, .raster
begin
        push    ebx ecx edx

        stdcall GetMem, sizeof.TContext
        jc      .error
        mov     ebx, eax

        mov     eax, [.raster]
        mov     [ebx+TContext.raster], eax

        cinvoke XCreateGC, [hApplicationDisplay], [ebx+TContext.raster], 0, 0
        mov     [ebx+TContext.handle], eax
        mov     eax, ebx

.exit:
        pop     edx ecx ebx
        clc
        return

.error:
        DebugMsg 'Error allocating context.'
        xor     eax, eax
        pop     edx ecx ebx
        stc
        return
endp




proc ReleaseContext, .context
begin
        push    eax ebx ecx edx
        mov     ebx, [.context]
        cinvoke XFlush, [hApplicationDisplay]
        cinvoke XFreeGC, [hApplicationDisplay], [ebx+TContext.handle]
        cmp     [ebx+TContext.clipregion], 0
        je      @f
        cinvoke XDestroyRegion, [ebx+TContext.clipregion]
@@:
        stdcall FreeMem, ebx

        clc
        pop     edx ecx ebx eax
        return
endp



proc SetLineStyle, .context, .pLineStyle
.color dd ?
begin
        push    eax ebx ecx edx esi

        mov     ebx, [.context]
        mov     esi, [.pLineStyle]

        mov     eax, [esi+TLineStyle.flags]
        mov     ecx, eax
        shr     ecx, 8
        and     eax, $ff        ; cap_style
        and     ecx, $ff        ; join_style

        mov     edx, LineSolid
        cmp     [esi+TLineStyle.DashCount], 0
        je      @f
        mov     edx, LineDoubleDash
@@:
        cinvoke XSetLineAttributes, [hApplicationDisplay], [ebx+TContext.handle], [esi+TLineStyle.width], edx, eax, ecx
        cinvoke XSetForeground,     [hApplicationDisplay], [ebx+TContext.handle], [esi+TLineStyle.color]

        cmp     [esi+TLineStyle.DashCount], 0
        je      .exit

        lea     ecx, [esi+TLineStyle.DashItems]
        cinvoke XSetDashes, [hApplicationDisplay], [ebx+TContext.handle], 0, ecx, [esi+TLineStyle.DashCount]
        cinvoke XSetBackground, [hApplicationDisplay], [ebx+TContext.handle], [esi+TLineStyle.clSpace]

.exit:
        pop     esi edx ecx ebx eax
        return
endp


proc  SetDrawMode, .context, .mode
begin
        push    eax ecx edx
        mov     eax, [.context]
        cinvoke XSetFunction, [hApplicationDisplay], [eax+TContext.handle], [.mode]
        pop     edx ecx eax
        return
endp





proc SetClipRectangle, .context, .pBounds
.rect XRectangle
begin
        push    eax ecx edx esi

        mov     esi, [.context]

        cmp     [esi+TContext.clipregion], 0
        je      @f
        cinvoke XDestroyRegion, [esi+TContext.clipregion]
@@:
        cinvoke XCreateRegion
        mov     [esi+TContext.clipregion], eax

        mov     edx, [.pBounds]
        test    edx, edx
        jz      .remove

        mov     eax, [edx+TBounds.x]
        mov     [.rect.x], ax

        mov     eax, [edx+TBounds.y]
        mov     [.rect.y], ax

        mov     eax, [edx+TBounds.width]
        mov     [.rect.width], ax

        mov     eax, [edx+TBounds.height]
        mov     [.rect.height], ax

        lea     edx, [.rect]
        cinvoke XUnionRectWithRegion, edx, [esi+TContext.clipregion], [esi+TContext.clipregion]
        cinvoke XSetRegion, [hApplicationDisplay], [esi+TContext.handle], [esi+TContext.clipregion]

.exit:
        pop     esi edx ecx eax
        return

.remove:
        cinvoke XSetClipMask, [hApplicationDisplay], [esi+TContext.handle], None
        jmp     .exit
endp




proc IsDrawable, .raster
begin

;       cinvoke  XSetErrorHandler,





endp
Changes to freshlib/graphics/Linux/draw.asm.
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
29
30
31
32
33
34
35










36
37
38
39
40
41
42







-
-
-
-
-
-
-
-
-
-







        mov     ebx, [.context]
        cinvoke XDrawLine, [hApplicationDisplay], [ebx+TContext.raster], [ebx+TContext.handle], [.x1], [.y1], [.x2], [.y2]
        pop     edx ecx ebx eax
        return
endp


proc DrawFillRect, .context, .x, .y, .width, .height, .color
begin
        push    eax ebx ecx edx
        mov     ebx, [.context]
        cinvoke XSetForeground, [hApplicationDisplay], [ebx+TContext.handle], [.color]
        cinvoke XFillRectangle, [hApplicationDisplay], [ebx+TContext.raster], [ebx+TContext.handle], [.x], [.y], [.width], [.height]
        pop     edx ecx ebx eax
        return
endp



macro Outline [type, x, y] {
  common
local ..types, ..points, ..count
     dd  ..count
     dd  ..types
Changes to freshlib/graphics/Linux/fonts.asm.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66













67
68
69
70
71
72
73
74
75












76
77
78
79
80
81
82






83
84


85
86
87
88
89










90
91
92
93
94
95
96
97
98
99



















100
101
102


103


104


105
106
107



108



109
110


111



112
113


114
115
116



117


118
119
120
121
122












123
124
125
126
127






128
129



130
131
132
133













134
135
136
137
138
139







140
141
142
143




144
145

146
147


148
149

150
151
152
153

154







155
156



157

158




































159
160
8
9
10
11
12
13
14












































15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39





40
41
42
43
44
45
46
47
48
49
50
51
52
53
54




55
56
57
58
59
60


61
62
63




64
65
66
67
68
69
70
71
72
73
74









75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93



94
95
96
97
98
99
100
101



102
103
104
105
106
107
108
109

110
111
112
113
114
115


116
117



118
119
120
121
122
123





124
125
126
127
128
129
130
131
132
133
134
135
136




137
138
139
140
141
142

143
144
145
146




147
148
149
150
151
152
153
154
155
156
157
158
159
160





161
162
163
164
165
166
167




168
169
170
171
172

173


174
175
176

177
178
179
180
181
182

183
184
185
186
187
188
189
190

191
192
193
194
195

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








+
+
+
+
+
+
+
+
+
+
+
+
+




-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+



-
-
-
-
+
+
+
+
+
+
-
-
+
+

-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+

+
+

+
+
-
-
-
+
+
+

+
+
+

-
+
+

+
+
+
-
-
+
+
-
-
-
+
+
+

+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
+
+
+
+
+
+
-

+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+

-
+
-
-
+
+

-
+




+
-
+
+
+
+
+
+
+

-
+
+
+

+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


proc FontCreate, .fontname, .size, .weight, .flags
begin
        push    ebx ecx edx
        stdcall StrDup, [.fontname]
        mov     ebx, eax

        test    [.flags], ffMonospaced
        jz      @f
        stdcall StrCat, ebx, FontAttr.mono
@@:
        sub     [.size], 2
        cmp     [.size], 0
        jle     @f

        stdcall StrCat, ebx, FontAttr.size
        stdcall NumToStr, [.size], ntsDec or ntsUnsigned
        push    eax
        stdcall StrCat, ebx, eax
        stdcall StrDel ; from the stack
@@:
        cmp     [.weight], 0
        je      @f
        shr     [.weight], 2
        stdcall StrCat, ebx, FontAttr.weight
        stdcall NumToStr, [.weight], ntsDec or ntsUnsigned
        push    eax
        stdcall StrCat, ebx, eax
        stdcall StrDel ; from the stack

@@:
        test    [.flags], ffItalic
        jz      @f
        stdcall StrCat, ebx, FontAttr.italic
@@:

        stdcall StrPtr, ebx
        cinvoke XftFontOpenName, [hApplicationDisplay], 0, eax

        stdcall StrDel, ebx
        pop     edx ecx ebx
        return
endp


iglobal
  if used FontAttr.mono | used FontAttr.size | used FontAttr.weight | used FontAttr.italic
    label FontAttr byte
    .mono db ',Mono', 0
    .size db ':pixelsize=', 0
    .weight db ':weight=', 0
    .italic db ':slant=italic', 0
    .regular db ':slant=roman', 0


;fwLight     = 0
;fwDemilight = 1
;fwNormal    = 2
;fwMedium    = 3
;fwDemibold  = 4
;fwBold      = 5
;fwExtraBold = 6
;fwBlack     = 7

    .font_weights db 0, 55, 80, 100, 180, 200, 205, 210
  end if
endg







;initialize InitFonts
;begin
;        cinvoke FcInit
;        return
;endp
;
;
;finalize FinalizeFonts
;begin
;        cinvoke FcFini
;        return
;endp



macro XftPushArg field, type, value {
      push value
      push type
      push field
proc FTCRequester as FT_Face_Requester
.res dd ?
.idx dd ?
.face dd ?
begin
        pushad
      add  ebx, 12
}

        mov     esi, [.face_id]

macro XftStartArguments {
      push 0
      mov  ebx, 4
}
        stdcall StrDup, [esi+__TFont.hFontFace]
        mov     ebx, eax

        test    [esi+__TFont.flags], ffMonospaced
        jz      @f
        stdcall StrCat, ebx, FontAttr.mono
@@:
        mov     eax, [esi+__TFont.weight]
        and     eax, 7
        movzx   eax, byte [FontAttr.font_weights+eax]

XftFamily  text 'family'
XftStyle   text 'style'
XftSpacing text 'spacing'
XftSlant   text 'slant'
XftWeight  text 'weight'
XftWidth   text 'width'
XftPixelSize text 'pixelsize'
XftAntialias text 'antialias'
XftAutohint  text 'autohint'
        stdcall StrCat, ebx, FontAttr.weight
        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        push    eax
        stdcall StrCat, ebx, eax
        stdcall StrDel ; from the stack

        mov     eax, FontAttr.regular
        test    [esi+__TFont.flags], ffItalic
        jz      @f
        mov     eax, FontAttr.italic
@@:
        stdcall StrCat, ebx, eax
        stdcall StrPtr, ebx

;        OutputLn eax

        cinvoke FcNameParse, eax
        stdcall StrDel, ebx

XftHintStyle text 'hintstyle'
XftHinting   text 'hinting'
XftRGBA      text 'rgba'
        test    eax, eax
        jnz     @f

        cinvoke FcNameParse, txt "Helvetica"
        DebugMsg "Error: Bad pattern fallback."

@@:
        mov     ebx, eax
proc FontCreate3, .fontname, .size, .weight, .flags
begin
        push    ebx ecx edx

        cinvoke FcDefaultSubstitute, ebx
        cinvoke FcConfigSubstitute, 0, ebx, 0

        lea     eax, [.res]
        cinvoke FcFontMatch, 0, ebx, eax
        push    eax

        XftStartArguments
        cinvoke FcPatternDestroy, ebx
        pop     ebx

        if defined options.DebugMode & options.DebugMode
          cinvoke FcPatternPrint, ebx
        end if
        cmp     [.fontname], 0
        je      @f

        lea     eax, [.res]
        stdcall StrPtr, [.fontname]
        XftPushArg XftFamily, XftTypeString, eax
@@:
        cinvoke FcPatternGetString, ebx, FC_FILE, 0, eax

        OutputLn [.res]

        lea     eax, [.idx]
        cinvoke FcPatternGetInteger, ebx, FC_INDEX, 0, eax
        cmp     [.size], 2
        jle     @f
        sub     [.size], 2
        XftPushArg XftPixelSize, XftTypeInteger, [.size]
@@:

        mov     edi, [.pFace]
        mov     eax, [.res]
        cinvoke FT_New_Face, [FTLibrary], eax, [.idx], edi

.finish:
        mov     [esp+4*regEAX], eax
        cinvoke FcPatternDestroy, ebx
        popad
        cret
endp


        cmp     [.weight], 0
        jle     @f
        shr     [.weight], 1
        XftPushArg XftWeight,    XftTypeInteger, [.weight]

FC_FILE text 'file'
FC_INDEX text 'index'
FC_PIXEL_SIZE  text 'pixelsize'


@@:

body FontCreate
begin
        push    edx
        test    [.flags], ffItalic
        jz      @f
        XftPushArg XftSlant, XftTypeInteger, XFT_SLANT_ITALIC
@@:

        stdcall GetMem, sizeof.__TFont
        mov     edx, eax

        stdcall StrDupMem, [.font_name]
        mov     [edx+__TFont.hFontFace], eax

        mov     eax, [.size]
        mov     [edx+__TFont.height], eax
        mov     eax, [.weight]
        mov     [edx+__TFont.weight], eax
        mov     eax, [.flags]
        mov     [edx+__TFont.flags], eax

        test    [.flags], ffMonospaced
        jz      @f
        XftPushArg XftSpacing, XftTypeInteger, XFT_MONO
@@:
        XftPushArg XftAntialias, XftTypeBool, 0
        mov     eax, edx
        pop     edx
        return
endp



        XftPushArg XftHinting, XftTypeBool, 0
        XftPushArg XftHintStyle, XftTypeInteger, 0
        XftPushArg XftRGBA, XftTypeInteger, 5
        XftPushArg XftWidth, XftTypeInteger, 100
body FontDestroy
begin
        pushad
        mov     edi, [.pFont]

        invoke  XftFontOpen, [hApplicationDisplay], 0
        cinvoke FTC_Manager_RemoveFaceID, [FTCManager], edi
        add     ebx, 8
        add     esp, ebx
        stdcall StrDel, [edi+__TFont.hFontFace]
        stdcall FreeMem, edi

        pop     edx ecx ebx
        popad
        return
endp


; returns some font metrics

;
; Arguments:
;    .font - the font
; Returns:
;    EAX - the line height of the font.
;    EBX - the ascender of the font.
;    EDX - the descender of the font.

proc FontDestroy, .font
body GetFontMetrics
.scaler  FTC_ScalerRec
.size    dd ?
begin
        push    ecx
        cinvoke XftFontClose, [hApplicationDisplay], [.font]

        mov     edx, [.font]
        xor     ecx, ecx

        mov     [.scaler.face_id], edx
        mov     [.scaler.width], ecx

        mov     eax, [edx+__TFont.height]
        inc     ecx

        mov     [.scaler.height], eax
        mov     [.scaler.pixel], ecx    ; ecx = 1

        lea     eax, [.scaler]
        lea     edx, [.size]
        cinvoke FTC_Manager_LookupSize, [FTCManager], eax, edx
        test    eax, eax
        jnz     .error

        mov     edx, [.size]

        mov     eax, [edx+FT_SizeRec.metrics.height]
        mov     ebx, [edx+FT_SizeRec.metrics.ascender]
        mov     edx, [edx+FT_SizeRec.metrics.descender]

        sar     eax, 6
        sar     ebx, 6
        sar     edx, 6

        clc
        pop     ecx
        return

.error:
        stc
        pop     ecx
        return
endp
Changes to freshlib/graphics/Linux/images.asm.
38
39
40
41
42
43
44
45
46


47
48
49


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
38
39
40
41
42
43
44


45
46
47


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76







-
-
+
+

-
-
+
+



















-
+








        xor     eax, eax
        inc     eax

        mov     ecx, [.width]
        mov     edx, [.height]

        test    ecx, ecx
        cmovz   ecx, eax
        cmp     ecx, 0
        cmovle  ecx, eax

        test    edx, edx
        cmovz   edx, eax
        cmp     edx, 0
        cmovle  edx, eax

        mov     [esi+TImage.width], ecx
        mov     [esi+TImage.height], edx

        lea     eax, [4*ecx]
        imul    eax, edx

        cinvoke shmget, IPC_PRIVATE, eax, IPC_CREAT or 777o
        test    eax, eax
        js      .error

        mov     [esi+TImage.shminfo.ShmID], eax

        cinvoke shmat, eax, 0, 0
        cmp     eax, -1
        je      .error_free

        mov     [esi+TImage.shminfo.Addr], eax
        mov     [esi+TImage.pPixels], eax
        mov     [esi+TImage.shminfo.fReadOnly], 0
        mov     [esi+TImage.shminfo.fReadOnly], 1

        lea     ebx, [esi+TImage.shminfo]
        cinvoke XShmCreateImage, [hApplicationDisplay], 0, $20, ZPixmap, eax, ebx, [esi+TImage.width], [esi+TImage.height]
        mov     [esi+TImage.ximage], eax

        cinvoke XShmAttach, [hApplicationDisplay], ebx

96
97
98
99
100
101
102
103

104
105
106

107
108
109
110
111
112


113
114
115
116
117
118
119
120
121
122
123
124
125
126




























127
128

129

130

131
132
133
134
135
136
137
138
139

140
141


142









143










144

145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119









120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158
159
160
161
162
163


164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197









































-
+



+





-
+
+





-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
-
+

+









+
-
-
+
+

+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
-
+




+





-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

body DestroyImage
begin
        pushad

        mov     esi, [.ptrImage]
        test    esi, esi
        jz      @f
        jz      .finish

        lea     eax, [esi+TImage.shminfo]
        cinvoke XShmDetach, [hApplicationDisplay], eax

        cinvoke XDestroyImage, [esi+TImage.ximage]

        cinvoke shmdt, [esi+TImage.shminfo.Addr]
        cinvoke shmctl, [esi+TImage.shminfo.ShmID], IPC_RMID, 0
        stdcall FreeMem, esi
@@:

.finish:
        popad
        return
endp


if used ___CheckCompletionEvent
___CheckCompletionEvent:
        mov     eax, [esp+8]      ;.pEvent
        mov     eax, [eax+XEvent.type]
        cmp     eax, [ShmCompletionEvent]
        sete    al
        movzx   eax, al
        retn
end if
;if used ___CheckCompletionEvent
;___CheckCompletionEvent:
;
;virtual at esp+4
;  .display dd ?
;  .pEvent  dd ?
;  .user    dd ?
;end virtual
;
;; timeout
;        stdcall GetTimestamp
;        cmp     eax, [.user]
;        jbe     @f
;
;        DebugMsg "Timeout!"
;
;        mov     eax, 1
;        retn
;
;@@:
;        mov     eax, [.pEvent]      ;.pEvent
;        mov     eax, [eax+XEvent.type]
;
;        cmp     eax, [ShmCompletionEvent]
;        sete    al
;        movzx   eax, al
;        retn
;end if



body DrawImage
body DrawImageRect
.event XEvent
       rb 256
begin
        pushad

        mov     esi, [.pImage]
        test    esi, esi
        jz      .exit

        mov     ebx, [esi+TImage.ximage]

        cinvoke XCreateGC, [hApplicationDisplay], [.where], 0, 0
        mov     ecx, [.context]
        cinvoke XShmPutImage, [hApplicationDisplay], [ecx+TContext.raster], [ecx+TContext.handle], [esi+TImage.ximage], 0, 0, [.x], [.y], [esi+TImage.width], [esi+TImage.height], 1
        mov     edi, eax


        cinvoke XShmPutImage, [hApplicationDisplay], [.where], edi, [esi+TImage.ximage], [.xSrc], [.ySrc], [.xDst], [.yDst], [.width], [.height], TRUE


; THIS CODE SOMETIMES CAUSES HANGS!

        stdcall GetTimestamp
        lea     esi, [eax+20]

.loop:
        lea     eax, [.event]
        cinvoke XCheckTypedEvent, [hApplicationDisplay], [ShmCompletionEvent], eax
        test    eax, eax
        jnz     .finish

        stdcall GetTimestamp
        cmp     eax, esi
        jb      .loop


.finish:
        cinvoke XIfEvent, [hApplicationDisplay], eax, ___CheckCompletionEvent, 0
        cinvoke XFreeGC, [hApplicationDisplay], edi

.exit:
        popad
        return

endp




body DrawText
  .cltxt   _XftColor
  .vis     XVisualInfo
begin
        push    eax ebx ecx edx esi edi

        cmp     [.font], 0
        jne     @f

        mov     eax, [_SystemFont]
        mov     [.font], eax

@@:
        cinvoke XDefaultScreen, [hApplicationDisplay]
        mov     edx, eax
        lea     eax, [.vis]
        cinvoke XMatchVisualInfo, [hApplicationDisplay], edx, $20, TrueColor, eax

        mov     ecx, [.pImage]
        cinvoke XftDrawCreate, [hApplicationDisplay], [ecx+TImage.ximage], [.vis.Visual], 0
        mov     ebx, eax

;        mov     ecx, [.context]
;        cinvoke XftDrawSetClip, ebx, [ecx+TContext.clipregion]

        lea     eax, [.cltxt]
        stdcall __ColorToRender, [.color], eax

        cinvoke XftDrawStringUtf8, ebx, eax, [.font], [.x], [.y], [.text], [.len]
        cinvoke XftDrawDestroy, ebx

        pop     edi esi edx ecx ebx eax
        return
endp
Changes to freshlib/graphics/Linux/text.asm.
8
9
10
11
12
13
14
15

16
17
18
19



20
21
22

23
24
25

26
27
28
29




30
31
32
33


34
35
36


37
38
39
40
41
42

43
44

45
46

47
48
49

50
51
52
53
54
55

56
57
58

59
60
61
62
63
64


65
66

67

68

69
70

71
72

73

74

75
76
77
78

79
80
81
82



83
84
85
86
87
88
89
90
91


92
93
94
95
96
97


98
99
100

101


102
103
104

105

106
107
108

109
110

111
112
113
114



115
116


117
118
119
120
121


122
123
124
125


126
127
128
129
130

131
132
133
134
135
136
137
138
139
140




141
142
143
144
145
146
147















148
149
150

151
152
153


154
155



156
157
158


159
160
161




162
163
164



165
166
167


168

169
170


171

172
173

174
175
176

177
178
179
180
181

182
183

184
185
186
187



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

215
216

217
218
219
220
221
222
223
224
225
226
227
228
229
230










231
232

233
234
235






















































































































































































































































































































236
237


238

239
240
241
242
243
244
245
246



247
248

249

250
251
252
253
254
255




256

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274



275
276
277
278
279
280
281
8
9
10
11
12
13
14

15
16



17
18
19



20
21
22
23
24




25
26
27
28
29
30
31

32
33
34


35
36
37





38


39
40

41



42


43



44



45

46




47
48


49
50
51

52


53


54
55
56

57

58


59
60



61
62
63
64








65
66
67





68
69



70
71
72
73


74
75

76

77

78


79



80
81
82
83


84
85


86


87
88




89
90
91



92
93
94
95
96
97
98
99




100
101
102
103







104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

119

120
121


122
123
124

125
126
127
128


129
130
131


132
133
134
135

136

137
138
139
140


141
142
143
144


145
146

147
148

149



150


151


152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168





















169
170

171
172
173
174
175
176
177
178
179
180


181
182
183
184
185
186
187
188
189
190
191
192
193
194

195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511

512
513
514
515

516



517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534

535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563







-
+

-
-
-
+
+
+
-
-
-
+



+
-
-
-
-
+
+
+
+



-
+
+

-
-
+
+

-
-
-
-
-
+
-
-
+

-
+
-
-
-
+
-
-

-
-
-
+
-
-
-
+
-

-
-
-
-
+
+
-
-
+

+
-
+
-
-
+
-
-
+

+
-
+
-

-
-
+

-
-
-
+
+
+

-
-
-
-
-
-
-
-
+
+

-
-
-
-
-
+
+
-
-
-
+

+
+
-
-

+
-
+
-

-
+
-
-
+
-
-
-

+
+
+
-
-
+
+
-
-

-
-
+
+
-
-
-
-
+
+

-
-
-

+






-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-

-
+

-
-
+
+

-
+
+
+

-
-
+
+

-
-
+
+
+
+
-

-
+
+
+

-
-
+
+

+
-
-
+
+
-
+

-
+
-
-
-
+
-
-

-
-
+


+




+
+
+






-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+

-
+









-
-



+
+
+
+
+
+
+
+
+
+

-
+


-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
-
+



-

-
-
-
+
+
+


+

+






+
+
+
+
-
+


















+
+
+







;  Target OS: Linux
;
;  Dependencies:
;
;  Notes: Uses XFT library to renter the text.
;_________________________________________________________________________________________

uses libFT, libFC, libXft
uses libFT, libFC

struct __TFont
  .hFontFace      dd ?    ; The name of the font face.
  .height         dd ?    ; The character height in pixels.

iglobal
  var flagFreeTypeLoadFlags = FT_LOAD_RENDER or FT_LOAD_TARGET_NORMAL or FT_LOAD_COLOR
  .weight         dd ?    ; The weight of the characters.
  .flags          dd ?    ; ffItalic, ffMonospaced, etc.
ends
endg



body DrawDecomposedString      ;, .pImage, .pArray, .x, .y, .font, .color
proc FTCRequester as FT_Face_Requester
.res dd ?
.idx dd ?
.face dd ?
.scaler  FTC_ScalerRec
.glyph   dd ?

.startX  dd ?
begin
        pushad

        mov     esi, [.face_id]
        mov     edx, [.font]
        xor     ecx, ecx

        stdcall StrDup, [esi+__TFont.hFontFace]
        mov     ebx, eax
        mov     [.scaler.face_id], edx
        mov     [.scaler.width], ecx

        test    [esi+__TFont.flags], ffMonospaced
        jz      @f
        stdcall StrCat, ebx, FontAttr.mono
@@:
        mov     eax, [esi+__TFont.weight]
        mov     eax, [edx+__TFont.height]
        test    eax, eax
        jz      @f
        inc     ecx

        shr     eax, 2
        mov     [.scaler.height], eax
        stdcall StrCat, ebx, FontAttr.weight
        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        push    eax
        mov     [.scaler.pixel], ecx    ; ecx = 1
        stdcall StrCat, ebx, eax
        stdcall StrDel ; from the stack

@@:
        test    [esi+__TFont.flags], ffItalic
        jz      @f
        mov     eax, [.x]
        stdcall StrCat, ebx, FontAttr.italic
@@:

        mov     [.startX], eax
        stdcall StrPtr, ebx

        cinvoke FcNameParse, eax
        stdcall StrDel, ebx
        mov     ebx, eax

        mov     esi, [.pArray]
        xor     edi, edi
        cinvoke FcConfigSubstitute, 0, ebx, 0
        cinvoke FcDefaultSubstitute, ebx
        dec     edi

.char_loop:
        lea     eax, [.res]
        inc     edi
        cinvoke FcFontMatch, 0, ebx, eax
        push    eax
        cmp     edi, [esi+TArray.count]
        cinvoke FcPatternDestroy, ebx
        pop     ebx
        jae     .finish

        cmp     word [esi+TArray.array+8*edi+TTextChar.width], 0
        lea     eax, [.res]
        je      .char_ok
        cinvoke FcPatternGetString, ebx, FC_FILE, 0, eax

        lea     eax, [.idx]
        cinvoke FcPatternGetInteger, ebx, FC_INDEX, 0, eax
        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, [esi+TArray.array+8*edi+TTextChar.code]

        mov     edi, [.pFace]
        mov     eax, [.res]
        cinvoke FT_New_Face, [FTLibrary], eax, [.idx], edi
        lea     ecx, [.scaler]
        lea     edx, [.glyph]
        cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0

.finish:
        mov     [esp+4*regEAX], eax
        cinvoke FcPatternDestroy, ebx
        popad
        cret
endp


        test    eax, eax
        jnz     .char_ok

FC_FILE text 'file'
FC_INDEX text 'index'
FC_PIXEL_SIZE  text 'pixelsize'


        mov     ebx, [.glyph]
        mov     ecx, [.x]
proc FontCreate4, .font_name, .size, .weight, .flags
begin
        push    edx
        mov     edx, [.y]

        add     ecx, [ebx+FT_BitmapGlyphRec.left]
        sub     edx, [ebx+FT_BitmapGlyphRec.top]
        stdcall GetMem, sizeof.__TFont
        mov     edx, eax

        lea     eax, [ebx+FT_BitmapGlyphRec.bitmap]
        stdcall StrDupMem, [.font_name]
        stdcall __DrawGlyph, [.pImage], eax, ecx, edx, [.color]
        mov     [edx+__TFont.hFontFace], eax

        mov     eax, [.size]
        movzx   eax, word [esi+TArray.array+8*edi+TTextChar.width]
        mov     [edx+__TFont.height], eax
        mov     eax, [.weight]
        add     [.x], eax
        mov     [edx+__TFont.weight], eax
        mov     eax, [.flags]
        mov     [edx+__TFont.flags], eax

.char_ok:
; check for new line.
        movzx   eax, word [esi+TArray.array+8*edi+TTextChar.height]
        mov     eax, edx
        pop     edx
        test    eax, eax
        jz      .char_loop
        return
endp



        add     [.y], eax
        mov     eax, [.startX]
proc FontDestroy2, .pFont
begin
        pushad
        mov     edi, [.pFont]
        mov     [.x], eax
        jmp     .char_loop

        cinvoke FTC_Manager_RemoveFaceID, [FTCManager], edi
        stdcall StrDel, [edi+__TFont.hFontFace]
        stdcall FreeMem, edi

.finish:
        popad
        return
endp



proc DrawString2, .pImage, .hString, .x, .y, .font, .color
.type    FTC_ImageType
.scaler  FTC_ScalerRec
.size    dd ?

; Draws the string on the image using the specified font and color.
; The string is drawn in one line. The control symbols are not
; processed. The tabs are not expanded or replaced with spaces.
.face    dd ?

.glyph   dd ?
.prev    dd ?
.kerning FT_Vector

begin
;
; Arguments:
;    .pImage  - pointer to the image where to draw the text.
;    .pString - pointer to a UTF-8 string.
;    .len     - how many bytes from the string to be drawn. If -1, the whole string will be drawn.
;    .x       - X coordinate, where to start drawing.
;    .y       - Y coordinate of the baseline where to draw the string.
;    .font    - the font to be used.
;    .color   - ARGB color to draw the glyphs.
;
;;;;;;;; Returns:
;;;;;;;;    EAX - the width of the string in pixels.
;;;;;;;;    EBX - the ascender of the string. It is negative.
;;;;;;;;    EDX - the height of the string in pixels.

        pushad

        shl     [.x], 6
body DrawString ;, .pImage, .pString, .len, .x, .y, .font, .color

        mov     edx, [.font]
        xor     ecx, ecx
.scaler  FTC_ScalerRec
.glyph   dd ?

        mov     [.prev], ecx
.miny    dd ?
.maxy    dd ?
.startX  dd ?

        mov     [.scaler.face_id], edx
        mov     [.type.face_id], edx
begin
        pushad

        mov     eax, [edx+__TFont.height]
        mov     [.scaler.height], eax
        mov     edx, [.font]
        xor     ecx, ecx

        mov     [.scaler.face_id], edx
        mov     [.type.height], eax
        mov     [.scaler.width], ecx
        mov     [.type.width], ecx

        mov     eax, [edx+__TFont.height]
        inc     ecx

        mov     [.scaler.pixel], 1
        mov     [.type.flags], FT_LOAD_RENDER or FT_LOAD_TARGET_LCD or FT_LOAD_COLOR
        mov     [.scaler.height], eax
        mov     [.scaler.pixel], ecx    ; ecx = 1

        ror     ecx, 1                  ; ecx = $80000000
        lea     eax, [.scaler]
        lea     edx, [.size]
        mov     [.maxy], ecx
        dec     ecx
        cinvoke FTC_Manager_LookupSize, [FTCManager], eax, edx
        mov     [.miny], ecx            ; ecx = $7fffffff

        mov     eax, [.size]
        mov     eax, [.x]
        mov     ecx, [eax+FT_SizeRec.face]
        mov     eax, [eax+FT_SizeRec.metrics.ascender]
        mov     [.face], ecx
        mov     [.startX], eax
        sar     eax, 6
        add     [.y], eax

        stdcall StrPtr, [.hString]
        mov     esi, eax
        mov     esi, [.pString]

.char_loop:

        stdcall DecodeUtf8, [esi]
        jc      .finish

        add     esi, edx

        sub     [.len], edx
        jb      .finish

        test    eax, eax
        jz      .finish

        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax

        mov     ebx, eax

; process the kerning;

        cmp     [.prev], 0
        je      .kerning_ok

        lea     eax, [.kerning]
        cinvoke FT_Get_Kerning, [.face], [.prev], ebx, 0, eax
        test    eax, eax
        jnz     .kerning_ok

        mov     eax, [.kerning.x]
;        sar     eax, 6

        add     [.x], eax

.kerning_ok:
        mov     [.prev], ebx

        lea     ecx, [.type]
        lea     ecx, [.scaler]
        lea     edx, [.glyph]
        cinvoke FTC_ImageCache_Lookup, [FTCImageCache], ecx, ebx, edx, 0
        cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0

        test    eax, eax
        jnz     .char_loop

        mov     ebx, [.glyph]

        mov     ecx, [.x]
        mov     edx, [.y]

        sar     ecx, 6

        add     ecx, [ebx+FT_BitmapGlyphRec.left]
        sub     edx, [ebx+FT_BitmapGlyphRec.top]

        cmp     edx, [.miny]
        jge     @f
        mov     [.miny], edx
@@:
        mov     eax, edx
        add     eax, [ebx+FT_BitmapGlyphRec.bitmap.rows]
        cmp     eax, [.maxy]
        jle     @f
        mov     [.maxy], eax
@@:
        lea     eax, [ebx+FT_BitmapGlyphRec.bitmap]
        stdcall DrawGlyph, [.pImage], eax, ecx, edx, [.color]
        stdcall __DrawGlyph, [.pImage], eax, ecx, edx, [.color]

        mov     eax, [ebx+FT_BitmapGlyphRec.root.advance.x]
        sar     eax, 10        ; format 16.16 fixed decimal point.
        sar     eax, 16        ; format 16.16 fixed decimal point.
        add     [.x], eax

        jmp     .char_loop


.finish:
;        mov     eax, [.x]
;        mov     edx, [.maxy]
;        mov     ebx, [.miny]
;        sub     eax, [.startX]
;        sub     edx, ebx
;        sub     ebx, [.y]

;        mov     [esp+4*regEAX], eax
;        mov     [esp+4*regEBX], ebx
;        mov     [esp+4*regEDX], edx

        popad
        return
endp



; returns:
;   EAX - array with decomposed string.
;   EDX - maximal bearing_Y of the string.
;   ECX - maximal descender of the string.

body TextDecompose      ;, .hString, .font

  .scaler  FTC_ScalerRec
  .glyph   dd ?

  .miny    dd ?
  .maxy    dd ?

begin
        pushad

        mov     edx, [.font]
        xor     ecx, ecx

        mov     [.scaler.face_id], edx
        mov     [.scaler.width], ecx

        mov     eax, [edx+__TFont.height]
        inc     ecx

        mov     [.scaler.height], eax
        mov     [.scaler.pixel], ecx    ; ecx = 1

        ror     ecx, 1                  ; ecx = $80000000
        mov     [.maxy], ecx
        dec     ecx
        mov     [.miny], ecx            ; ecx = $7fffffff

        stdcall StrPtr, [.hString]
        mov     esi, eax

        stdcall CreateArray, sizeof.TTextChar
        mov     edi, eax

.char_loop:
        stdcall DecodeUtf8, [esi]
        jc      .finish

        add     esi, edx
        mov     ebx, eax

        test    eax, eax
        jz      .end

        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax

        lea     ecx, [.scaler]
        lea     edx, [.glyph]
        cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0

        xor     ecx, ecx

        test    eax, eax
        jnz     .glyph_size_ok  ; zero width glyph ????

        mov     ecx, [.glyph]

        mov     eax, [ecx+FT_BitmapGlyphRec.top]
        neg     eax

        cmp     eax, [.miny]
        jge     @f
        mov     [.miny], eax
@@:

        add     eax, [ecx+FT_BitmapGlyphRec.bitmap.rows]
        cmp     eax, [.maxy]
        jle     @f
        mov     [.maxy], eax
@@:
        mov     ecx, [ecx+FT_BitmapGlyphRec.root.advance.x]  ; format 16.16 fixed decimal point.
        sar     ecx, 16   ; format 16.16


.glyph_size_ok:

        stdcall AddArrayItems, edi, 1
        mov     edi, edx
        mov     dword [eax+TTextChar.width], ecx
        mov     [eax+TTextChar.code],  ebx
        jmp     .char_loop

.end:
        clc

.finish:
        mov     [esp+4*regEAX], edi

        mov     eax, [.miny]
        neg     eax
        mov     ecx, [.maxy]

        mov     [esp+4*regEDX], eax
        mov     [esp+4*regECX], ecx

        add     ecx, eax
        mov     [edi+TArray.lparam], ecx

        popad
        return
endp



; Returns an array with the widths from the begining of the text to the every character inside the string.


proc GetTextWidthsArray, .hString, .font

  .scaler  FTC_ScalerRec
  .glyph   dd ?

  .x       dd ?

begin
        pushad

        mov     edx, [.font]
        xor     ecx, ecx

        mov     [.scaler.face_id], edx
        mov     [.scaler.width], ecx

        mov     eax, [edx+__TFont.height]
        inc     ecx

        mov     [.scaler.height], eax
        mov     [.scaler.pixel], ecx    ; ecx = 1


        stdcall StrPtr, [.hString]
        mov     esi, eax

        stdcall CreateArray, 4
        mov     edi, eax

        xor     ebx, ebx

.char_loop:
        stdcall DecodeUtf8, [esi]
        jc      .finish

        add     esi, edx
        test    eax, eax
        jz      .end

        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax

        lea     ecx, [.scaler]
        lea     edx, [.glyph]
        cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0

        test    eax, eax
        jnz     .glyph_size_ok  ; zero width glyph ????


        mov     ecx, [.glyph]
        mov     ecx, [ecx+FT_BitmapGlyphRec.root.advance.x]  ; format 16.16 fixed decimal point.

        add     ebx, ecx


.glyph_size_ok:

        stdcall AddArrayItems, edi, 1
        mov     edi, edx

        mov     edx, ebx
        sar     edx, 16         ; format 16.16
        mov     [eax], edx
        jmp     .char_loop

.end:
        clc

.finish:
        mov     [esp+4*regEAX], edi
        popad
        return

.error:
        stc
        popad
        return
endp











; Computes the width and height of the text.
;
; Arguments:
;    .pString - pointer to a UTF-8 string.
;    .len     - how many bytes from the string to be used. If -1 the whole string will be scanned.
;    .font    - the font to be used for the computations.
;
; Returns:
;    EAX - the width of the string in pixels.
;    EBX - the ascender of the string. It is negative.
;    EDX - the height of the string in pixels.


body GetTextBounds      ;, .pString, .len, .font

.scaler  FTC_ScalerRec
.glyph   dd ?

.x       dd ?

.miny    dd ?
.maxy    dd ?

.charlen dd ?

begin
        pushad

        mov     edx, [.font]
        xor     ecx, ecx

        mov     [.scaler.face_id], edx
        mov     [.scaler.width], ecx

        mov     [.x], ecx

        mov     eax, [edx+__TFont.height]
        inc     ecx

        mov     [.scaler.height], eax
        mov     [.scaler.pixel], ecx    ; ecx = 1

        ror     ecx, 1                  ; ecx = $80000000
        mov     [.maxy], ecx
        dec     ecx
        mov     [.miny], ecx            ; ecx = $7fffffff

        mov     esi, [.pString]

.char_loop:
        stdcall DecodeUtf8, [esi]
        jc      .finish

        add     esi, edx
        mov     [.charlen], edx

        test    eax, eax
        jz      .finish

        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax

        lea     ecx, [.scaler]
        lea     edx, [.glyph]
        cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags],  eax, edx, 0

        test    eax, eax
        jnz     .char_loop

        mov     ebx, [.glyph]

        sub     eax, [ebx+FT_BitmapGlyphRec.top]                ; eax = 0 here
        mov     edx, eax
        add     edx, [ebx+FT_BitmapGlyphRec.bitmap.rows]

        cmp     eax, [.miny]
        jge     @f
        mov     [.miny], eax
@@:
        cmp     edx, [.maxy]
        jle     @f
        mov     [.maxy], edx
@@:

        mov     eax, [ebx+FT_GlyphRec.advance.x]
        sar     eax, 16        ; format 16.16 fixed decimal point.
        add     [.x], eax

        mov     eax, [.charlen]
        sub     [.len], eax
        jmp     .char_loop
        ja      .char_loop


.finish:
        mov     edx, [.size]
        mov     eax, [.x]
        mov     edx, [edx+FT_SizeRec.metrics.height]
        sar     eax, 6
        sar     edx, 6
        mov     edx, [.maxy]
        mov     ebx, [.miny]
        sub     edx, ebx

        mov     [esp+4*regEAX], eax
        mov     [esp+4*regEBX], ebx
        mov     [esp+4*regEDX], edx

        popad
        return
endp







proc DrawGlyph, .pImage, .pFTBitmap, .x, .y, .color
proc __DrawGlyph, .pImage, .pFTBitmap, .x, .y, .color
.spitch   dd ?
.dpitch   dd ?

.drect   RECT
.srect   RECT

.pixel_mode dd ?

.sstart dd ?
.dstart dd ?

.xsize  dd ?

.bpp    dd ?
.bit_ofs dd ?

begin
        pushad

        stdcall __fix_color, [.color], regEAX
        mov     [.color], eax

        mov     ebx, [.pImage]
        mov     edi, [.pFTBitmap]

; the glyph pixel mode handling.
        movzx   eax, [edi+FT_Bitmap.pixel_mode]
        cmp     eax, FT_PIXEL_MODE_BGRA
454
455
456
457
458
459
460
461
462


463
464
465
466


467
468

469
470
471




472
473
474


475
476


477

478
479
480
481
482
483
484
485
486
487
488

489
490
491
492


493
494
495



496
497
498
499
500
501
502
503
504



505
506
507
508





509
510
511


512
513
514
515



516
517

518
519
520

521
522
523
524





525
526
527
528
529
530
531
532
533

534
535
536
537


538
539


540
541


542
543
544
545
546
547
548
736
737
738
739
740
741
742


743
744

745


746
747
748

749



750
751
752
753
754


755
756

757
758
759

760

761

762
763
764
765




766




767
768
769


770
771
772
773
774
775
776
777
778
779
780

781
782
783
784



785
786
787
788
789
790


791
792
793



794
795
796
797

798

799

800


801

802
803
804
805
806
807
808
809
810





811




812
813
814

815
816
817

818
819
820
821
822
823
824
825
826







-
-
+
+
-

-
-
+
+

-
+
-
-
-
+
+
+
+

-
-
+
+
-

+
+
-
+
-

-




-
-
-
-
+
-
-
-
-
+
+

-
-
+
+
+








-
+
+
+

-
-
-
+
+
+
+
+

-
-
+
+

-
-
-
+
+
+

-
+
-

-
+
-
-

-
+
+
+
+
+




-
-
-
-
-
+
-
-
-
-
+
+

-
+
+

-
+
+







        dec     [.xsize]
        jnz     .loopx1
        jmp     .nexty



.loopx8:
        movzx   eax, byte [esi]         ; source alpha
        inc     esi
        movzx     eax, byte [esi]         ; intensity
        add       esi, 1
        movzx   ecx, byte [.color+3]    ; color alpha

        imul    eax, ecx
        shr     eax, 8
        movd      mm6, [.color]
        movd      mm7, eax

        mov     ecx, [.color]
        punpcklbw mm6, mm0              ; byte to word color.
        bswap   ecx
        mov     cl, al
        bswap   ecx
        punpckldq mm7, mm7              ;
        packssdw  mm7, mm7              ; mm7 = I, I, I, I

        pmullw    mm7, mm6              ; mm7 is the color to blend = Cs*256

        movd    mm7, ecx                ; source pixel.
        movd    mm6, [edi]              ; destination pixel.
        movd      mm6, [edi]            ; Destination color
        punpcklbw mm6, mm0              ; byte to word destination pixel
        movd    mm5, eax                ; alpha source

        movq      mm5, mm7
        psrlq     mm5, 56               ; alpha source
        punpckldq mm5, mm5              ;
        punpckldq mm5, mm5
        punpcklbw mm6, mm0              ; byte to word destination pixel
        packssdw  mm5, mm5              ; mm5 = As, As, As, As
        punpcklbw mm7, mm0              ; byte to word source pixel

        movq    mm4, mm1
        psubw   mm4, mm5                ; mm4 = Bs Bs Bs Bs     (Bs = $100 - As)

        psrlq   mm5, 16                 ; mm5 = 0  As As As
        por     mm5, mm2                ; mm5 = $100 As As As

        pmullw  mm6, mm4                ; mm6 = Cd = Cd * (256-As) = Cd * Bs   (For alpha Ad = Ad*Bs)
        pmullw  mm6, mm4                ; mm6 = Cd = Cd * (256-As) = Cd * Bs
        pmullw  mm7, mm5                ; Cs = Cs * As                   (For alpha As = $100*As )

        paddusw mm6, mm7                ; Cd = Cs + Cd                   (For alpha Ad = $100*As + Ad*Bs)
        psrlw   mm6, 8                  ; Cd = Cd/256                    (For alpha Ad = As + Ad*Bs/$100)
        paddusw mm6, mm7                ; Cd = 256*Cs + Cd*(256-As)
        psrlw   mm6, 8                  ; Cd = Cd/256

        packuswb mm6, mm0
        movd    [edi], mm6
        packuswb mm6, mm0               ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
        movd     [edi], mm6

        add     edi, 4

        dec     [.xsize]
        jnz     .loopx8
        jmp     .nexty


.loopx24:
        movzx   ecx, byte [.color+3]    ; color alpha.

        movzx   eax, byte [esi]
        movzx   edx, byte [esi+1]

        mov     eax, [esi]              ; source alpha As, As, As
        or      eax, $ff000000          ; eax = $ff Ar Ag Ab
        add     esi, 3
        lea     eax, [eax+2*edx]
        movzx   edx, byte [esi+2]

        add     eax, edx
        shr     eax, 2          ; grayscale.

        movd    mm5, ecx                ; mm5 = 00 00 00 00 00 00 00 Ac
        movd    mm6, eax                ; mm6 = 00 00 00 00 ff Ar Ag Ab
        movd      mm6, [.color]
        movd      mm7, eax

        punpckldq mm5, mm5              ;
        punpcklbw mm6, mm0              ; mm6 = ff Ar Ag Ab  ; byte to word source alpha.
        packssdw  mm5, mm5              ; mm5 = Ac Ac Ac Ac
        punpcklbw mm6, mm0              ; byte to word color.
        punpckldq mm7, mm7              ;
        packssdw  mm7, mm7              ; mm7 = I, I, I, I

        pmullw    mm5, mm6
        pmullw    mm7, mm6              ; mm7 is the color to blend = Cs*256
        psrlw     mm5, 8                ; mm5 = Ac, Ac*Ar, Ac*Ag, Ac*Ab  ; total alpha.

        movd    mm6, [edi]              ; destination pixel.
        movd      mm6, [edi]            ; Destination color
        movd    mm7, [.color]           ; source pixel.

        punpcklbw mm6, mm0              ; byte to word destination pixel
        punpcklbw mm7, mm0              ; byte to word source pixel

        movq      mm5, mm7
        psrlq     mm5, 56               ; alpha source
        punpckldq mm5, mm5
        packssdw  mm5, mm5              ; mm5 = As, As, As, As

        movq    mm4, mm1
        psubw   mm4, mm5                ; mm4 = Bs Bs Bs Bs     (Bs = $100 - As)

        psllq   mm5, 16                 ; mm5 = Ac*Ar Ac*Ag Ac*Ab 0
        psrlq   mm5, 16                 ; mm5 = 0  Ac*Ar Ac*Ag Ac*Ab
        por     mm5, mm2                ; mm5 = $100 Ac*Ar Ac*Ag Ac*Ab

        pmullw  mm6, mm4                ; mm6 = Cd = Cd * (256-As) = Cd * Bs   (For alpha Ad = Ad*Bs)
        pmullw  mm6, mm4                ; mm6 = Cd = Cd * (256-As) = Cd * Bs
        pmullw  mm7, mm5                ; Cs = Cs * As                   (For alpha As = $100*As )

        paddusw mm6, mm7                ; Cd = Cs + Cd                   (For alpha Ad = $100*As + Ad*Bs)
        psrlw   mm6, 8                  ; Cd = Cd/256                    (For alpha Ad = As + Ad*Bs/$100)
        paddusw mm6, mm7                ; Cd = 256*Cs + Cd*(256-As)
        psrlw   mm6, 8                  ; Cd = Cd/256

        packuswb mm6, mm0
        packuswb mm6, mm0               ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
        movd     [edi], mm6

        movd    [edi], mm6

        add     esi, 3
        add     edi, 4

        dec     [.xsize]
        jnz     .loopx24
        jmp     .nexty


589
590
591
592
593
594
595

596
597
598
599
600
601
602
603
604
605
606

607
608
609
610
611
612
613
614
615

616
617
618
619
620

621
622


623
624

625
626
627
628
629
630




631
632

633
634

635
636

637
638
639
640
641
642
643

644
645
646

647
648
649
650
651
652
653
654
655
656





657
658
659
660
661

662
663
664
665
666
667
668

669
670

671
672

673
674
675



676
677

678
679

680
681
682
683
684
685
686
687
688

689
690
691

692
693
694

695
696
697


698
699
700


701
702
703


704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883


884




885




886


887
888
889
890


891
892
893

894

895




896
897
898
899


900


901
902

903

904



905

906



907


908







909
910
911
912
913

914



915
916

917


918

919


920

921
922



923
924
925


926
927

928


929


930

931

932



933

934

935



936
937



938
939
940


941
942
943
944
945
946
947
948
949


























































































































































































































































































+









-
-
+
-
-
-
-

-
-
-
-
+
-
-



+
-
-
+
+

-
+
-

-
-
-
-
+
+
+
+
-
-
+
-
-
+

-
+
-

-
-
-

-
+
-
-
-
+
-
-

-
-
-
-
-
-
-
+
+
+
+
+
-

-
-
-
+

-

-
-

-
+
-
-
+
-

+
-
-
-
+
+
+
-
-
+

-
+
-
-

-
-

-

-
+
-
-
-
+
-

-
+
-
-
-
+
+
-
-
-
+
+

-
-
+
+







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
        add     edi, [.dpitch]

        dec     [.srect.bottom]         ; height
        jnz     .loopy


.finish:
        emms
        popad
        return

.bpp_const db 0, 1, 8, 2, 4, 24, 8, 32

endp



proc GetTextBounds2, .hString, .font

; the colors must be pre-multiplied ARGB.
.type    FTC_ImageType
.scaler  FTC_ScalerRec
.size    dd ?
.face    dd ?

.glyph   dd ?
.prev    dd ?
.kerning FT_Vector

proc _BlendPixel, .dstColor, .srcColor
.x       dd ?

begin
        pushad

        movzx   ecx, byte [.srcColor+3]      ; As
        mov     edx, [.font]
        xor     ecx, ecx
        mov     ebx, $ff
        mov     esi, ebx

        mov     [.x], ecx
        sub     ebx, ecx                     ; 1 - As
        mov     [.prev], ecx

        mov     [.scaler.face_id], edx
        mov     [.type.face_id], edx

        mov     eax, [edx+__TFont.height]
        movzx   eax, byte [.dstColor+3]      ; Ad
        imul    ecx, esi
        mul     ebx
        add     eax, ecx
        mov     [.scaler.height], eax
        mov     [.type.height], eax
        adc     edx, 0
        mov     [.scaler.width], ecx
        mov     [.type.width], ecx
        div     esi

        mov     [.scaler.pixel], 1
        mov     byte [esp+4*regEAX+3], al
        mov     [.type.flags], FT_LOAD_RENDER or FT_LOAD_TARGET_LCD or FT_LOAD_COLOR

        lea     eax, [.scaler]
        lea     edx, [.size]
        cinvoke FTC_Manager_LookupSize, [FTCManager], eax, edx

        mov     eax, [.size]
        movzx   eax, byte [.dstColor]       ; Bd
        mov     eax, [eax+FT_SizeRec.face]
        mov     [.face], eax

        movzx   ecx, byte [.srcColor]       ; Bs
        stdcall StrPtr, [.hString]
        mov     esi, eax

.char_loop:
        stdcall DecodeUtf8, [esi]
        jc      .finish

        add     esi, edx

        test    eax, eax
        imul    ecx, esi
        mul     ebx
        add     eax, ecx
        adc     edx, 0
        div     esi
        jz      .finish

        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax

        mov     ebx, eax
        mov     byte [esp+4*regEAX], al

; process the kerning;

        cmp     [.prev], 0
        je      .kerning_ok

        lea     eax, [.kerning]
        movzx   eax, byte [.dstColor+1]       ; Gd
        cinvoke FT_Get_Kerning, [.face], [.prev], ebx, 0, eax
        test    eax, eax
        movzx   ecx, byte [.srcColor+1]       ; Gs
        jnz     .kerning_ok

        imul    ecx, esi
        mov     eax, [.kerning.x]
        add     [.x], eax

        mul     ebx
        add     eax, ecx
        adc     edx, 0
.kerning_ok:
        mov     [.prev], ebx
        div     esi

        lea     ecx, [.type]
        mov     byte [esp+4*regEAX+1], al
        lea     edx, [.glyph]
        cinvoke FTC_ImageCache_Lookup, [FTCImageCache], ecx, ebx, edx, 0

        test    eax, eax
        jnz     .char_loop

        mov     ebx, [.glyph]

        mov     eax, [ebx+FT_GlyphRec.advance.x]
        movzx   eax, byte [.dstColor+2]       ; Rd
        sar     eax, 10        ; format 16.16 fixed decimal point.
        add     [.x], eax

        movzx   ecx, byte [.srcColor+2]       ; Rs
        jmp     .char_loop


        imul    ecx, esi
.finish:
        mov     edx, [.size]
        mov     eax, [.x]
        mul     ebx
        add     eax, ecx
        mov     edx, [edx+FT_SizeRec.metrics.height]
        sar     eax, 6
        sar     edx, 6
        adc     edx, 0
        div     esi

        mov     [esp+4*regEAX], eax
        mov     [esp+4*regEDX], edx
        mov     byte [esp+4*regEAX+2], al


        popad
        return
endp

















proc __ColorToRender, .color, .rendercolor
begin
        push    eax ecx edx

        mov     edx, [.rendercolor]

        xor     eax, eax
        xor     ecx, ecx
        dec     eax
        dec     ecx

        mov     ah, byte [.color]
        mov     ch, byte [.color+1]

        mov     [edx+_XftColor.color.blue], ax
        mov     [edx+_XftColor.color.green], cx

        mov     ah, byte [.color+2]
        mov     ch, byte [.color+3]
        mov     [edx+_XftColor.color.red], ax
        mov     [edx+_XftColor.color.alpha], cx

        pop     edx ecx eax
        return
endp



proc DrawString, .context, .ptrString, .len, .x, .y, .font, .color
  .cltxt   _XftColor
  .vis     XVisualInfo
begin
        push    eax ebx ecx edx esi edi

        cmp     [.font], 0
        jne     @f

        mov     eax, [_SystemFont]
        mov     [.font], eax

@@:
        cinvoke XDefaultScreen, [hApplicationDisplay]
        mov     edx, eax
        lea     eax, [.vis]
        cinvoke XMatchVisualInfo, [hApplicationDisplay], edx, $20, TrueColor, eax

        mov     ecx, [.context]
        cinvoke XftDrawCreate, [hApplicationDisplay], [ecx+TContext.raster], [.vis.Visual], 0
        mov     ebx, eax

        mov     ecx, [.context]
        cinvoke XftDrawSetClip, ebx, [ecx+TContext.clipregion]

        lea     eax, [.cltxt]
        stdcall __ColorToRender, [.color], eax

        cinvoke XftDrawStringUtf8, ebx, eax, [.font], [.x], [.y], [.ptrString], [.len]
        cinvoke XftDrawDestroy, ebx

        pop     edi esi edx ecx ebx eax
        return
endp




proc DrawStringOpaque, .context, .ptrString, .len, .x, .y, .font, .color, .background
  .cltxt   _XftColor
  .vis     XVisualInfo
begin
        push    eax ebx ecx edx esi edi

        cmp     [.font], 0
        jne     @f

        mov     eax, [_SystemFont]
        mov     [.font], eax

@@:
        cinvoke XDefaultScreen, [hApplicationDisplay]
        mov     edx, eax
        lea     eax, [.vis]
        cinvoke XMatchVisualInfo, [hApplicationDisplay], edx, $20, TrueColor, eax

        mov     ecx, [.context]
        cinvoke XftDrawCreate, [hApplicationDisplay], [ecx+TContext.raster], [.vis.Visual], 0
        mov     ebx, eax

        mov     ecx, [.context]
        cinvoke XftDrawSetClip, ebx, [ecx+TContext.clipregion]

        lea     eax, [.cltxt]
        stdcall __ColorToRender, [.color], eax

        cinvoke XftDrawStringUtf8, ebx, eax, [.font], [.x], [.y], [.ptrString], [.len]
        cinvoke XftDrawDestroy, ebx

        pop     edi esi edx ecx ebx eax
        return
endp



proc DrawColoredString, .context, .ptrString, .pCharAttr, .str_len_bytes, .x, .y, .char_offs, .fontwidth, .fontheight
.xbeg   dd ?
.cltxt  _XftColor
.char   dd ?
.height dd ?
.offs   dd ?
.skip   dd ?

.vis    XVisualInfo
begin
        push    eax ebx ecx edx esi edi

        mov     esi, [.pCharAttr]

        mov     eax, [.x]
        mov     [.xbeg], eax

        cinvoke XDefaultScreen, [hApplicationDisplay]
        mov     edx, eax
        lea     eax, [.vis]
        cinvoke XMatchVisualInfo, [hApplicationDisplay], edx, $20, TrueColor, eax

        mov     ecx, [.context]
        cinvoke XftDrawCreate, [hApplicationDisplay], [ecx+TContext.raster], [.vis.Visual], 0
        mov     ebx, eax

        mov     ecx, [.context]
        cinvoke XftDrawSetClip, ebx, [ecx+TContext.clipregion]

        lea     edi, [.cltxt]

        stdcall GetTextBounds, [.context], __HeightProbeString, __HeightProbeString.length, [esi+TCharAttr.font]
        mov     [.height], edx

        stdcall GetTextOffset, [.context], __HeightProbeString, __HeightProbeString.length, [esi+TCharAttr.font]
        mov     [.offs], edx

.skip_offset:
        mov     ecx, [.char_offs]
        mov     [.skip], ecx

.drawloop:
        cmp     [.str_len_bytes], 0
        jle     .enddraw

        mov     ecx, [.ptrString]
        stdcall DecodeUtf8, [ecx]
        mov     [.char], edx

        cmp     eax, $01        ; word wrap character
        je      .wrapline

        cmp     [.skip], 0
        jg      .drawok

;        mov     ecx, [.y]
;        sub     ecx, [.offs]
;        sub     ecx, 2
;        stdcall DrawFillRect, [.context], [.x], ecx, [.fontwidth], [.height], [esi+TCharAttr.backbround]

        stdcall __ColorToRender, [esi+TCharAttr.color], edi
        cinvoke XftDrawStringUtf8, ebx, edi, [esi+TCharAttr.font], [.x], [.y], [.ptrString], [.char]

        mov     eax, [.fontwidth]
        add     [.x], eax
;        sub     [.width], eax
;        js      .enddraw

.drawok:
        dec     [.skip]
        mov     eax, [.char]
        add     [.ptrString], eax
        sub     [.str_len_bytes], eax

        add     esi, sizeof.TCharAttr
        jne     .drawloop

.enddraw:
        cinvoke XftDrawDestroy, ebx
        pop     edi esi edx ecx ebx eax
        return

.wrapline:
        mov     eax, [.fontheight]
        add     [.y], eax
        mov     eax, [.xbeg]
        mov     [.x], eax

        mov     eax, [.char]
        add     [.ptrString], eax
        sub     [.str_len_bytes], eax

        add     esi, sizeof.TCharAttr
        jmp     .skip_offset

endp







; returns:
;       eax - width of the string in pixels.
;       edx - heigth of the string in pixels.


proc GetTextBounds, .context, .ptrString, .len, .font
.extents _XGlyphInfo
begin
        push    esi ecx

        cmp     [.font], 0
        jne     @f

        mov     eax, [_SystemFont]
        mov     [.font], eax

@@:
        lea     esi, [.extents]
        cinvoke   XftTextExtentsUtf8, [hApplicationDisplay], [.font], [.ptrString], [.len], esi

        movzx   eax, [esi+_XGlyphInfo.xOff]
        movzx   edx, [esi+_XGlyphInfo.height]
        add     edx, 2

        pop     ecx esi
        return
endp


; returns:
;       eax - x offset of the baseline of the string.
;       edx - y offset of the baseline of the string.

proc GetTextOffset, .context, .ptrString, .len, .font
.extents _XGlyphInfo
begin
        push    esi ecx

        cmp     [.font], 0
        jne     @f

        mov     eax, [_SystemFont]
        mov     [.font], eax

@@:
        lea     esi, [.extents]
        cinvoke   XftTextExtentsUtf8, [hApplicationDisplay], [.font], [.ptrString], [.len], esi

        movzx   eax, [esi+_XGlyphInfo.x]
        movzx   edx, [esi+_XGlyphInfo.y]
        add     edx, 2

        pop     ecx esi
        return
endp
Deleted freshlib/graphics/Win32/backbuffer.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118






















































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Provides raster bitmap, to be used for double buffer painting.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________



proc CreateBackBuffer, .hwin, .width, .height
begin
        push    ebx ecx edx

        stdcall GetMem, sizeof.TBackBuffer
        mov     ebx, eax

        mov     ecx, [.width]
        mov     edx, [.height]

        test    ecx, ecx
        jns     @f
        xor     ecx, ecx
@@:
        test    edx, edx
        jns     @f
        xor     edx, edx
@@:
        mov     [ebx+TBackBuffer.width], ecx
        mov     [ebx+TBackBuffer.height], edx

        invoke  GetDC, [.hwin]
        push    eax
        invoke  CreateCompatibleBitmap, eax, [ebx+TBackBuffer.width], [ebx+TBackBuffer.height]
        mov     [ebx+TBackBuffer.raster], eax

        invoke  ReleaseDC, [.hwin] ; from the stack

        mov     eax, ebx
        pop     edx ecx ebx
        return
endp



proc DestroyBackBuffer, .pBackBuffer
begin
        push    eax ecx edx
        mov     eax, [.pBackBuffer]
        push    eax
        invoke  DeleteObject, [eax+TBackBuffer.raster]
        stdcall FreeMem ; from the stack
        pop     edx ecx eax
        return
endp



proc DrawBackBuffer, .context, .pBackBuffer, .x, .y
begin
        push    eax ecx edx esi edi
        mov     esi, [.pBackBuffer]

        stdcall AllocateContext, [esi+TBackBuffer.raster]
        jc      .exit
        mov     edi, eax

        mov     ecx, [.context]
        invoke  BitBlt, [ecx+TContext.handle], [.x], [.y], [esi+TBackBuffer.width], [esi+TBackBuffer.height], [edi+TContext.handle], 0, 0, SRCCOPY

        stdcall ReleaseContext, edi

.exit:
        pop     edi esi edx ecx eax
        return


endp






proc BackBufferToImage, .context, .backbuffer, .bpp
.bi BITMAPINFOHEADER
begin
        pushad

        mov     esi, [.backbuffer]
        mov     ebx, [.context]

        stdcall CreateImage, [esi+TBackBuffer.width], [esi+TBackBuffer.height], [.bpp]
        mov     edi, eax

        mov     [.bi.biSize], 40
        mov     ecx, [esi+TBackBuffer.width]
        mov     edx, [esi+TBackBuffer.height]
        mov     [.bi.biWidth], ecx
        mov     [.bi.biHeight], edx
        mov     [.bi.biPlanes], 1
        mov     ecx, [.bpp]
        mov     [.bi.biBitCount], cx
        mov     [.bi.biCompression], 0

        lea     eax, [.bi]
        invoke  GetDIBits, [ebx+TContext.handle], [esi+TBackBuffer.raster], 0, [esi+TBackBuffer.height], [edi+TImage.pData], eax, DIB_RGB_COLORS

        mov     [esp+4*regEAX], edi
        popad
        return
endp
Deleted freshlib/graphics/Win32/context.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303















































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Context is a object that represents drawing surface in FreshLib
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

uses user32, gdi32

; Some of these constants are probably wrong!
cmClear        =     R2_BLACK
cmAnd          =     R2_MASKPEN
cmAndReverse   =     R2_NOTMASKPEN
cmCopy         =     R2_COPYPEN
cmAndInverted  =     R2_MASKPENNOT
cmNoOp         =     R2_NOP
cmXor          =     R2_XORPEN
cmOr           =     R2_MERGEPEN
cmNor          =     R2_NOTMERGEPEN
cmEquiv        =     R2_NOTXORPEN
cmInvert       =     R2_NOT
cmOrReverse    =     R2_MERGENOTPEN
cmCopyInverted =     R2_NOTCOPYPEN
cmOrInverted   =     R2_NOTMERGEPEN
cmNand         =     R2_NOTMASKPEN
cmSet          =     R2_WHITE


proc AllocateContext, .raster
begin
        push    ebx ecx edx

        stdcall GetMem, sizeof.TContext
        mov     ebx, eax

        push    [.raster]
        pop     [ebx+TContext.raster]

        invoke  IsWindow, [.raster]
        test    eax, eax
        jz      .not_window

        invoke  GetDC, [.raster]
        mov     [ebx+TContext.handle], eax
        test    eax, eax
        jz      .error

        invoke  SaveDC, [ebx+TContext.handle]

.exit_ok:
        mov     eax, ebx
        pop     edx ecx ebx
        clc
        return

.not_window:    ; then it must be handle to image bitmap...
        invoke  GetObjectType, [.raster]
        cmp     eax, OBJ_BITMAP
        jne     .error

        invoke  CreateCompatibleDC, 0
        mov     [ebx+TContext.handle], eax
        test    eax, eax
        jz      .error

        invoke  SaveDC, ebx
        invoke  SelectObject, [ebx+TContext.handle], [.raster]
        jmp     .exit_ok

.error:
        stdcall FreeMem, ebx
        xor     eax, eax
        pop     edx ecx ebx
        stc
        return
endp




proc ReleaseContext, .context
begin
        push    eax ebx ecx edx

        mov     ebx, [.context]

; delete all selected objects...
        invoke  GetCurrentObject, [ebx+TContext.handle], OBJ_PEN
        push    eax
        invoke  GetCurrentObject, [ebx+TContext.handle], OBJ_BRUSH
        push    eax
        invoke  GetCurrentObject, [ebx+TContext.handle], OBJ_FONT
        push    eax

        invoke  RestoreDC, [ebx+TContext.handle], -1

        invoke  DeleteObject ; from the stack
        invoke  DeleteObject ; from the stack
        invoke  DeleteObject ; from the stack

        invoke  GetObjectType, [ebx+TContext.handle]
        cmp     eax, OBJ_MEMDC
        je      .delete

        cmp     eax, OBJ_DC
        je      .release

        stc
.exit:
        pop     edx ecx ebx eax
        return

.delete:
        invoke  DeleteDC, [ebx+TContext.handle]
        jmp     .free

.release:
        invoke  ReleaseDC, [ebx+TContext.raster] , [ebx+TContext.handle]

.free:
        stdcall FreeMem, ebx
        clc
        jmp     .exit
endp



proc  SetDrawMode, .context, .mode
begin
        push    eax ebx ecx edx
        mov     ebx, [.context]
        test    ebx, ebx
        jz      .finish

        push    [.mode]
        pop     [ebx+TContext.drawmode]
        invoke  SetROP2, [ebx+TContext.handle], [.mode]

.finish:
        pop     edx ecx ebx eax
        return
endp




proc SetLineStyle, .context, .pLineStyle
begin
        push    eax ebx ecx edx esi

        mov     ebx, [.pLineStyle]
        mov     esi, [.context]

        mov     eax, [ebx+TLineStyle.color]
        bswap   eax                             ; FreshLib uses Linux type color - red in the MSB
        ror     eax, 8
        xor     eax, $ff000000

        mov     edx, PS_SOLID
        cmp     [ebx+TLineStyle.DashCount], 0
        je      @f
        mov     edx, PS_DOT
        mov     [ebx+TLineStyle.width], 0
@@:
        invoke  CreatePen, edx, [ebx+TLineStyle.width], eax     ;[ebx+TLineStyle.color]
        invoke  SelectObject, [esi+TContext.handle], eax
        invoke  DeleteObject, eax

        cmp     [ebx+TLineStyle.DashCount], 0
        je      .exit

        mov     eax, [ebx+TLineStyle.clSpace]
        bswap   eax                             ; FreshLib uses Linux type color - red in the MSB
        ror     eax, 8
        xor     eax, $ff000000

        invoke  SetBkColor, [esi+TContext.handle], eax
        invoke  SetBkMode, [esi+TContext.handle], OPAQUE


.exit:
        pop     esi edx ecx ebx eax
        return
endp






proc SetClipRectangle, .context, .pBounds
begin
        push    eax ebx ecx edx

        xor     ebx, ebx
        mov     edx, [.pBounds]
        test    edx, edx
        jz      .setit

        mov     eax, [edx+TBounds.width]
        mov     ecx, [edx+TBounds.height]
        add     eax, [edx+TBounds.x]
        add     ecx, [edx+TBounds.y]
        invoke  CreateRectRgn, [edx+TBounds.x], [edx+TBounds.y], eax, ecx
        mov     ebx, eax

.setit:
        mov     edx, [.context]
        invoke  SelectClipRgn, [edx+TContext.handle], ebx

        test    ebx, ebx
        jz      .exit
        invoke  DeleteObject, ebx
.exit:
        pop     edx ecx ebx eax
        return
endp




;proc SetLineStyle, .context, .pLineStyle
;.brush LOGBRUSH
;.width dd ?
;.dashcount dd ?
;.dashes rd 16
;begin
;        push    eax ebx ecx edx esi
;
;        mov     ebx, [.pLineStyle]
;        mov     esi, [.context]
;
;        mov     ecx, [ebx+TLineStyle.DashCount]
;        cmp     ecx, 16
;        jbe     @f
;        mov     ecx, 16
;@@:
;        mov     [.dashcount], ecx
;
;.dashloop:
;        dec     ecx
;        js      .enddash
;        movzx   eax, byte [ebx+TLineStyle.DashItems+ecx]
;        mov     [.dashes+4*ecx], eax
;        jmp     .dashloop
;
;.enddash:
;        push    [ebx+TLineStyle.width]
;        pop     [.width]
;
;        mov     [.brush.lbStyle], BS_SOLID
;        mov     eax, [ebx+TLineStyle.color]
;        bswap   eax                             ; FreshLib uses Linux type color - red in the MSB
;        ror     eax, 8
;
;        mov     [.brush.lbColor], eax
;
;        mov     edx, PS_SOLID
;        xor     ecx, ecx
;        cmp     [.dashcount], 0
;        je      @f
;        mov     edx, PS_USERSTYLE
;        lea     ecx, [.dashes]
;@@:
;
;        or      edx, PS_GEOMETRIC
;        cmp     [.width], 0
;        jne     @f
;        and     edx, not PS_GEOMETRIC
;        inc     [.width]
;@@:
;        or      edx, [ebx+TLineStyle.flags]
;        lea     eax, [.brush]
;
;        invoke  ExtCreatePen, edx, [.width], eax, [.dashcount], ecx
;        invoke  SelectObject, [esi+TContext.handle], eax
;
;
;        invoke  SetBkMode, [esi+TContext.handle], OPAQUE
;
;        mov     eax, [ebx+TLineStyle.color]
;        cmp     [ebx+TLineStyle.DashCount], 0
;        je      @f
;        mov     eax, [ebx+TLineStyle.clSpace]
;@@:
;        bswap   eax                             ; FreshLib uses Linux type color - red in the MSB
;        ror     eax, 8
;
;        invoke  SetBkColor, [esi+TContext.handle], eax
;
;        pop     esi edx ecx ebx eax
;        return
;endp
;


Changes to freshlib/graphics/Win32/fonts.asm.
9
10
11
12
13
14
15



















16

17
18
19
20






21
22
23

24
25
26
27


28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49




















50
51
52
53
54
55





56
57

58
59
60

61
62
63

































9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50


51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

107
108
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+




+
+
+
+
+
+


-
+


-
-
+
+





-
+
















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






+
+
+
+
+

-
+


-
+



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


iglobal
  if used FontAttr.font_weights

;fwLight     = 0
;fwDemilight = 1
;fwNormal    = 2
;fwMedium    = 3
;fwDemibold  = 4
;fwBold      = 5
;fwExtraBold = 6
;fwBlack     = 7

    FontAttr:
      .font_weights dw FW_THIN, FW_EXTRALIGHT, FW_NORMAL, FW_MEDIUM, FW_SEMIBOLD, FW_BOLD, FW_EXTRABOLD, FW_HEAVY
  end if
endg



proc FontCreate, .fontface, .size, .weight, .flags
body FontCreate
.pwc dd ?
begin
        push    ebx ecx edx esi edi

        mov     eax, [.weight]
        and     eax, 7
        movzx   eax, [FontAttr.font_weights+2*eax]

        mov     [.weight], eax

        neg     [.size]

        stdcall StrLen, [.fontface]
        stdcall StrLen, [.font_name]
        mov     ebx, eax

        stdcall StrPtr, [.fontface]
        mov     [.fontface], eax
        stdcall StrPtr, [.font_name]
        mov     [.font_name], eax

        lea     ecx, [8*ebx]
        stdcall GetMem, ecx
        mov     edi, eax

        invoke  MultiByteToWideChar, CP_UTF8, 0, [.fontface], ebx, edi, ecx
        invoke  MultiByteToWideChar, CP_UTF8, 0, [.font_name], ebx, edi, ecx

        mov     eax, [.flags]
        mov     ebx, eax
        mov     ecx, eax
        mov     edx, eax
        and     ebx, ffItalic
        and     ecx, ffUnderline
        and     edx, ffStrikeOut
        and     eax, ffMonospaced
        jz      @f
        mov     eax, FIXED_PITCH
@@:
        invoke  CreateFontW, [.size], 0, 0, 0, [.weight], ebx, ecx, edx,         \
                                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,        \
                                    CLIP_DEFAULT_PRECIS, PROOF_QUALITY, eax,  \
                                    edi

      if defined options.DebugMode & options.DebugMode
        pushad
        mov     esi, eax

        invoke        CreateCompatibleDC, 0
        mov           ebx, eax

        invoke  SelectObject, ebx, esi
        push    eax

        invoke  GetTextFaceA, ebx, 1024, fontName

        OutputLn fontName

        invoke  SelectObject, ebx ; from the stack
        invoke  DeleteObject, ebx

        popad
      end if

        stdcall FreeMem, edi
        pop     edi esi edx ecx ebx
        return
endp

uglobal
  if defined options.DebugMode & options.DebugMode
    fontName rb 1024
  end if
endg

proc FontDestroy, .font
body FontDestroy
begin
        push    eax ecx edx
        invoke  DeleteObject, [.font]
        invoke  DeleteObject, [.pFont]
        pop     edx ecx eax
        return
endp


; returns some font metrics
;
; Arguments:
;    .font - the font
; Returns:
;    EAX - the line height of the font.
;    EBX - the ascender of the font.
;    EDX - the descender of the font.

body GetFontMetrics
.tm TEXTMETRIC
begin
        invoke  CreateCompatibleDC, 0
        mov     ebx, eax

        invoke  SelectObject, ebx, [.font]
        push    eax

        lea     eax, [.tm]
        invoke  GetTextMetricsW, ebx, eax

        invoke  SelectObject, ebx ; from the stack

        invoke  DeleteDC, ebx

        mov     eax, [.tm.tmHeight]
        mov     ebx, [.tm.tmAscent]
        mov     edx, [.tm.tmDescent]

        return
endp
Changes to freshlib/graphics/Win32/images.asm.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37

38
39
40
41
42

43
44
45
46
47
48
49
50
51


52
53
54


55
56
57
58
59
60


61
62
63
64
65
66
67





68
69
70
71
72

73
74
75


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93


94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115

116
117
118
119
120

121
122

123
124
125
126


127
128
129

130
131
132

133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175





























176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209






























210
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28


29

30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48


49
50
51


52
53
54
55
56
57


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128

129


130
131



132
133

134

135


136
137

138
139
140
141
142
143
144

145






146
147


























148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176


































177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207







-
+













-
-

-
+





+




-
+







-
-
+
+

-
-
+
+




-
-
+
+







+
+
+
+
+





+

-
-
+
+


















+
+


+

















-
+


+




-
+
-
-
+

-
-
-
+
+
-

-
+
-
-

+
-
+






-

-
-
-
-
-
-


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

;  Target OS: Win32
;
;  Dependencies: memory.asm
;
;  Notes:
;_________________________________________________________________________________________

uses msimg32
uses msimg32, gdi32


struct TImage
  .width   dd ?  ; width in pixels.
  .height  dd ?  ; height in pixels.
  .pPixels dd ?  ; pointer to the pixel memory.

; os dependent data
  .hBitmap dd ?
ends



; only 16, 24 and 32 bpp are supported.
; It is stupid to support palleted modes and even 24bpp is not good...
body CreateImage
.bmi BITMAPINFOHEADER
  .bmi BITMAPV4HEADER
begin
        pushad

        stdcall GetMem, sizeof.TImage
        jc      .finish

        mov     esi, eax

        xor     eax, eax
        lea     edi, [.bmi]
        mov     ecx, sizeof.BITMAPINFOHEADER/4
        mov     ecx, sizeof.BITMAPV4HEADER/4
        rep stosd

        inc     eax

        mov     ecx, [.width]
        mov     edx, [.height]

        test    ecx, ecx
        cmovz   ecx, eax
        cmp     ecx, 0
        cmovle  ecx, eax

        test    edx, edx
        cmovz   edx, eax
        cmp     edx, 0
        cmovle  edx, eax

        mov     [esi+TImage.width], ecx
        mov     [esi+TImage.height], edx

        mov     [.bmi.biSize], sizeof.BITMAPINFOHEADER
        mov     [.bmi.biPlanes], ax
        mov     [.bmi.biSize], sizeof.BITMAPV4HEADER
        mov     [.bmi.biPlanes], 1

; it is already 0
;        mov     [.bmi.biCompression], BI_RGB
;        mov     [.bmi.biSizeImage], 0
;        mov     [.bmi.biClrUsed], 0
;        mov     [.bmi.biClrImportant], 0

        mov     [.bmi.BlueMask],  $000000ff
        mov     [.bmi.GreenMask], $0000ff00
        mov     [.bmi.RedMask],   $00ff0000
        mov     [.bmi.AlphaMask], $ff000000

        mov     [.bmi.biBitCount], 32
        neg     edx
        mov     [.bmi.biWidth], ecx
        mov     [.bmi.biHeight], edx

        lea     eax, [.bmi]
        lea     ecx, [esi+TImage.pPixels]
        lea     eax, [.bmi]
        invoke  CreateDIBSection, 0, eax, DIB_RGB_COLORS, ecx, 0, 0
        xor     edx, edx
        invoke  CreateDIBSection, edx, eax, DIB_RGB_COLORS, ecx, edx, edx
        mov     [esi+TImage.hBitmap], eax

        clc
        mov     [esp+4*regEAX], esi

.finish:
        popad
        return
endp


body DestroyImage
begin
        push    eax ecx edx esi

        mov     esi, [.ptrImage]
        cmp     esi, 0
        je      @f

        invoke  GdiFlush
        invoke  DeleteObject, [esi+TImage.hBitmap]
        stdcall FreeMem, esi

@@:
        pop     esi edx ecx eax
        return
endp



;AC_SRC_OVER =  $00000000
;AC_SRC_ALPHA = $01000000
;
;struct BLENDFUNCTION
;  .BlendOp             db ?
;  .BlendFlags          db ?
;  .SourceConstantAlpha db ?
;  .AlphaFormat         db ?
;ends

body DrawImage
body DrawImageRect
begin
        push    eax ecx edx esi edi

        mov     esi, [.pImage]
        test    esi, esi
        jz      .exit

        stdcall AllocateContext, [esi+TImage.hBitmap]
        invoke  CreateCompatibleDC, 0
        jc      .exit
        mov     edi, eax
        mov     ebx, eax

        mov     ecx, [.context]
        mov     eax, [ecx+TContext.drawmode]
        dec     eax
        invoke  SelectObject, ebx, [esi+TImage.hBitmap]
        push    eax
        and     eax, $0f


        invoke  BitBlt, [.where], [.xDst], [.yDst], [.width], [.height], ebx, [.xSrc], [.ySrc], SRCCOPY
;        invoke  AlphaBlend, [ecx+TContext.handle], [.x], [.y], [esi+TImage.width], [esi+TImage.height], [edi+TContext.handle], 0, 0, [esi+TImage.width], [esi+TImage.height], $01ff0000
        invoke  BitBlt, [ecx+TContext.handle], [.x], [.y], [esi+TImage.width], [esi+TImage.height], [edi+TContext.handle], 0, 0, [4*eax+__RopTable]

        invoke  SelectObject, ebx ; from the stack
        stdcall ReleaseContext, edi
        invoke  DeleteDC, ebx

.exit:
        pop     edi esi edx ecx eax
        return
endp

; NEEDS some edit to fill the zeroes.

if used __RopTable
__RopTable dd  BLACKNESS, PATPAINT,    0,          NOTSRCCOPY, \
               0,         DSTINVERT,   SRCINVERT,  SRCERASE,   \
               SRCAND,    0,           0,          0,          \
               SRCCOPY,   MERGEPAINT,  SRCPAINT,   WHITENESS
end if



body DrawText
.pwc dd ?
.pwl dd ?
.buffer  rb 256
.charlen dd ?
begin
        push    eax ebx ecx edx

; first convert the string:
        lea     eax, [.buffer]
        mov     ecx, [.len]
        shl     ecx, 3
        cmp     ecx, $100
        jbe     @f

        stdcall GetMem, ecx

@@:
        mov     [.pwl], ecx
        mov     [.pwc], eax

        invoke  MultiByteToWideChar, CP_UTF8, 0, [.text], [.len], [.pwc], ecx
        mov     [.charlen], eax


;body DrawText
;.pwc dd ?
;.pwl dd ?
;.buffer  rb 256
;.charlen dd ?
;begin
;        push    eax ebx ecx edx
;
;; first convert the string:
;        lea     eax, [.buffer]
;        mov     ecx, [.len]
;        shl     ecx, 3
;        cmp     ecx, $100
;        jbe     @f
;
;        stdcall GetMem, ecx
;
;@@:
;        mov     [.pwl], ecx
;        mov     [.pwc], eax
;
;        invoke  MultiByteToWideChar, CP_UTF8, 0, [.text], [.len], [.pwc], ecx
;        mov     [.charlen], eax
;
;
;        mov     ebx, [.pImage]
;        stdcall AllocateContext, [ebx+TImage.hBitmap]
;        mov     ebx, eax
;
        mov     ebx, [.pImage]
        stdcall AllocateContext, [ebx+TImage.hBitmap]
        mov     ebx, eax

        cmp     [.font], 0
        jne     @f

        invoke  GetStockObject, DEFAULT_GUI_FONT
        mov     [.font], eax

@@:
        invoke  SelectObject, [ebx+TContext.handle], [.font]
        push    eax

        invoke  SetBkMode, [ebx+TContext.handle], TRANSPARENT
        invoke  SetTextAlign, [ebx+TContext.handle], TA_NOUPDATECP or TA_LEFT or TA_BASELINE

        mov     eax, [.color]
        bswap   eax
        ror     eax, 8
        invoke  SetTextColor, [ebx+TContext.handle], eax
        invoke  TextOutW, [ebx+TContext.handle], [.x], [.y], [.pwc], [.charlen]

        invoke  SelectObject, [ebx+TContext.handle] ; old font from the stack.

        cmp     [.pwl], $100
        jbe     @f
        stdcall FreeMem, [.pwc]
@@:
        stdcall ReleaseContext, ebx

        pop     edx ecx ebx eax
        return
endp
;        cmp     [.font], 0
;        jne     @f
;
;        invoke  GetStockObject, DEFAULT_GUI_FONT
;        mov     [.font], eax
;
;@@:
;        invoke  SelectObject, [ebx+TContext.handle], [.font]
;        push    eax
;
;        invoke  SetBkMode, [ebx+TContext.handle], TRANSPARENT
;        invoke  SetTextAlign, [ebx+TContext.handle], TA_NOUPDATECP or TA_LEFT or TA_BASELINE
;
;        mov     eax, [.color]
;        bswap   eax
;        ror     eax, 8
;        invoke  SetTextColor, [ebx+TContext.handle], eax
;        invoke  TextOutW, [ebx+TContext.handle], [.x], [.y], [.pwc], [.charlen]
;
;        invoke  SelectObject, [ebx+TContext.handle] ; old font from the stack.
;
;        cmp     [.pwl], $100
;        jbe     @f
;        stdcall FreeMem, [.pwc]
;@@:
;        stdcall ReleaseContext, ebx
;
;        pop     edx ecx ebx eax
;        return
;endp

Changes to freshlib/graphics/Win32/text.asm.
10
11
12
13
14
15
16
17
18
19
20
21






































































































22
23

24


25
26
27
28
29
30
















31
32



33



34
35
36



37
38
39


40

41

42

43
44



45
46
47

48
49
50
51


52


53
54




55

56
57
58
59
60










61





62


63


64
65
66
67
68








69
70
71
72
73

74



75
76
77
78







79
80
81
82
83
84
85
86
87










88


89



90

91
92




93

94
95

96
97
98
99


100
101
102
103
104


105
106
107

108
109
110
111
112
113
114


115
116
117
118
119
120
121



122
123

124
125

126
127
128

129
130
131
132
133
134
135
136
137
138
139




140
141

142

143



144




















145
146
147
148











149




150
151











































152
153
154

155
156
157
158


159
160
161




162
163

164
165
166


167
168
169


170
171

172
173
174
175
176
177





178
179

180
181
182
183
184


185
186
187
188
189


190
191
192
193




194
195
196



197
198

199
200
201




202
203
204
205
206










207
208



209
210
211
212
213





214
215
216
217
218
219






220
221

222
223
224


225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245

246
247

248
249
250
251
252



253
254
255
256
257
258
259

260
261
262
263

264
265
266
267
268
269
270

271
272
273
274
275



276
277
278
279
280
281
282
10
11
12
13
14
15
16





17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123






124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147



148
149
150
151


152
153
154
155

156
157
158


159
160
161
162


163
164



165
166
167
168
169


170
171
172
173
174
175





176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

192
193
194
195
196





197
198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214



215
216
217
218
219
220
221
222
223
224






225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241
242


243
244
245
246
247
248
249

250
251
252


253
254


255


256
257
258


259
260
261





262
263

264





265
266
267
268

269
270

271

272

273
274
275
276
277
278
279
280




281
282
283
284


285
286
287

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311




312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327


328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371


372

373


374
375
376


377
378
379
380
381

382
383


384
385
386


387
388
389

390






391
392
393
394
395
396

397


398


399
400

401



402
403
404



405
406
407
408
409


410
411
412


413



414
415
416
417
418




419
420
421
422
423
424
425
426
427
428
429

430
431
432
433




434
435
436
437
438
439





440
441
442
443
444
445
446

447



448
449
450














451
452
453
454
455
456
457
458

459
460
461
462
463
464
465
466
467
468
469
470
471
472
473

474
475
476


477







478
479
480
481


482
483
484
485
486
487
488
489
490
491







-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+

+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+
+
+

+
+
+
-
-
-
+
+
+

-
-
+
+

+
-
+

+
-
-
+
+
+

-
-
+

-
-
-
+
+

+
+
-
-
+
+
+
+

+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
-
+
+

+
+
-
-
-
-
-
+
+
+
+
+
+
+
+





+
-
+
+
+

-
-
-
+
+
+
+
+
+
+



-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

+
+
-
+
+
+

+
-
-
+
+
+
+

+

-
+


-
-
+
+
-
-

-
-
+
+

-
-
+


-
-
-
-
-
+
+
-

-
-
-
-
-
+
+
+

-
+

-
+
-

-
+







-
-
-
-
+
+
+
+
-
-
+

+
-
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
+
-

-
-
+
+

-
-
+
+
+
+

-
+

-
-
+
+

-
-
+
+

-
+
-
-
-
-
-
-
+
+
+
+
+

-
+
-
-

-
-
+
+
-

-
-
-
+
+

-
-
-
+
+
+
+

-
-
+
+
+
-
-
+
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
+
+
+

-
-
-
-
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+
+

-
+
-
-
-
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-






+

-
+





+
+
+






-
+


-
-
+
-
-
-
-
-
-
-
+



-
-
+
+
+







;  Dependencies: memory.asm
;
;  Notes:
;_________________________________________________________________________________________



proc DrawString, .context, .ptrString, .len, .x, .y, .font, .color
.pwc dd ?
.pwl dd ?
.buffer  rb 256
.charlen dd ?

body DrawDecomposedString      ;, .pImage, .pArray, .x, .y, .font, .color

.startX  dd ?

.old_font    dd ?
.old_bmp     dd ?

.img    dd ?

begin
        pushad

        mov     eax, [.x]
        mov     [.startX], eax

        stdcall GetFontMetrics, [.font]
        sub     [.y], ebx

        mov     ebx, [.pImage]
        stdcall CreateImage, 100, 100
        mov     [.img], eax

        invoke  CreateCompatibleDC, 0
        mov     ebx, eax

        mov     eax, [.img]
        invoke  SelectObject, ebx, [eax+TImage.hBitmap]
        mov     [.old_bmp], eax

        invoke  SelectObject, ebx, [.font]
        mov     [.old_font], eax

        invoke  SetBkMode, ebx, TRANSPARENT
        invoke  SelectClipRgn, ebx, 0
        invoke  SetTextColor, ebx, $ffffff
        invoke  SetTextAlign, ebx, TA_TOP or TA_LEFT

        mov     esi, [.pArray]
        xor     edi, edi
        dec     edi

.char_loop:
        inc     edi
        cmp     edi, [esi+TArray.count]
        jae     .finish

        cmp     word [esi+TArray.array+8*edi+TTextChar.width], 0
        je      .char_ok

        movzx   ecx, word [esi+TArray.array+8*edi+TTextChar.width]
        stdcall DrawSolidRect, [.img], 0, 0, ecx, [esi+TArray.lparam], 0

        lea     eax, [esi+TArray.array+8*edi+TTextChar.code]
        movzx   ecx, word [esi+TArray.array+8*edi+TTextChar.width]
        invoke  ExtTextOutW, ebx, 0, 0, 0, 0, eax, 1, 0

        movzx   ecx, word [esi+TArray.array+8*edi+TTextChar.width]
        stdcall __BlendAlphaMask, [.pImage], [.x], [.y], [.img], 0, 0, ecx, [esi+TArray.lparam], [.color]

        movzx   eax, word [esi+TArray.array+8*edi+TTextChar.width]
        add     [.x], eax

.char_ok:
; check for new line.
        movzx   eax, word [esi+TArray.array+8*edi+TTextChar.height]
        test    eax, eax
        jz      .char_loop

        add     [.y], eax
        mov     eax, [.startX]
        mov     [.x], eax
        jmp     .char_loop


.finish:
        invoke  SelectObject, ebx, [.old_font]
        invoke  SelectObject, ebx, [.old_bmp]
        invoke  DeleteDC, ebx

        stdcall DestroyImage, [.img]

        popad
        return
endp




body TextDecompose      ;, .hString, .font

  .miny    dd ?
  .maxy    dd ?

  .more    dd ?
  .string  rd 2
  .code    dd ?

  .size SIZE

  .old_font dd ?

begin
        push    eax ebx ecx edx
        pushad

        invoke  CreateCompatibleDC, 0
        mov     ebx, eax
; first convert the string:
        lea     eax, [.buffer]
        mov     ecx, [.len]
        shl     ecx, 3
        cmp     ecx, $100
        jbe     @f

        invoke  SelectClipRgn, ebx, 0
        invoke  SelectObject, ebx, [.font]
        mov     [.old_font], eax

        xor     ecx, ecx

        mov     [.string], ecx
        mov     [.string+4], ecx

        inc     ecx

        ror     ecx, 1                  ; ecx = $80000000
        mov     [.maxy], ecx
        dec     ecx
        mov     [.miny], ecx            ; ecx = $7fffffff

        stdcall GetMem, ecx

        mov     word [.string], '|'
        mov     word [.string+2], '|'

        lea     ecx, [.string]
        lea     eax, [.size]
        invoke  GetTextExtentPoint32W, ebx, ecx, 1, eax
@@:
        mov     [.pwl], ecx
        mov     [.pwc], eax

        mov     eax, [.size.cx]
        mov     [.more], eax

        invoke  MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.len], [.pwc], ecx
        mov     [.charlen], eax
        stdcall StrPtr, [.hString]
        mov     esi, eax

        stdcall CreateArray, sizeof.TTextChar
        mov     ebx, [.context]
        mov     edi, eax

.char_loop:
        cmp     [.font], 0
        jne     @f

        stdcall DecodeUtf8, [esi]
        jc      .finish

        invoke  GetStockObject, DEFAULT_GUI_FONT
        mov     [.font], eax
        add     esi, edx

@@:
        invoke  SelectObject, [ebx+TContext.handle], [.font]
        push    eax
        test    eax, eax
        jz      .end

        mov     [.code], eax
        mov     word [.string], ax
        invoke  SetBkMode, [ebx+TContext.handle], TRANSPARENT
        invoke  SetTextAlign, [ebx+TContext.handle], TA_NOUPDATECP or TA_LEFT or TA_BASELINE

        lea     ecx, [.string]
        lea     eax, [.size]
        invoke  GetTextExtentPoint32W, ebx, ecx, 2, eax

        stdcall AddArrayItems, edi, 1
        mov     eax, [.color]
        bswap   eax
        ror     eax, 8
        invoke  SetTextColor, [ebx+TContext.handle], eax
        invoke  TextOutW, [ebx+TContext.handle], [.x], [.y], [.pwc], [.charlen]
        mov     edi, edx

        mov     ecx, [.size.cx]
        sub     ecx, [.more]

        mov     dword [eax+TTextChar.width], ecx
        mov     ecx, [.code]
        mov     [eax+TTextChar.code],  ecx

        jmp     .char_loop

.end:
        clc

.finish:
        pushf
        invoke  SelectObject, [ebx+TContext.handle] ; old font from the stack.
        invoke  SelectObject, ebx, [.old_font] ; old font from the stack.
        invoke  DeleteDC, ebx

        stdcall GetFontMetrics, [.font]
        popf
        cmp     [.pwl], $100
        jbe     @f
        stdcall FreeMem, [.pwc]
@@:
        pop     edx ecx ebx eax

        mov     [esp+4*regEDX], ebx             ; font ascent
        mov     [esp+4*regECX], edx             ; font descent
        mov     [edi+TArray.lparam], eax        ; line height

        mov     [esp+4*regEAX], edi

        popad
        return
endp




proc DrawStringOpaque, .context, .ptrString, .len, .x, .y, .font, .color, .background
;interface DrawString, .pImage, .pString, .len, .x, .y, .font, .color

body DrawString ;, .pImage, .pString, .len, .x, .y, .font, .color
.pwc dd ?
.pwl dd ?
.buffer  rb 256
.charlen dd ?
.charlen dd ?

.img  dd ?
.size SIZE

.tm TEXTMETRIC

begin
        push    eax ebx ecx edx

; first convert the string:
        lea     eax, [.buffer]
        mov     ecx, [.len]
        shl     ecx, 2
        cmp     ecx, $100
        jbe     @f
        invoke  CreateCompatibleDC, 0
        mov     ebx, eax

        invoke  SelectObject, ebx, [.font]
        push    eax

        invoke  SetBkMode,    ebx, TRANSPARENT
        invoke  SetTextAlign, ebx, TA_TOP or TA_LEFT
        invoke  SelectClipRgn, ebx, 0
        invoke  SetTextColor, ebx, $ffffff

        lea     eax, [.tm]
        invoke  GetTextMetricsW, ebx, eax
        stdcall GetMem, ecx

        mov     eax, [.tm.tmAscent]
        sub     [.y], eax

; convert the string:
@@:
        mov     [.pwl], ecx

        mov     ecx, [.len]
        shl     ecx, 2
        stdcall GetMem, ecx
        mov     [.pwc], eax
        shr     ecx, 1

        invoke  MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.len], [.pwc], ecx
        invoke  MultiByteToWideChar, CP_UTF8, 0, [.pString], [.len], [.pwc], ecx
        mov     [.charlen], eax

        mov     ebx, [.context]

        lea     eax, [.size]
        invoke  GetTextExtentPoint32W, ebx, [.pwc], [.charlen], eax
        cmp     [.font], 0
        jne     @f

        invoke  GetStockObject, DEFAULT_GUI_FONT
        mov     [.font], eax
        stdcall CreateImage, [.size.cx], [.size.cy]
        mov     [.img], eax

@@:
        invoke  SelectObject, [ebx+TContext.handle], [.font]
        invoke  SelectObject, ebx, [eax+TImage.hBitmap]
        push    eax

        invoke  SetBkMode, [ebx+TContext.handle], OPAQUE
        mov     eax, [.background]
        bswap   eax
        ror     eax, 8
        invoke  SetBkColor, [ebx+TContext.handle], eax
        xor     eax, eax
        invoke  ExtTextOutW, ebx, eax, eax, eax, eax, [.pwc], [.charlen], eax
        invoke  SetTextAlign, [ebx+TContext.handle], TA_NOUPDATECP or TA_LEFT or TA_BASELINE

        mov     eax, [.color]
        bswap   eax
        ror     eax, 8
        invoke  SetTextColor, [ebx+TContext.handle], eax
        invoke  TextOut, [ebx+TContext.handle], [.x], [.y], [.pwc], [.charlen]
        invoke  SelectObject, ebx ; old bitmap from the stack.
        invoke  SelectObject, ebx ; old font from the stack.
        invoke  DeleteDC, ebx

        invoke  SelectObject, [ebx+TContext.handle] ; old font from the stack.
        stdcall __BlendAlphaMask, [.pImage], [.x], [.y], [.img], 0, 0, [.size.cx], [.size.cy], [.color]

        cmp     [.pwl], $100
        stdcall DestroyImage, [.img]
        jbe     @f
        stdcall FreeMem, [.pwc]
@@:

        pop     edx ecx ebx eax
        return
endp




proc DrawColoredString, .context, .ptrString, .pCharAttr, .str_len_bytes, .x, .y, .char_offs, .fontwidth, .fontheight
.xbeg    dd ?
;.wbeg    dd ?
.pwc     dd ?

proc __BlendAlphaMask, .pDstImage, .xDst, .yDst, .pSrcImage, .xSrc, .ySrc, .width, .height, .color
.srect RECT
.drect RECT
.charlen dd ?
.point   POINT
.rect  RECT
begin
        pushad
        push    eax ebx ecx edx esi edi

        stdcall __fix_color, [.color], regEAX
        mov     [.color], eax

        mov     esi, [.pSrcImage]
        mov     edi, [.pDstImage]

        xor     eax, eax
        mov     ecx, [esi+TImage.width]
        mov     edx, [esi+TImage.height]

        mov     [.srect.left], eax
        mov     [.srect.top], eax
        mov     [.srect.right], ecx
        mov     [.srect.bottom], edx

        mov     ecx, [edi+TImage.width]
        mov     edx, [edi+TImage.height]

        mov     [.drect.left], eax
        mov     [.drect.top], eax
        mov     [.drect.right], ecx
        mov     [.drect.bottom], edx

        mov     eax, [.x]
;        mov     ecx, [.width]
        mov     [.xbeg], eax
;        mov     [.wbeg], ecx
        mov     ecx, [.xSrc]
        mov     edx, [.ySrc]

        mov     [.rect.left], ecx
        mov     [.rect.top], edx

        add     ecx, [.width]
        add     edx, [.height]

        mov     [.rect.right], ecx
        mov     [.rect.bottom], edx

        lea     ecx, [.srect]
        lea     edx, [.rect]
        stdcall RectIntersect, ecx, ecx, edx
        jc      .finish
; first convert the string:
        mov     ecx, [.str_len_bytes]

        mov     ecx, [.xSrc]
        mov     edx, [.ySrc]
        sub     ecx, [.xDst]
        sub     edx, [.yDst]

; convert the rect to the destination coordinates.
        sub     [.srect.left], ecx
        sub     [.srect.top], edx
        sub     [.srect.right], ecx
        sub     [.srect.bottom], edx

        lea     eax, [.srect]
        lea     ebx, [.drect]
        stdcall RectIntersect, ebx, ebx, eax
        jc      .finish

        stdcall RectCopy, eax, ebx      ; srect = drect

;convert back to source coordinates.
        add     [.srect.left], ecx
        add     [.srect.top], edx
        add     [.srect.right], ecx
        add     [.srect.bottom], edx

; here [.srect] contains the source rectange
; [.drect] contains the destination rectangle
; the width and height of the rectangles  is the same.

        mov     ecx, [.srect.left]
        mov     edx, [.srect.top]
        sub     [.srect.right], ecx
        sub     [.srect.bottom], edx

        mov     ecx, [.srect.top]
        mov     edx, [.drect.top]

        imul    ecx, [esi+TImage.width]
        imul    edx, [edi+TImage.width]

        add     ecx, [.srect.left]
        add     edx, [.drect.left]

        shl     ecx, 2
        stdcall GetMem, ecx
        mov     esi, eax
        shl     edx, 2
        mov     [.pwc], eax

        invoke  MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.str_len_bytes], esi, ecx
        mov     [.charlen], eax
        add     ecx, [esi+TImage.pPixels]
        add     edx, [edi+TImage.pPixels]

        mov     ebx, [.context]
        mov     edi, [.pCharAttr]
        mov     esi, [esi+TImage.width]
        mov     edi, [edi+TImage.width]
        lea     esi, [4*esi]
        lea     edi, [4*edi]

        invoke  SaveDC, [ebx+TContext.handle]
; prepare MMX constants

        invoke  SetBkMode,    [ebx+TContext.handle], TRANSPARENT
        invoke  SetTextAlign, [ebx+TContext.handle], TA_LEFT or TA_BASELINE
        pxor    mm0, mm0        ; mm0 = 0000 0000 0000 0000
        pcmpeqw mm1, mm1        ; mm1 = ffff ffff ffff ffff

.skip_offset:
        mov     ecx, [.char_offs]
        psrlw   mm1, 15         ; mm1 = 0001 0001 0001 0001
        psllw   mm1, 8          ; mm1 = 0100 0100 0100 0100

.offsloop:
.loopY:
        jecxz   .loop

        lodsw
        add     edi, sizeof.TCharAttr
        dec     [.charlen]
        jz      .endline
        mov     ebx, [.srect.right]     ; the width of the source rectangle

.loopX:
        dec     ebx                     ; The ZF will not be changed later in the inner loop.
        js      .nextY

        dec     ecx
        push    edx
        cmp     eax, $01
        jne     .offsloop

        mov     eax, [.fontheight]
        add     [.y], eax
        movzx   eax, byte [ecx+4*ebx]
        movzx   edx, byte [ecx+4*ebx+1]
        jmp     .skip_offset

.loop:
        cmp     word [esi], $01
        je      .wrapline
        lea     eax, [eax+2*edx]
        movzx   edx, byte [ecx+4*ebx+2]

        mov     eax, [edi+TCharAttr.font]
        test    eax, eax
        jnz     @f
        add     eax, edx
        shr     eax, 2          ; grayscale.

        pop     edx

        invoke  GetStockObject, DEFAULT_GUI_FONT
@@:
        movd      mm6, [.color]
        movd      mm7, eax

        invoke  SelectObject, [ebx+TContext.handle], eax
        mov     eax, [edi+TCharAttr.background]
        punpcklbw mm6, mm0              ; byte to word color.
        bswap   eax
        ror     eax, 8
        invoke  SetBkColor, [ebx+TContext.handle], $ff0000
        punpckldq mm7, mm7              ;
        packssdw  mm7, mm7              ; mm7 = I, I, I, I

        pmullw    mm7, mm6              ; mm7 is the color to blend = Cs*256

        mov     eax, [edi+TCharAttr.color]
        bswap   eax
        ror     eax, 8
        invoke  SetTextColor, [ebx+TContext.handle], eax
        movd      mm6, [edx+4*ebx]      ; Destination color
        punpcklbw mm6, mm0              ; byte to word destination pixel

        movq      mm5, mm7
        psrlq     mm5, 56               ; alpha source
        punpckldq mm5, mm5
        packssdw  mm5, mm5              ; mm5 = As, As, As, As

        movq    mm4, mm1
        psubw   mm4, mm5                ; mm4 = Bs Bs Bs Bs     (Bs = $100 - As)

        invoke  TextOutW, [ebx+TContext.handle], [.x], [.y], esi, 1
        pmullw  mm6, mm4                ; mm6 = Cd = Cd * (256-As) = Cd * Bs
        paddusw mm6, mm7                ; Cd = 256*Cs + Cd*(256-As)
        psrlw   mm6, 8                  ; Cd = Cd/256

        mov     eax, [.fontwidth]
        add     [.x], eax
;        sub     [.width], eax
;        jl      .endline
        packuswb mm6, mm0               ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
        movd     [edx+4*ebx], mm6

        jmp     .loopX


.nextchar:
        add     esi, 2
        add     edi, sizeof.TCharAttr
        dec     [.charlen]
        jnz     .loop
.nextY:
        add     ecx, esi
        add     edx, edi

        dec     [.srect.bottom]
        jnz     .loopY

.endline:
.finish:
        invoke  RestoreDC, [ebx+TContext.handle], -1
        stdcall FreeMem, [.pwc]
        pop     edi esi edx ecx ebx eax
        emms
        popad
        return

.wrapline:
        mov     eax, [.fontheight]
        add     [.y], eax
        mov     eax, [.xbeg]
;        mov     ecx, [.wbeg]
        mov     [.x], eax
;        mov     [.width], ecx

        add     esi, 2
        add     edi, sizeof.TCharAttr
        dec     [.charlen]
        jnz     .skip_offset
        jmp     .endline
endp





;interface GetTextBounds, .pString, .len, .font

proc GetTextBounds, .context, .ptrString, .len, .font
body GetTextBounds      ;, .pString, .len, .font
.size SIZE
.pwc dd ?
.charlen dd ?
begin
        push    ebx ecx

        invoke  CreateCompatibleDC, 0
        mov     ebx, eax

; first convert the string:
        mov     ecx, [.len]
        shl     ecx, 3
        stdcall GetMem, ecx
        mov     [.pwc], eax
        invoke  MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.len], [.pwc], ecx
        invoke  MultiByteToWideChar, CP_UTF8, 0, [.pString], [.len], [.pwc], ecx
        mov     [.charlen], eax

        mov     ebx, [.context]

        invoke  SelectClipRgn, ebx, 0
        cmp     [.font], 0
        jne     @f
        invoke  GetStockObject, DEFAULT_GUI_FONT
        mov     [.font], eax

@@:
        invoke  SelectObject, [ebx+TContext.handle], [.font]
        invoke  SelectObject, ebx, [.font]
        push    eax

        lea     eax, [.size]
        invoke  GetTextExtentPoint32W, [ebx+TContext.handle], [.pwc], [.charlen], eax
        invoke  SelectObject, [ebx+TContext.handle] ; from the stack.
        invoke  GetTextExtentPoint32W, ebx, [.pwc], [.charlen], eax
        invoke  SelectObject, ebx ; from the stack.
        invoke  DeleteDC, ebx

        mov     eax, [.size.cx]
        mov     edx, [.size.cy]

        stdcall FreeMem, [.pwc]
        pop     ecx ebx
        return
Changes to freshlib/graphics/all.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14

15
16
17
18
19













-

-





; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Graphics amalgamation include file.
;               Includes all graphic libraries of FreshLib
;
;  Target OS: Any
;_________________________________________________________________________________________


include 'rectangles.asm'
include 'context.asm'
include 'images.asm'
include 'backbuffer.asm'
include 'draw.asm'
include 'giflib.asm'
include 'pnglib.asm'
include 'fonts.asm'
include 'text.asm'
Deleted freshlib/graphics/backbuffer.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27



























-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Provides raster bitmap, to be used for double buffer painting.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________
module "BackBuffer library"

; should be equal to the first 3 members of TImage in order to use the same draw procedure.

struct TBackBuffer
  .width  dd ?
  .height dd ?
  .raster dd ?
ends


include '%TargetOS%/backbuffer.asm'

endmodule
Deleted freshlib/graphics/context.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110














































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Context is a object that represents drawing surface in FreshLib
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: This file contains OS independent part and includes OS dependent files.
;_________________________________________________________________________________________
module "Graphic context library"

struct TBounds
  .x      dd ?
  .y      dd ?
  .width  dd ?
  .height dd ?
ends



struct TContext
  .raster     dd ?          ; handle to raster object (depends on TargetOS)
  .handle     dd ?          ; handle to context object (depends on TargetOS)
  .clipregion dd ?          ; clipping region.
  .drawmode   dd ?
ends


struct TDashListItem
  .dash  dd ?
  .space dd ?
ends


struct TLineStyle
  .width dd ?                   ; width of the line in pixels. Width 0 is 1px width. It have special meaning in Linux for example.
  .color dd ?                   ; color of the line in format (from LSB to MSB) bb, gg, rr, aa ; Use of alpha value is something not very clear for all implementations...
  .flags dd ?                   ; set of lsEndCapXXX; lsJoinXXX
  .clSpace dd ?                 ; space color.
  .DashCount dd ?               ; count of dash items in the dash list. For solid lines DashCount=0
  .DashItems:                   ; arbitrary count of TDashListItem
ends


; Creates static TLineStyle structure in design time.

struc LineStyle width*, color*, flags, spacecolor, [dash, space] {
common
local ..count, ..dashcount
  ..count = 0

common
  dd width
  dd color
  if flags eq
    dd lsEndCapRound or lsJoinRound
  else
    dd flags
  end if

  if spacecolor eq
    dd 0
  else
    dd spacecolor
  end if

  dd ..dashcount

forward
  if ~dash eq
    db dash, space
    ..count = ..count + 2
  end if

common
  ..dashcount = ..count
}



proc SetSimpleLine, .context, .color
.style TLineStyle
       rd 16
begin
        push    eax

        lea     eax, [.style]
        mov     [eax+TLineStyle.width], 0
        mov     [eax+TLineStyle.flags], 0
        mov     [eax+TLineStyle.DashCount], 0
        mov     [eax+TLineStyle.clSpace],0

        push    [.color]
        pop     [eax+TLineStyle.color]


        stdcall SetLineStyle, [.context], eax
        pop     eax
        return
endp



include '%TargetOS%/context.asm'

endmodule
Changes to freshlib/graphics/draw.asm.
10
11
12
13
14
15
16
17
























































































































































































































































































































































18
19
20



21
22

23
24

25
26
27
28
29
30







31

32


33
34
35
36
37















38












39
























40
41
42
43
44
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362

363
364
365
366

367
368

369
370





371
372
373
374
375
376
377
378
379
380
381
382





383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439







-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
+
+
+

-
+

-
+

-
-
-
-
-
+
+
+
+
+
+
+

+

+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





;  Dependencies:
;
;  Notes: This file contains OS independent part and includes OS dependent files.
;_________________________________________________________________________________________
module "Draw library"


include "%TargetOS%/draw.asm"
;include "%TargetOS%/draw.asm"



proc DrawSolidRect, .pDstImage, .x, .y, .width, .height, .color
.drect RECT
.rect  RECT
begin
        pushad

        mov     esi, [.pDstImage]

        xor     eax, eax
        mov     ecx, [esi+TImage.width]
        mov     edx, [esi+TImage.height]

        mov     [.drect.left], eax
        mov     [.drect.top], eax
        mov     [.drect.right], ecx
        mov     [.drect.bottom], edx

        mov     ecx, [.x]
        mov     edx, [.y]

        mov     [.rect.left], ecx
        mov     [.rect.top], edx

        add     ecx, [.width]
        add     edx, [.height]

        mov     [.rect.right], ecx
        mov     [.rect.bottom], edx

        lea     ecx, [.drect]
        lea     edx, [.rect]
        stdcall RectIntersect, ecx, ecx, edx
        jc      .finish

; here [.srect] contains the source rectange
; [.drect] contains the destination rectangle
; the width and height of the rectangles  is the same.

        mov     ecx, [.drect.right]
        mov     edx, [.drect.bottom]
        sub     ecx, [.drect.left]
        sub     edx, [.drect.top]

        mov     edi, [.drect.top]
        imul    edi, [esi+TImage.width]
        add     edi, [.drect.left]
        lea     edi, [edi*4]
        add     edi, [esi+TImage.pPixels]

        mov     esi, [esi+TImage.width]
        lea     esi, [4*esi]

        stdcall __fix_color, [.color], regEAX

.loopY:

        mov     ebx, ecx     ; the width of the source rectangle

.loopX:
        dec     ebx
        mov     [edi+4*ebx], eax        ; fill the color
        jnz     .loopX

        add     edi, esi
        dec     edx
        jnz     .loopY


.finish:
        popad
        return
endp





proc BlendSolidRect, .pDstImage, .x, .y, .width, .height, .color
.drect RECT
.rect  RECT
begin
        pushad

        mov     esi, [.pDstImage]

        xor     eax, eax
        mov     ecx, [esi+TImage.width]
        mov     edx, [esi+TImage.height]

        mov     [.drect.left], eax
        mov     [.drect.top], eax
        mov     [.drect.right], ecx
        mov     [.drect.bottom], edx

        mov     ecx, [.x]
        mov     edx, [.y]

        mov     [.rect.left], ecx
        mov     [.rect.top], edx

        add     ecx, [.width]
        add     edx, [.height]

        mov     [.rect.right], ecx
        mov     [.rect.bottom], edx

        lea     ecx, [.drect]
        lea     edx, [.rect]
        stdcall RectIntersect, ecx, ecx, edx
        jc      .finish

; here [.srect] contains the source rectange
; [.drect] contains the destination rectangle
; the width and height of the rectangles  is the same.

        mov     ecx, [.drect.right]
        mov     edx, [.drect.bottom]
        sub     ecx, [.drect.left]
        sub     edx, [.drect.top]

        mov     edi, [.drect.top]
        imul    edi, [esi+TImage.width]
        add     edi, [.drect.left]
        lea     edi, [edi*4]
        add     edi, [esi+TImage.pPixels]

        mov     esi, [esi+TImage.width]
        lea     esi, [4*esi]

        stdcall __fix_color, [.color], regEAX

; prepare MMX constants

        pxor    mm0, mm0        ; mm0 = 0000 0000 0000 0000
        pcmpeqw mm1, mm1                                        ; mm1 = ffff ffff ffff ffff
        psrlw   mm1, 8                                         ; mm1 = 00ff 00ff 00ff 00ff

; the color
        movd    mm7, eax

        movq    mm5, mm7
        psrlq   mm5, 24                 ; alpha source
        punpckldq mm5, mm5
        packssdw  mm5, mm5              ; mm5 = As, As, As, As

        movq    mm4, mm1
        psubw   mm4, mm5                ; mm4 = Bs Bs Bs Bs     (Bs = $100 - As)

        punpcklbw mm7, mm0              ; byte to word source pixel
        psllw     mm7, 8                ; Cs = Cs*256


.loopY:
        mov     ebx, ecx        ; the width of the source rectangle

.loopX:
        dec     ebx                     ; The ZF will not be changed later in the inner loop.

        movd    mm6, [edi+4*ebx]        ; destination pixel.
        punpcklbw mm6, mm0              ; byte to word destination pixel
        pmullw  mm6, mm4                ; mm6 = Cd = Cd * (256-As) = Cd * Bs   (For alpha Ad = Ad*Bs)
        paddusw mm6, mm7                ; Cd = Cs + Cd
        psrlw   mm6, 8                  ; Cd = Cd/256

        packuswb mm6, mm0               ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
        movd     [edi+4*ebx], mm6

        jnz     .loopX

.nextY:
        add     edi, esi
        dec     edx
        jnz     .loopY


.finish:
        popad
        return
endp







proc __fix_color, .color, .reg
begin
        pushad

        movzx   ebx, byte [.color+3]    ; alpha
        mov     ecx, ebx

        mov     esi, $ff

        movzx   eax, byte [.color+2]    ; red
        mul     ebx
        div     esi

        shl     ecx, 8
        mov     cl, al

        movzx   eax, byte [.color+1]    ; green
        mul     ebx
        div     esi

        shl     ecx, 8
        mov     cl, al

        movzx   eax, byte [.color]      ; blue
        mul     ebx
        div     esi

        shl     ecx, 8
        mov     cl, al

        mov     eax, [.reg]
        lea     eax, [esp+4*eax]

        mov     [eax], ecx
        popad
        return
endp



; Draws horizontal line from .x1 to .x2 on y with color [.color]
;
;

proc DrawHLine, .pImage, .x1, .x2, .y, .color
begin






        return
endp






proc DrawVLine, .pImage, .y1, .y2, .x, .color
begin


        return
endp






proc ApplyAlphaRect, .pImage, .x, .y, .width, .height, .alpha
.drect RECT
.rect  RECT
begin
        pushad

        mov     edi, [.pImage]

        xor     eax, eax
        mov     ecx, [edi+TImage.width]
        mov     edx, [edi+TImage.height]

        mov     [.drect.left], eax
        mov     [.drect.top], eax
        mov     [.drect.right], ecx
        mov     [.drect.bottom], edx

        mov     ecx, [.x]
        mov     edx, [.y]

        mov     [.rect.left], ecx
        mov     [.rect.top], edx

        add     ecx, [.width]
        add     edx, [.height]

        mov     [.rect.right], ecx
        mov     [.rect.bottom], edx

        lea     ecx, [.drect]
        lea     edx, [.rect]
        stdcall RectIntersect, ecx, ecx, edx
        jc      .finish

; here [.drect] contains the destination rectangle

        mov     ecx, [.drect.left]
        mov     edx, [.drect.top]
        sub     [.drect.right], ecx
        sub     [.drect.bottom], edx

        imul    edx, [edi+TImage.width]
        add     edx, [.drect.left]
        shl     edx, 2

        add     edx, [edi+TImage.pPixels]       ; pointer to the upper left corner of the rect.

        mov     edi, [edi+TImage.width]
        lea     edi, [4*edi]


.loopY:
        mov     ebx, [.drect.right]     ; the width of the source rectangle

.loopX:
        dec     ebx                     ; The ZF will not be changed later in the inner loop.
        js      .nextY


        movzx   eax, byte [edx+4*ebx+3]         ; dest alpha.
        movzx   ecx, byte [.alpha]

; Ad = Ad * [.alpha]/256

        imul    eax, ecx
        sar     eax, 8

        mov     [edx+4*ebx+3], al
        jmp     .loopX

.nextY:
        add     edx, edi
        dec     [.drect.bottom]
        jnz     .loopY


.finish:
        popad
        return
endp




proc DrawRectangle, .context, .pBounds, .color
proc FilterDisabled, .pImage, .no_alpha
.gray dd ?
.alpha dd ?
begin
        push    eax ecx edx
        pushad

        mov     edx, [.pBounds]
        mov     edi, [.pImage]

        mov     eax, [edx+TBounds.x]
        mov     ecx, [edx+TBounds.y]
        add     eax, [edx+TBounds.width]
        add     ecx, [edx+TBounds.height]
        dec     eax
        mov     ebx, [edi+TImage.width]
        mov     ecx, [edi+TImage.height]

        mov     edi, [edi+TImage.pPixels]


.outloop:
        dec     ecx
        js      .finish

        mov     esi, ebx      ; Counter from 0 to IconWidth-1
        inc     esi
        stdcall SetSimpleLine, [.context], [.color]
        stdcall DrawLine, [.context], [edx+TBounds.x], [edx+TBounds.y], eax, [edx+TBounds.y]
        stdcall DrawLine, [.context], eax, [edx+TBounds.y], eax, ecx
        stdcall DrawLine, [.context], [edx+TBounds.x], ecx, eax, ecx
        stdcall DrawLine, [.context], [edx+TBounds.x], [edx+TBounds.y], [edx+TBounds.x], ecx

.inloop:
        dec     esi
        jz      .outloop

        movzx   eax, byte [edi]         ; blue
        movzx   edx, byte [edi+1]       ; green

        lea     edx, [edx+2*eax]        ;  2*Blue + Green

        movzx   eax, byte [edi+2]
        add     edx, eax                ; + Red

        movzx   eax, byte [edi+3]       ; Alpha
        mov     [.alpha], eax

        shr     edx, 2          ; div 4 -> Grayscale pixel.
                                ; This formula gives more realistic view.

        mov     [.gray], edx

; blend alpha

        cmp     [.no_alpha], 0
        jne     .store

        imul    eax, esi
        cdq
        pop     edx ecx eax
        div     ebx
        mov     [.alpha], eax

        mov     eax, [.gray]
        imul    eax, esi
        cdq
        div     ebx
        mov     [.gray], eax

.store:

        mov     al, byte [.alpha]
        shl     eax, 8
        mov     al ,byte [.gray]
        shl     eax, 8
        mov     al ,byte [.gray]
        shl     eax, 8
        mov     al ,byte [.gray]

        stosd
        jmp     .inloop

.finish:
        popad
        return
endp


endmodule
Changes to freshlib/graphics/fonts.asm.
15
16
17
18
19
20
21





































22
23
24
25
26
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





module "Fonts library"

ffItalic    = 1
ffUnderline = 2
ffStrikeOut = 4

ffMonospaced = $80


fwLight     = 0
fwDemilight = 1
fwNormal    = 2
fwMedium    = 3
fwDemibold  = 4
fwBold      = 5
fwExtraBold = 6
fwBlack     = 7



struct __TFont
  .hFontFace      dd ?    ; The name of the font face.
  .height         dd ?    ; The character height in pixels.
  .weight         dd ?    ; The weight of the characters.
  .flags          dd ?    ; ffItalic, ffMonospaced, etc.
ends


interface FontCreate, .font_name, .size, .weight, .flags

interface FontDestroy, .pFont


; returns some font metrics
;
; Arguments:
;    .font - the font
; Returns:
;    EAX - the line height of the font.
;    EBX - the ascender of the font.
;    EDX - the descender of the font.

interface GetFontMetrics, .font



include '%TargetOS%/fonts.asm'

endmodule
Changes to freshlib/graphics/images.asm.
18
19
20
21
22
23
24
25
26
27


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
18
19
20
21
22
23
24



25
26















27
28
29
30
31
32
33







-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







; Creates memory image with parameters specified.
interface CreateImage, .width, .height


interface DestroyImage, .ptrImage


interface DrawImage, .context, .pImage, .x, .y


; Draws the image on a OS provided window surface.
interface DrawImageRect, .where, .pImage, .xDst, .yDst, .xSrc, .ySrc, .width, .height
interface DrawText, .pImage, .text, .len, .x, .y, .font, .color





proc DrawMaskedImage, .context, .mask, .image, .x, .y
begin
        stdcall SetDrawMode, [.context], cmAnd
        stdcall DrawImage, [.context], [.mask], [.x], [.y]
        stdcall SetDrawMode, [.context], cmXor
        stdcall DrawImage, [.context], [.image], [.x], [.y]
        return
endp




proc BlendImage, .pDstImage, .xDst, .yDst, .pSrcImage, .xSrc, .ySrc, .width, .height
.srect RECT
.drect RECT
.rect  RECT
140
141
142
143
144
145
146


147
148


149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173
174



175
176
177
178
179
180


181
182
183
184
185
186
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
124
125
126
127
128
129
130
131
132


133
134



135
136
137
138
139
140
141
142
143
144
145
146


147

148

149
150
151
152


153
154
155
156
157




158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181









































































182
183
184
185
186
187
188







+
+
-
-
+
+
-
-
-












-
-
+
-

-




-
-
+
+
+


-
-
-
-
+
+














+







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







        lea     esi, [4*esi]
        lea     edi, [4*edi]

; prepare MMX constants

        pxor    mm0, mm0        ; mm0 = 0000 0000 0000 0000
        pcmpeqw mm1, mm1                                        ; mm1 = ffff ffff ffff ffff
        psrlw   mm1, 8                                         ; mm1 = 00ff 00ff 00ff 00ff

        psrlw   mm1, 15                                         ; mm1 = 0001 0001 0001 0001
        psllw   mm1, 8          ; mm1 = 0100 0100 0100 0100
;        psrlw   mm1, 15                                         ; mm1 = 0001 0001 0001 0001
;        psllw   mm1, 8          ; mm1 = 0100 0100 0100 0100

        movq    mm2, mm1                                        ; mm2 = 0001 0001 0001 0001
        psllq   mm2, 48         ; mm2 = 0100 0000 0000 0000

.loopY:
        mov     ebx, [.srect.right]     ; the width of the source rectangle

.loopX:
        dec     ebx                     ; The ZF will not be changed later in the inner loop.

        movd    mm7, [ecx+4*ebx]        ; source pixel.
        movd    mm6, [edx+4*ebx]        ; destination pixel.

        movq    mm5, mm7
        psrlq   mm5, 24                 ; alpha source

        punpckldq mm5, mm5              ;
        punpckldq mm5, mm5
        punpcklbw mm6, mm0              ; byte to word destination pixel
        packssdw  mm5, mm5              ; mm5 = As, As, As, As
        punpcklbw mm7, mm0              ; byte to word source pixel

        movq    mm4, mm1
        psubw   mm4, mm5                ; mm4 = Bs Bs Bs Bs     (Bs = $100 - As)

        psrlq   mm5, 16                 ; mm5 = 0  As As As
        por     mm5, mm2                ; mm5 = $100 As As As
        punpcklbw mm6, mm0              ; byte to word destination pixel
        punpcklbw mm7, mm0              ; byte to word source pixel
        psllw     mm7, 8                ; Cs = Cs*256

        pmullw  mm6, mm4                ; mm6 = Cd = Cd * (256-As) = Cd * Bs   (For alpha Ad = Ad*Bs)
        pmullw  mm7, mm5                ; Cs = Cs * As                   (For alpha As = $100*As )

        paddusw mm6, mm7                ; Cd = Cs + Cd                   (For alpha Ad = $100*As + Ad*Bs)
        psrlw   mm6, 8                  ; Cd = Cd/256                    (For alpha Ad = As + Ad*Bs/$100)
        paddusw mm6, mm7                ; Cd = Cs + Cd
        psrlw   mm6, 8                  ; Cd = Cd/256

        packuswb mm6, mm0               ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
        movd     [edx+4*ebx], mm6

        jnz     .loopX

.nextY:
        add     ecx, esi
        add     edx, edi

        dec     [.srect.bottom]
        jnz     .loopY

.finish:
        emms
        popad
        return
endp




proc DrawSolidRect, .pDstImage, .x, .y, .width, .height, .color
.drect RECT
.rect  RECT
begin
        pushad

        mov     esi, [.pDstImage]

        xor     eax, eax
        mov     ecx, [esi+TImage.width]
        mov     edx, [esi+TImage.height]

        mov     [.drect.left], eax
        mov     [.drect.top], eax
        mov     [.drect.right], ecx
        mov     [.drect.bottom], edx

        mov     ecx, [.x]
        mov     edx, [.y]

        mov     [.rect.left], ecx
        mov     [.rect.top], edx

        add     ecx, [.width]
        add     edx, [.height]

        mov     [.rect.right], ecx
        mov     [.rect.bottom], edx

        lea     ecx, [.drect]
        lea     edx, [.rect]
        stdcall RectIntersect, ecx, ecx, edx
        jc      .finish

; here [.srect] contains the source rectange
; [.drect] contains the destination rectangle
; the width and height of the rectangles  is the same.

        mov     ecx, [.drect.right]
        mov     edx, [.drect.bottom]
        sub     ecx, [.drect.left]
        sub     edx, [.drect.top]

        mov     edi, [.drect.top]
        imul    edi, [esi+TImage.width]
        add     edi, [.drect.left]
        lea     edi, [edi*4]
        add     edi, [esi+TImage.pPixels]

        mov     esi, [esi+TImage.width]
        lea     esi, [4*esi]

        mov     eax, [.color]

.loopY:

        mov     ebx, ecx     ; the width of the source rectangle

.loopX:
        dec     ebx
        mov     [edi+4*ebx], eax        ; fill the color
        jnz     .loopX

        add     edi, esi
        dec     edx
        jnz     .loopY


.finish:
        popad
        return
endp



proc CopyImageRect, .pDstImage, .xDst, .yDst, .pSrcImage, .xSrc, .ySrc, .width, .height
.srect RECT
.drect RECT
.rect  RECT
begin
396
397
398
399
400
401
402

403
404
405
406
407
408





409






























































































410
411
412
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321

322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418







+






+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



        add     ecx, esi
        add     edx, edi

        dec     [.srect.bottom]
        jnz     .loopY

.finish:
        emms
        popad
        return
endp



;proc ImageMulAlpha2, .pImage, .x, .y, .width, .height
;.drect RECT
;.rect  RECT
;begin
;        pushad

;
;        mov     edi, [.pImage]
;
;        xor     eax, eax
;        mov     ecx, [edi+TImage.width]
;        mov     edx, [edi+TImage.height]
;
;        mov     [.drect.left], eax
;        mov     [.drect.top], eax
;        mov     [.drect.right], ecx
;        mov     [.drect.bottom], edx
;
;        mov     ecx, [.x]
;        mov     edx, [.y]
;
;        mov     [.rect.left], ecx
;        mov     [.rect.top], edx
;
;        add     ecx, [.width]
;        add     edx, [.height]
;
;        mov     [.rect.right], ecx
;        mov     [.rect.bottom], edx
;
;        lea     ecx, [.drect]
;        lea     edx, [.rect]
;        stdcall RectIntersect, ecx, ecx, edx
;        jc      .finish
;
;        mov     ecx, [.drect.left]
;        mov     edx, [.drect.top]
;        sub     [.drect.right], ecx
;        sub     [.drect.bottom], edx
;
;        mov     esi, [.drect.top]
;        imul    esi, [edi+TImage.width]
;
;        add     esi, [.drect.left]
;        lea     esi, [4*esi]
;        add     esi, [edi+TImage.pPixels]
;
;        mov     edi, [edi+TImage.width]
;        lea     edi, [4*edi]
;
;; prepare MMX constants
;
;        pxor    mm0, mm0        ; mm0 = 0000 0000 0000 0000
;        pcmpeqw mm1, mm1                                        ; mm1 = ffff ffff ffff ffff
;        psrlw   mm1, 15                                         ; mm1 = 0001 0001 0001 0001
;        psllw   mm1, 8          ; mm1 = 0100 0100 0100 0100
;        psllq   mm1, 48         ; mm1 = 0100 0000 0000 0000
;
;.loopY:
;        mov     ebx, [.drect.right]     ; the width of the source rectangle
;
;.loopX:
;        dec     ebx                     ; The ZF will not be changed later in the inner loop.
;
;        movd    mm6, [esi+4*ebx]        ; destination pixel.
;
;        movq    mm5, mm6
;        psrlq   mm5, 24                 ; alpha
;
;        punpckldq mm5, mm5              ;
;        punpcklbw mm6, mm0              ; byte to word destination pixel
;        packssdw  mm5, mm5              ; mm5 = Ad, Ad, Ad, Ad
;
;        psrlq   mm5, 16                 ; mm5 = 0  Ad Ad Ad
;        por     mm5, mm1                ; mm5 = $100 Ad Ad Ad
;
;        pmullw  mm6, mm5                ; mm6 = Cd = Cd * Ad   (For alpha Ad = Ad * 256)
;        psrlw   mm6, 8                  ; Cd = Cd/256          (For alpha Ad = Ad)
;
;        packuswb mm6, mm0               ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
;        movd     [esi+4*ebx], mm6
;
;        jnz     .loopX
;
;.nextY:
;        add     esi, edi
;
;        dec     [.drect.bottom]
;        jnz     .loopY
;
;.finish:
;        emms
;        popad
;        return
;endp





include '%TargetOS%/images.asm'

endmodule
Changes to freshlib/graphics/pnglib.asm.
566
567
568
569
570
571
572



573
574
575
576
577
578
579
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582







+
+
+








        rol     ebx, cl
        shl     ebx, 2
        add     ebx, [.pPalette]
        mov     edx, [ebx]

.store_px:

        stdcall __fix_color, edx, regEDX        ; pre-multiply alpha

        mov     [edi], edx
        add     edi, 4

        dec     [.j]
        jnz     .inner2

        movzx   eax, ch
Changes to freshlib/graphics/rectangles.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13











































































14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95













+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: TGrid object class
;
;  Target OS: Any
;
;  Dependencies:
;  Notes:
;_________________________________________________________________________________________
module "Rectangles library"


; Calculates the bounding rectangle of two source rectangles, pointed by [.src1] and [.src2]
; The result rectangle is placed in RECT structure pointed by [.dest]
;
; All three rectangles may point to the same structures.
;
; Procedure preserves all registers.

proc RectBounding, .dest, .src1, .src2
begin
        pushad


        mov     esi, [.src1]
        mov     edi, [.src2]
        mov     ebx, [.dest]

; min left1, left2

        mov     eax, [esi+RECT.left]
        mov     edx, [edi+RECT.left]

        sub     edx, eax
        sbb     ecx, ecx
        and     ecx, edx
        add     eax, ecx

        mov     [ebx+RECT.left], eax


; min top1, top2

        mov     eax, [esi+RECT.top]
        mov     edx, [edi+RECT.top]

        sub     edx, eax
        sbb     ecx, ecx
        and     ecx, edx
        add     eax, ecx

        mov     [ebx+RECT.top], eax


; max right1, right2

        mov     eax, [esi+RECT.right]
        mov     edx, [edi+RECT.right]

        sub     edx, eax
        sbb     ecx, ecx
        not     ecx
        and     ecx, edx
        add     eax, ecx

        mov     [ebx+RECT.right], eax


; max bottom1, bottom2

        mov     eax, [esi+RECT.bottom]
        mov     edx, [edi+RECT.bottom]

        sub     edx, eax
        sbb     ecx, ecx
        not     ecx
        and     ecx, edx
        add     eax, ecx

        mov     [ebx+RECT.bottom], eax

        popad
        return
endp



; Calculates the intersection of two source rectangles, pointed by [.src1] and [.src2]
; The result rectangle is placed in RECT structure pointed by [.dest]
; All three rectangles may point to the same structures.
;
; Returns CF=0 if rectangles intersect and CF=1 if not.
Changes to freshlib/graphics/text.asm.
10
11
12
13
14
15
16
17


18
19
20
21
22
23
24
25





26
27
28


29
30
31
32
33

34
35
36
37
38
39
40
41



42
43
44
45
46
47
48
49
50
51
52




53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91

92
93
94

95
96
97

98
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127






128

129
130



131
132
133



134
135
136

137
138
139

140
141
142
143
144




145
146
147
148
149
150


151
152
153



154
155
156


157
158
159

160
161



162
163
164
165
166



167
168
169




170
171

172
173
174
175
176
177

178
179
180
181
182
183
184









185
186

187
188
189

190
191
192
193
194
195




196
197
198

199
200
201


202
203
204
205
206






207

208
209


210
211
212





213
214
215



216
217
218



219

220

221

222
223




224

225
226
227



228
229
230

231
232
233
234


235

236
237


238
239
240
241
242
243
244







245


246
247
248
249
250
251
252
253
254
255
256

















257
258
259



260
261



262
263
264
265



266
267
268
269
270
271









272
273
274
275
276

277
278

279

280


281
282
283


284
285

286
287
288




289
290


291

292
293
294
295
296
297
298
299
300
301
302














303
304



305

306
307
308
309
310





311
312
313
314


315
316
317
318
319
320




321
322
323


324
325


326
327
328
329
330
331
332
333
334
335
336












337

338
339


340
341
342


343
344
345
346


347
348

349
350
351
352
353


354
355


356
357

358
359

360
361
362
363
364
365









366
367
368











369

370

371
372
373

374
375

376
377

378
379
380


381
382

383
384
385

386
387
388
389
390

391
392
393
394
395
396
397

398
399

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421



























































































































422
423
424
425
426
427










































428
429
430
431
432
433
434
435
436
437
438
439




































































































































440


















441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483





























































































































































































































































































































































484
485
486
487
10
11
12
13
14
15
16

17
18
19
20






21
22
23
24
25
26


27
28





29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81


82







83



84



85



86









87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103





104
105
106
107
108
109
110
111


112
113
114
115


116
117
118
119


120

121

122
123




124
125
126
127



128


129
130
131


132
133
134
135


136
137



138
139

140
141
142


143


144
145
146
147


148
149
150
151
152

153
154



155

156
157






158
159
160
161
162
163
164
165
166
167

168

169

170

171




172
173
174
175
176


177
178


179
180
181




182
183
184
185
186
187
188
189


190
191
192


193
194
195
196
197
198


199
200
201



202
203
204
205
206

207
208
209


210
211
212
213
214
215



216
217
218



219
220



221
222
223
224


225
226
227






228
229
230
231
232
233
234
235
236
237











238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255


256
257
258
259

260
261
262
263



264
265
266






267
268
269
270
271
272
273
274
275
276




277


278
279
280

281
282
283


284
285

286
287



288
289
290
291
292

293
294
295
296











297
298
299
300
301
302
303
304
305
306
307
308
309
310
311

312
313
314
315
316





317
318
319
320
321
322



323
324






325
326
327
328
329


330
331


332
333
334










335
336
337
338
339
340
341
342
343
344
345
346
347
348


349
350
351


352
353
354



355
356
357

358
359




360
361
362

363
364
365

366


367


368


369
370
371
372
373
374
375
376
377
378



379
380
381
382
383
384
385
386
387
388
389
390
391

392
393


394
395

396


397



398
399
400

401
402


403





404





405

406


407

408



409
410
411
412
413












414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537





538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579












580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730











































731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083







-
+
+


-
-
-
-
-
-
+
+
+
+
+

-
-
+
+
-
-
-
-
-
+








+
+
+











+
+
+
+
















+





-




-
-

-
-
-
-
-
-
-
+
-
-
-
+
-
-
-
+
-
-
-
+
-
-
-
-
-
-
-
-
-
+
















-
-
-
-
-
+
+
+
+
+
+

+
-
-
+
+
+

-
-
+
+
+

-
-
+
-

-
+

-
-
-
-
+
+
+
+
-
-
-

-
-
+
+

-
-
+
+
+

-
-
+
+
-
-
-
+

-
+
+
+
-
-

-
-
+
+
+

-
-
+
+
+
+

-
+

-
-
-

-
+

-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
+
-

-
+
-

-
-
-
-
+
+
+
+

-
-
+

-
-
+
+

-
-
-
-
+
+
+
+
+
+

+
-
-
+
+

-
-
+
+
+
+
+

-
-
+
+
+
-
-
-
+
+
+

+
-
+

+
-
-
+
+
+
+

+
-
-
-
+
+
+
-
-
-
+

-
-
-
+
+

+
-
-
+
+

-
-
-
-
-
-
+
+
+
+
+
+
+

+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
+
+
+

-
+
+
+

-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
-
-
-
+
-
-
+

+
-
+
+

-
-
+
+
-

+
-
-
-
+
+
+
+

-
+
+

+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+
+
+

+
-
-
-
-
-
+
+
+
+
+

-
-
-
+
+
-
-
-
-
-
-
+
+
+
+

-
-
+
+
-
-
+
+

-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+

+
-
-
+
+

-
-
+
+

-
-
-
+
+

-
+

-
-
-
-
+
+

-
+
+

-
+
-
-
+
-
-

-
-

+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+

+
-
+

-
-
+

-
+
-
-
+
-
-
-
+
+

-
+

-
-
+
-
-
-
-
-
+
-
-
-
-
-

-
+
-
-
+
-

-
-
-





-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




;  Dependencies: StrLib
;
;  Notes: This file contains OS independent part of the library and includes respective
;         OS dependent files.
;_________________________________________________________________________________________
module "Text library"

include "%TargetOS%/text.asm"

interface DrawString, .pImage, .pString, .len, .x, .y, .font, .color


macro min a, b, use {
        sub     b, a
        sbb     use, use
        and     use, b
        add     a, use
}
interface TextDecompose, .hString, .font


interface DrawDecomposedString, .pImage, .pArray, .x, .y, .font, .color


macro max a, b, use {
        sub     b, a
interface GetTextBounds, .pString, .len, .font

        sbb     use, use
        not     use
        and     use, b
        add     a, use
}



struct TTextExtent
  .width  dd ?
  .height dd ?
  .OffsX  dd ?
  .OffsY  dd ?
ends





struct TCharAttr
  .font       dd ?
  .color      dd ?
  .background dd ?
  .flags      dd ?      ; for free use of the client.
ends


; dtfXXX means "draw text flag"

dtfHAlignMask = $3
dtfVAlignMask = $c


; horizontal align
dtfAlignLeft    = 0
dtfAlignRight   = 1
dtfAlignCenter  = 2
dtfAlignJustify = 3

; vertical align
dtfAlignTop    = 0 shl 2
dtfAlignBottom = 1 shl 2
dtfAlignMiddle = 2 shl 2

; Text layout
dtfCRLF         = $0100
dtfWordWrap     = $0200
dtfTableTabs    = $0400
dtfSingleLine   = $0800


struct _TTextChunk
  .y      dd ?
  .width  dd ?
  .height dd ?
  .len    dd ?
  .ptr    dd ?
ends

__HeightProbeString text '18ilj.Xygl[_|"`g'
__NumberProbeString text '8888888888888888'

; returns: eax - mean width
; returns: edx - height
; returns: ecx - descent
proc FontGetCharSize, .raster, .font, .probe
begin
        push    ebx

struct TTextChar
        stdcall AllocateContext, [.raster]
        mov     ebx, eax

  .code   dd ?           ; unicode of the character.
        stdcall GetTextOffset, ebx, [.probe], 16, [.font]
        mov     ecx, edx

  .width  dw ?           ; width increment in pixels.
;        DebugMsg "Text offset y:"
;        OutputRegister regECX, 10

  .height dw ?           ; height increment in pixels - if <> 0 this char must be written on new line.
        stdcall GetTextBounds, ebx, [.probe], 16, [.font]
        stdcall ReleaseContext, ebx

        sub     ecx, edx
        shr     eax, 4
        neg     ecx
        pop     ebx
        return
endp
ends




proc AdjustCountUtf8
begin
        push    esi
        lea     esi, [esi+ebx]
        stdcall ScanBackUtf8
        mov     ebx, esi
        pop     esi
        sub     ebx, esi
        return
endp


proc DrawTextBox, .context, .text, .bounds, .flags, .font, .color
.len   dd ?
.count dd ?
.height dd ?
.y      dd ?

proc JustifyLine, .CharArray, .from, .to, .current_width, .align_width
begin
        pushad

        dec     [.to]   ; don't change the last character width.

        mov     edi, [.CharArray]
.low  dd  ?
.high dd  ?
        mov     ecx, [.to]
        sub     ecx, [.from]
        jle     .finish

.linew     dd ?
.lineh     dd ?
        mov     edx, [.align_width]
        sub     edx, [.current_width]
        jle     .finish

.DrawProc dd ?
begin
        mov     esi, edx
        pushad

        mov     ecx, DrawString
        mov     ebx, [.from]

        mov     eax, [.flags]
        and     eax, $03
        cmp     eax, dtfAlignJustify
        jne     @f
.align_loop:
        inc     ebx
        cmp     ebx, [.to]
        jae     .finish
        mov     ecx, DrawStringJustified
@@:
        mov     [.DrawProc], ecx

        stdcall StrLen, [.text]
        mov     [.len], eax
        cmp     word [edi+TArray.array+8*ebx+TTextChar.width], 0
        je      .skip_this

        stdcall StrPtr, [.text]
        mov     esi, eax
.sub:
        test    esi, esi
        js      .negative

        mov     edi, [.bounds]
        mov     eax, [edi+TBounds.height]
        sub     esi, ecx
        inc     word [edi+TArray.array+8*ebx+TTextChar.width]
;        mov     ecx, [edi+TBounds.y]
        mov     [.height], eax
        mov     [.y], 0 ;ecx
        jmp     .sub

; slice the string on chunks, depending on flags, rectangle width and the string content.
.negative:
        add     esi, edx
        jmp     .align_loop
; push _TTextChunk for every chunk in stack.
        mov     [.count], 0

.slice:
        mov     ecx, [.len]
.skip_this:
        dec     ecx
        jnz     .align_loop

        test    [.flags], dtfCRLF
        jz      .cropit
.finish:
        popad
        return
endp

        xor     ecx, ecx


.scanCRLF:
        cmp     ecx, [.len]
        jae     .cropit

        mov     al, [esi+ecx]
proc DrawTextBox, .pImage, .text, .x, .y, .width, .height, .extra_line, .flags, .font, .color

        cmp     al, $0d
        je      .cropit
        cmp     al, $0a
        je      .cropit
        inc     ecx
        jmp     .scanCRLF
.ascender   dd ?
.descender  dd ?

.txt_height dd ?

.last_word  dd ?
.lw_width   dd ?

.no_just    dd ?

.cropit:
begin
        mov     ebx, ecx  ; high limit

        stdcall AdjustCountUtf8
        pushad
        stdcall GetTextBounds, [.context], esi, ebx, [.font]

        cmp     edx, [.height]
        jg      .drawchunks

        mov     [.lineh], edx
        stdcall TextDecompose, [.text], [.font]
        mov     edi, eax
        mov     [.ascender], edx
        mov     [.descender], ecx

        cmp     eax, [edi+TBounds.width]
        jle     .itfits
        add     [.y], edx

        mov     [.high], ebx
        mov     [.low], 0
        xor     ecx, ecx
        mov     [.txt_height], ecx

.croploop:
        mov     ebx, [.low]
        add     ebx, [.high]
        shr     ebx, 1
        cmp     [edi+TArray.count], ecx
        je      .finish

.main_loop:                             ; start of new line
        xor     ebx, ebx                ; current X coordinate.
        or      [.last_word], -1        ; end of the word -1 means there is no word from the beginning of the line.

        mov     eax, [.txt_height]
        cmp     ebx, 1
        ja      .check_width
        cmp     eax, [.height]
        jb      .format_it

        mov     ebx, 1
        jmp     .itfits
        mov     eax, [.extra_line]
        sub     [.txt_height], eax

        mov     [edi+TArray.count], ecx
        jmp     .draw_all2

.check_width:
        stdcall AdjustCountUtf8

.format_it:
        stdcall InsertArrayItems, edi, ecx, 1
        stdcall GetTextBounds, [.context], esi, ebx, [.font]
        cmp     eax, [edi+TBounds.width]
        je      .itfits
        mov     edi, edx
        mov     [eax+TTextChar.code], $20
        mov     dword [eax+TTextChar.width], ebx        ; Set to zero TTextChar.height as well!

        mov     esi, ecx       ; start of the line!
        jg      .above
        inc     ecx

.slice_loop:
        cmp     ebx, [.low]
        je      .itfits

; Is it end of a word?
        cmp     [edi+TArray.array+8*ecx+TTextChar.code], $20
        ja      .white_ok

        test    ecx, ecx
        mov     [.low], ebx
        jmp     .croploop

        jz      .white_ok

        cmp     [edi+TArray.array+8*ecx-8+TTextChar.code], $20  ; previous character
.above:
        mov     [.high], ebx
        jmp     .croploop
        jbe     .white_ok

.itfits: ; here ebx contains the len of string that fits in the rectangle.
        mov     ecx, ebx
        mov     [.linew], eax
        mov     [.last_word], ecx        ; edx is a pointer to the end of the last word.
        mov     [.lw_width], ebx

.white_ok:
        test    [.flags], dtfWordWrap
        jz      .pushit
        test    [.flags], dtfCRLF
        jz      .crlf_ok

; search the last space or tab that separates words:
        mov     edx, ecx
        cmp     byte [esi+edx], $0d
        je      .found
        cmp     byte [esi+edx], $0a
        je      .found
        mov     [.no_just], 1

        cmp     [edi+TArray.array+8*ecx+TTextChar.code], $0d
        je      .new_line

        cmp     [edi+TArray.array+8*ecx+TTextChar.code], $0a
        je      .new_line

.crlf_ok:
        mov     [.no_just], 0
.searchword:
        cmp     byte [esi+edx], 0
        je      .found
        cmp     byte [esi+edx], ' '
        je      .found
        cmp     byte [esi+edx], $09
        je      .found
        cmp     byte [esi+edx], $0d
        je      .found
        cmp     byte [esi+edx], $0a
        je      .found

        test    [.flags], dtfTableTabs
        jz      .tabs_ok

; implement here check for tab and tabs expanding.

.tabs_ok:

; check the current line width

        movzx   eax, word [edi+TArray.array+8*ecx+TTextChar.width]
        add     eax, ebx

        cmp     eax, [.width]
        ja      .wider

        mov     ebx, eax

        dec     edx
        jnz     .searchword
        inc     ecx
        cmp     ecx, [edi+TArray.count]
        jb      .slice_loop

        mov     edx, ecx
        mov     [.no_just], 1
        call    .RowAlign
        jmp     .draw_all

.found:
        push    ebx
        mov     ebx, edx

.wider:
        test    [.flags], dtfSingleLine
        stdcall AdjustCountUtf8
        stdcall GetTextBounds, [.context], esi, ebx, [.font]
        mov     [.linew], eax
        mov     [.lineh], edx
        mov     ecx, ebx
        pop     ebx
        jnz     .del_remaining

        mov     eax, ecx
        sub     eax, esi
        cmp     eax, 1
        jbe     .finish         ; Even single char can not be displayed on this [.width]

; next line
.new_line:

.pushit:
        push    esi             ; pointer to the string.
        push    ecx             ; length of the string.
        push    [.lineh]        ; height of the line.
        test    [.flags], dtfWordWrap
        push    [.linew]        ; width of the line.
        push    [.y]            ;
        jz      .word_ok

; word wrap
        inc     [.count]
        cmp     [.last_word], 0
        jl      .word_ok       ; there is no previous word, so split on the current pos.

        mov     eax, [.lineh]
        add     [.y], eax
        mov     ecx, [.last_word]
        mov     ebx, [.lw_width]
        sub     [.height], eax

.word_ok:
        lea     esi, [esi+ecx]
        sub     [.len], ecx
        jz      .drawchunks
        call    .RowAlign

        mov     eax, [edi+TArray.lparam]                                ; contains the line height computed by DecomposeText
        add     eax, [.extra_line]

        xor     ecx, ecx
        add     [.txt_height], eax
        mov     word [edi+TArray.array+8*ecx-8+TTextChar.height], ax

        test    [.flags], dtfCRLF
; search for the whitespace that have to be skip
.skiploop:
        mov     al, [esi]
        cmp     al, $0d
        je      .skipcrlf
        cmp     al, $0a
        je      .skipcrlf
        cmp     al, $20
        je      .skipspace
        cmp     al, $09
        je      .skipspace
        jz      .skip_ws_loop

        mov     eax, [edi+TArray.array+8*ecx+TTextChar.code]
        cmp     eax, $0d
        je      .skip_cr

        cmp     eax, $0a
        jne     .skip_ws_loop

.skip_cr:
        mov     word [edi+TArray.array+8*ecx+TTextChar.width], 0     ; zero width, skip it.
        inc     ecx
        cmp     ecx, [edi+TArray.count]
        je      .draw_all

        jmp     .slice
        xor     eax, $0d xor $0a
        cmp     [edi+TArray.array+8*ecx+TTextChar.code], eax
        jne     .main_loop

        mov     word [edi+TArray.array+8*ecx+TTextChar.width], 0     ; zero width, skip it.
.skipspace:
        inc     esi
        dec     [.len]
        jnz     .skiploop
        jmp     .drawchunks

        inc     ecx
        cmp     ecx, [edi+TArray.count]
        jae     .draw_all
        jmp     .main_loop

.skipcrlf:
        inc     esi
        dec     [.len]
.del_remaining:

        xor     al, $0d xor $0a
        cmp     [esi], al
        jne     .slice
        inc     esi
        dec     [.len]
        jnz     .slice
        mov     eax, [edi+TArray.count]
        sub     eax, ecx
        stdcall DeleteArrayItems, edi, ecx, eax
        jmp     .draw_all

; pop the _TTextChunk structures and draw, depending on flags.
.drawchunks:

.skip_ws_loop:
        cmp     [.count], 0
        je      .finish
        cmp     [edi+TArray.array+8*ecx+TTextChar.code], $20
        ja      .main_loop

        mov     ebx, esp
        stdcall GetTextOffset, [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.font]
        mov     eax, [ebx+_TTextChunk.height]
        sub     eax, edx        ; it should be the line y descent
        test    [.flags], dtfAlignBottom
        jnz     @f
        sub     [.y], eax
@@:
        mov     edx, [.flags]
        and     edx, dtfAlignBottom or dtfAlignMiddle
        mov     word [edi+TArray.array+8*ecx+TTextChar.width], 0     ; zero width, skip it.

        inc     ecx
        cmp     ecx, [edi+TArray.count]
        jb      .skip_ws_loop


.draw_all:
; compute the vertical align.

        mov     eax, [edi+TArray.lparam]
        add     [.txt_height], eax

.draw_all2:
        mov     ecx, [edi+TBounds.height]
        sub     ecx, [.y]
        mov     ecx, [.height]
        sub     ecx, [.txt_height]

        cmp     edx, dtfAlignBottom
        je      .yalignok
        mov     eax, [.flags]
        and     eax, dtfVAlignMask

        sar     ecx, 1
        cmp     edx, dtfAlignMiddle
        je      .yalignok
        cmp     eax, dtfAlignTop
        je      .drawit

        xor     ecx, ecx
        add     [.y], ecx

.yalignok:
.drawloop:
        cmp     [.count], 0
        je      .finish
        cmp     eax, dtfAlignBottom
        je      .drawit

        mov     ebx, esp
        sar     ecx, 1
        sub     [.y], ecx

        mov     eax, [edi+TBounds.width]
.drawit:
        sub     eax, [ebx+_TTextChunk.width]

        stdcall DrawDecomposedString, [.pImage], edi, [.x], [.y], [.font], [.color]
        mov     edx, [.flags]
        and     edx, $03

        cmp     edx, dtfAlignRight
        je      .hready

.finish:
        stdcall FreeMem, edi
        popad
        return




.RowAlign:
        shr     eax, 1
        cmp     edx, dtfAlignCenter
        je      .hready
        mov     eax, [.flags]
        and     eax, dtfHAlignMask

        cmp     eax, dtfAlignLeft
        je      .align_ok               ; no need for extra space

        cmp     eax, dtfAlignJustify
        jne     .align_center_right

        cmp     [.no_just], 1
        je      .align_ok

        stdcall JustifyLine, edi, esi, ecx, ebx, [.width]
        xor     eax, eax
        jmp     .align_ok

.hready:
        add     eax, [edi+TBounds.x]
.align_center_right:

        push    eax
        mov     edx, [.width]
        stdcall GetTextOffset, [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.font]
        add     edx, ecx
        sub     edx, ebx
        add     edx, [ebx+_TTextChunk.y]
        add     edx, [edi+TBounds.y]
        pop     eax
        cmp     eax, dtfAlignRight
        je      .set_align

        stdcall [.DrawProc], [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], eax, edx, [.font], [.color]
        sar     edx, 1

; draws lines on every row of text. For debug purposes.
iglobal
.set_align:
  if used __UnderlineStyle
    __UnderlineStyle LineStyle 0, $808080
  end if
endg

        mov     word [edi+TArray.array+8*esi+TTextChar.width], dx
if defined options.DebugMode & options.DebugMode
        stdcall SetLineStyle, [.context], __UnderlineStyle
        stdcall DrawLine, [.context], [edi+TBounds.x], edx, [edi+TBounds.width], edx
end if
; end debug code


.align_ok:
        add     esp, sizeof._TTextChunk
        dec     [.count]
        retn
        jmp     .drawloop

.finish:
        popad
        return
endp




proc DrawStringJustified, .raster, .ptrString, .len, .x, .y, .font, .color
.XX    dd ?
.rem   dd ?
.crem  dd ?
.endptr dd ?
begin
        pushad

        mov     esi, [.ptrString]
        mov     eax, [.len]
        add     eax, esi
        mov     [.endptr], eax


;proc DrawTextBox, .pImage, .text, .x, .y, .width, .height, .flags, .font, .color
;
;  .count dd ?
;
;  .widths  dd  ?
;  .offset  dd  ?
;
;begin
;        pushad
;
;        stdcall StrPtr, [.text]
;        mov     esi, eax
;
;        add     [.y], 22
;
;        stdcall GetTextWidthsArray, [.text], [.font]
;
;        mov     [.widths], eax
;        mov     eax, [.widths]
;        lea     edi, [eax+TArray.array]     ; array with x coordinates of every char in the string.
;
;; slice the string on chunks, depending on flags, rectangle width and the string content.
;; push _TTextChunk for every chunk in stack.
;
;        xor     ecx, ecx
;        mov     [.count], ecx
;        mov     [.offset], ecx
;
;.slice_loop:
;        push    esi                             ; push _TTextChunk.ptr
;
;.scan_loop:
;        stdcall DecodeUtf8, [esi]
;
;        test    eax, eax
;        jz      .slice_here
;
;        test    [.flags], dtfCRLF
;        jz      .check_width
;
;        cmp     eax, $0d
;        je      .cr_lf
;
;        cmp     eax, $0a
;        je      .cr_lf
;
;
;.check_width:
;        mov     ecx, [edi]
;        sub     ecx, [.offset]
;        cmp     ecx, [.width]
;        jae    .slice_here
;
;        add     esi, edx
;        add     edi, 4
;        jmp     .scan_loop
;
;
;.cr_lf:
;        mov     ecx, esi
;        inc     esi
;        add     edi, 4
;
;        xor     eax, $0d xor $0a
;        cmp     byte [esi], al
;        jne     @f
;        inc     esi
;        dec     ecx
;        add     edi, 4
;@@:
;
;        pushd   [edi]
;        popd    [.offset]
;
;        jmp     .chunk_len
;
;
;.slice_here:
;        mov     ecx, [edi]
;        mov     [.offset], ecx
;
;.end_string:
;        mov     ecx, esi
;
;.chunk_len:
;        sub     ecx, [esp]      ; the start of the chunk!
;
;        push    ecx                     ; push _TTextChunk.len
;        push    edx                     ; push _TTextChunk.width
;        push    [.y]                    ; push _TTextChunk.y
;
;
;        add     [.y], 22        ;TEST/DEBUG
;        inc     [.count]
;
;        test    eax, eax
;        jnz     .slice_loop
;
;; here, all slices are in the stack, so draw them from down to the top.
;
;
;        cmp     [.count], 0
;        je      .finish
;
;.draw_loop:
;        mov     ebx, esp
;        stdcall DrawString, [.pImage], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.x], [ebx+_TTextChunk.y], [.font], [.color]
;
;        add     esp, sizeof._TTextChunk
;
;        dec     [.count]
;        jnz     .draw_loop
;
;
;.finish:
;        stdcall FreeMem, [.widths]
;        popad
;        return
;
;endp


        stdcall StrLenUtf8, esi, [.len]
        mov     ecx, eax
        dec     ecx
        jg      @f
        mov     ecx, 1

;
;
;
;
;
;        mov     ecx, [.len]
;
;        test    [.flags], dtfCRLF
;        jz      .cropit
;
;        xor     ecx, ecx
;
;.scanCRLF:
;        cmp     ecx, [.len]
;        jae     .cropit
;
;        mov     al, [esi+ecx]
;
;        cmp     al, $0d
;        je      .cropit
;        cmp     al, $0a
;        je      .cropit
;        inc     ecx
;        jmp     .scanCRLF
;
;.cropit:
;        mov     ebx, ecx  ; high limit
;
;        stdcall AdjustCountUtf8
;
;        mov     eax, [.widths]
;        mov     eax, [eax+4*ebx+TArray.array]
;        sub     eax, [.start_len]
;
;;        stdcall GetTextBounds, [.context], esi, ebx, [.font]
;
;;?????
;;        cmp     edx, [.height]
;;        jg      .drawchunks
;
;;        mov     [.lineh], edx
@@:

        stdcall GetTextBounds, [.raster], esi, [.len], [.font]

        sub     eax, [edi+TBounds.width]
        neg     eax

        cdq
        div    ecx

        cmp     eax, 4
        jge     .cantjustify    ; the needed space is too big for justify, so just draw it left aligned
;
;        cmp     eax, [edi+TBounds.width]
;        jle     .itfits
;
;        mov     [.high], ebx
;        mov     [.low], 0
;
;.croploop:
;        mov     ebx, [.low]
;        add     ebx, [.high]
;        shr     ebx, 1
;
;        cmp     ebx, 1
;        ja      .check_width
;
;        mov     ebx, 1
;        jmp     .itfits
;
;.check_width:
;        stdcall AdjustCountUtf8
;        stdcall GetTextBounds, [.context], esi, ebx, [.font]
;        cmp     eax, [edi+TBounds.width]
;        je      .itfits
;
;        jg      .above
;
;        cmp     ebx, [.low]
;        je      .itfits
;
;        mov     [.low], ebx
;        jmp     .croploop
;
;.above:
;        mov     [.high], ebx
;        jmp     .croploop
;
;.itfits: ; here ebx contains the len of string that fits in the rectangle.
;        mov     ecx, ebx
;        mov     [.linew], eax
;
;        test    [.flags], dtfWordWrap
;        jz      .pushit
;
;; search the last space or tab that separates words:
;        mov     edx, ecx
;
;.searchword:
;        cmp     byte [esi+edx], 0
;        je      .found
;        cmp     byte [esi+edx], ' '
;        je      .found
;        cmp     byte [esi+edx], $09
;        je      .found
;        cmp     byte [esi+edx], $0d
;        je      .found
;        cmp     byte [esi+edx], $0a
;        je      .found
;
;        dec     edx
;        jnz     .searchword
;
;        mov     edx, ecx
;
;.found:
;        push    ebx
;        mov     ebx, edx
;
;        stdcall AdjustCountUtf8
;
;        stdcall GetTextBounds, [.context], esi, ebx, [.font]
;
;        mov     [.linew], eax
;        mov     [.lineh], edx
;        mov     ecx, ebx
;        pop     ebx
;
;.pushit:
;        push    esi             ; pointer to the string.
;        push    ecx             ; length of the string in bytes.
;        push    [.lineh]        ; height of the line in pixels.
;        push    [.linew]        ; width of the line in pixels.
;        push    [.y]            ; y coordinate of the line.
;
;        inc     [.count]
;
;        mov     eax, [.lineh]
;        add     [.y], eax
;        sub     [.height], eax
;
;        lea     esi, [esi+ecx]
;        sub     [.len], ecx
;        jz      .drawchunks
;
;        xor     ecx, ecx
;
;; search for the whitespace that have to be skip
;.skiploop:
;        mov     al, [esi]
;        cmp     al, $0d
;        je      .skipcrlf
;        cmp     al, $0a
;        je      .skipcrlf
;        cmp     al, $20
;        je      .skipspace
;        cmp     al, $09
;        je      .skipspace
;
;        jmp     .slice
;
;.skipspace:
;        inc     esi
;        dec     [.len]
;        jnz     .skiploop
;        jmp     .drawchunks
;
;.skipcrlf:
;        inc     esi
;        dec     [.len]
;        xor     al, $0d xor $0a
;        cmp     [esi], al
;        jne     .slice
;        inc     esi
;        dec     [.len]
;        jnz     .slice
;
;
;
;
;
;        return
;endp




;proc DrawTextBox, .context, .text, .bounds, .flags, .font, .color
;.len   dd ?
;.count dd ?
;.height dd ?
;.y      dd ?
;
;.low  dd  ?
;.high dd  ?
;
;.linew     dd ?
;.lineh     dd ?
;
;.DrawProc dd ?
;begin
;        pushad
;
        mov     ecx, eax
        mov     [.rem], edx
        mov     [.crem], edx

        mov     ebx, [.len]
        push    [.x]
        pop     [.XX]

.drawloop:
        cmp     esi, [.endptr]
        jae     .finish

        stdcall DecodeUtf8, [esi]
        jc      .finish

        push    edx
        stdcall DrawString, [.raster], esi, edx, [.XX], [.y], [.font], [.color]
        stdcall GetTextBounds, [.raster], esi, edx, [.font]
        pop     edx
        add     esi, edx
        add     [.XX], eax
        add     [.XX], ecx

        cmp     [.crem], 0
        je      .drawloop

        sub     ebx, [.rem]
        jge     .drawloop

        inc     [.XX]
        dec     [.crem]
        mov     ebx, [.len]
        sub     ebx, [.rem]
        jmp     .drawloop

.finish:
        popad
        return

.cantjustify:
        stdcall DrawString, [.raster], [.ptrString], [.len], [.x], [.y], [.font], [.color]
        jmp     .finish
endp
;        mov     ecx, DrawString
;
;        mov     eax, [.flags]
;        and     eax, $03
;        cmp     eax, dtfAlignJustify
;        jne     @f
;        mov     ecx, DrawStringJustified
;@@:
;        mov     [.DrawProc], ecx
;
;        stdcall StrLen, [.text]
;        mov     [.len], eax
;
;        stdcall StrPtr, [.text]
;        mov     esi, eax
;
;        mov     edi, [.bounds]
;        mov     eax, [edi+TBounds.height]
;;        mov     ecx, [edi+TBounds.y]
;        mov     [.height], eax
;        mov     [.y], 0 ;ecx
;
;; slice the string on chunks, depending on flags, rectangle width and the string content.
;; push _TTextChunk for every chunk in stack.
;        mov     [.count], 0
;
;.slice:
;        mov     ecx, [.len]
;
;        test    [.flags], dtfCRLF
;        jz      .cropit
;
;        xor     ecx, ecx
;
;.scanCRLF:
;        cmp     ecx, [.len]
;        jae     .cropit
;
;        mov     al, [esi+ecx]
;
;        cmp     al, $0d
;        je      .cropit
;        cmp     al, $0a
;        je      .cropit
;        inc     ecx
;        jmp     .scanCRLF
;
;.cropit:
;        mov     ebx, ecx  ; high limit
;
;        stdcall AdjustCountUtf8
;        stdcall GetTextBounds, [.context], esi, ebx, [.font]
;
;        cmp     edx, [.height]
;        jg      .drawchunks
;
;        mov     [.lineh], edx
;
;        cmp     eax, [edi+TBounds.width]
;        jle     .itfits
;
;        mov     [.high], ebx
;        mov     [.low], 0
;
;.croploop:
;        mov     ebx, [.low]
;        add     ebx, [.high]
;        shr     ebx, 1
;
;        cmp     ebx, 1
;        ja      .check_width
;
;        mov     ebx, 1
;        jmp     .itfits
;
;.check_width:
;        stdcall AdjustCountUtf8
;        stdcall GetTextBounds, [.context], esi, ebx, [.font]
;        cmp     eax, [edi+TBounds.width]
;        je      .itfits
;
;        jg      .above
;
;        cmp     ebx, [.low]
;        je      .itfits
;
;        mov     [.low], ebx
;        jmp     .croploop
;
;.above:
;        mov     [.high], ebx
;        jmp     .croploop
;
;.itfits: ; here ebx contains the len of string that fits in the rectangle.
;        mov     ecx, ebx
;        mov     [.linew], eax
;
;        test    [.flags], dtfWordWrap
;        jz      .pushit
;
;; search the last space or tab that separates words:
;        mov     edx, ecx
;        cmp     byte [esi+edx], $0d
;        je      .found
;        cmp     byte [esi+edx], $0a
;        je      .found
;
;.searchword:
;        cmp     byte [esi+edx], 0
;        je      .found
;        cmp     byte [esi+edx], ' '
;        je      .found
;        cmp     byte [esi+edx], $09
;        je      .found
;        cmp     byte [esi+edx], $0d
;        je      .found
;        cmp     byte [esi+edx], $0a
;        je      .found
;
;        dec     edx
;        jnz     .searchword
;
;        mov     edx, ecx
;
;.found:
;        push    ebx
;        mov     ebx, edx
;        stdcall AdjustCountUtf8
;        stdcall GetTextBounds, [.context], esi, ebx, [.font]
;        mov     [.linew], eax
;        mov     [.lineh], edx
;        mov     ecx, ebx
;        pop     ebx
;
;.pushit:
;        push    esi             ; pointer to the string.
;        push    ecx             ; length of the string.
;        push    [.lineh]        ; height of the line.
;        push    [.linew]        ; width of the line.
;        push    [.y]            ;
;
;        inc     [.count]
;
;        mov     eax, [.lineh]
;        add     [.y], eax
;        sub     [.height], eax
;
;        lea     esi, [esi+ecx]
;        sub     [.len], ecx
;        jz      .drawchunks
;
;        xor     ecx, ecx
;
;; search for the whitespace that have to be skip
;.skiploop:
;        mov     al, [esi]
;        cmp     al, $0d
;        je      .skipcrlf
;        cmp     al, $0a
;        je      .skipcrlf
;        cmp     al, $20
;        je      .skipspace
;        cmp     al, $09
;        je      .skipspace
;
;        jmp     .slice
;
;.skipspace:
;        inc     esi
;        dec     [.len]
;        jnz     .skiploop
;        jmp     .drawchunks
;
;.skipcrlf:
;        inc     esi
;        dec     [.len]
;        xor     al, $0d xor $0a
;        cmp     [esi], al
;        jne     .slice
;        inc     esi
;        dec     [.len]
;        jnz     .slice
;
;; pop the _TTextChunk structures and draw, depending on flags.
;.drawchunks:
;        cmp     [.count], 0
;        je      .finish
;
;        mov     ebx, esp
;        stdcall GetTextOffset, [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.font]
;        mov     eax, [ebx+_TTextChunk.height]
;        sub     eax, edx        ; it should be the line y descent
;        test    [.flags], dtfAlignBottom
;        jnz     @f
;        sub     [.y], eax
;@@:
;        mov     edx, [.flags]
;        and     edx, dtfAlignBottom or dtfAlignMiddle
;
;        mov     ecx, [edi+TBounds.height]
;        sub     ecx, [.y]
;
;        cmp     edx, dtfAlignBottom
;        je      .yalignok
;
;        sar     ecx, 1
;        cmp     edx, dtfAlignMiddle
;        je      .yalignok
;
;        xor     ecx, ecx
;
;.yalignok:
;.drawloop:
;        cmp     [.count], 0
;        je      .finish
;
;        mov     ebx, esp
;
;        mov     eax, [edi+TBounds.width]
;        sub     eax, [ebx+_TTextChunk.width]
;
;        mov     edx, [.flags]
;        and     edx, $03
;
;        cmp     edx, dtfAlignRight
;        je      .hready
;
;        shr     eax, 1
;        cmp     edx, dtfAlignCenter
;        je      .hready
;
;        xor     eax, eax
;
;.hready:
;        add     eax, [edi+TBounds.x]
;
;        push    eax
;        stdcall GetTextOffset, [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.font]
;        add     edx, ecx
;        add     edx, [ebx+_TTextChunk.y]
;        add     edx, [edi+TBounds.y]
;        pop     eax
;
;        stdcall [.DrawProc], [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], eax, edx, [.font], [.color]
;
;;; draws lines on every row of text. For debug purposes.
;;iglobal
;;  if used __UnderlineStyle
;;    __UnderlineStyle LineStyle 0, $808080
;;  end if
;;endg
;;
;;if defined options.DebugMode & options.DebugMode
;;        stdcall SetLineStyle, [.context], __UnderlineStyle
;;        stdcall DrawLine, [.context], [edi+TBounds.x], edx, [edi+TBounds.width], edx
;;end if
;;; end debug code
;
;
;        add     esp, sizeof._TTextChunk
;        dec     [.count]
;        jmp     .drawloop
;
;.finish:
;        popad
;        return
;endp
;
;
;
;
;proc DrawStringJustified, .raster, .ptrString, .len, .x, .y, .font, .color
;.XX    dd ?
;.rem   dd ?
;.crem  dd ?
;.endptr dd ?
;begin
;        pushad
;
;        mov     esi, [.ptrString]
;        mov     eax, [.len]
;        add     eax, esi
;        mov     [.endptr], eax
;
;        stdcall StrLenUtf8, esi, [.len]
;        mov     ecx, eax
;        dec     ecx
;        jg      @f
;        mov     ecx, 1
;@@:
;
;        stdcall GetTextBounds, [.raster], esi, [.len], [.font]
;
;        sub     eax, [edi+TBounds.width]
;        neg     eax
;
;        cdq
;        div    ecx
;
;        cmp     eax, 4
;        jge     .cantjustify    ; the needed space is too big for justify, so just draw it left aligned
;
;        mov     ecx, eax
;        mov     [.rem], edx
;        mov     [.crem], edx
;
;        mov     ebx, [.len]
;        push    [.x]
;        pop     [.XX]
;
;.drawloop:
;        cmp     esi, [.endptr]
;        jae     .finish
;
;        stdcall DecodeUtf8, [esi]
;        jc      .finish
;
;        push    edx
;        stdcall DrawString, [.raster], esi, edx, [.XX], [.y], [.font], [.color]
;        stdcall GetTextBounds, [.raster], esi, edx, [.font]
;        pop     edx
;        add     esi, edx
;        add     [.XX], eax
;        add     [.XX], ecx
;
;        cmp     [.crem], 0
;        je      .drawloop
;
;        sub     ebx, [.rem]
;        jge     .drawloop
;
;        inc     [.XX]
;        dec     [.crem]
;        mov     ebx, [.len]
;        sub     ebx, [.rem]
;        jmp     .drawloop
;
;.finish:
;        popad
;        return
;
;.cantjustify:
;        stdcall DrawString, [.raster], [.ptrString], [.len], [.x], [.y], [.font], [.color]
;        jmp     .finish
;endp


include "%TargetOS%/text.asm"




endmodule
Changes to freshlib/gui/KolibriOS/Main.asm.
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55



56

57
58
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61







-
+











+
+
+
-
+


;
; The event can be not processed in the following cases:
;   1. The window that receives the message is not FreshLib object.
;   2. TObjectClass.procSysEventHandler = 0 for the given class and all parents.
;   3. All procSysEventHandler procedures refuse to process the event (CF=1)
;----------------------------------------------------------------------------------------------------------

dproc __ProcessOneSystemEvent, .hwnd, .wmsg, .wparam, .lparam
proc __ProcessOneSystemEvent, .hwnd, .wmsg, .wparam, .lparam
begin

        dispatch [.wmsg]

.ondefault:
        stc
        return

oncase 0
       clc
       return


        enddispatch
enddp
endp


Changes to freshlib/gui/KolibriOS/TApplication.asm.
9
10
11
12
13
14
15












16

17
18
19
20
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32







+
+
+
+
+
+
+
+
+
+
+
+
-
+




;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________




uglobal
    var FTLibrary = ?
    var FTCManager = ?
    var FTCImageCache = ?
    var FTCCMapCache = ?
endg




method TApplication.Create
method TApplication.__create
begin
        return
endp

Changes to freshlib/gui/KolibriOS/mouse.asm.
22
23
24
25
26
27
28
29

30
31
32
22
23
24
25
26
27
28

29
30
31
32







-
+




proc GetStockCursor, .index
begin
        return
endp


proc MouseCapture, .hwnd
proc __MouseCapture, .hwnd
begin
        return
endp
Changes to freshlib/gui/KolibriOS/windows.asm.
8
9
10
11
12
13
14
15






16
17
18
19








































20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

133
134
135
136
137










138
139
140
141
142

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
201
202
203
204
205
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

71


72
73
74
75
76
77
78
79





80




81
82
83
84
85
86
87
88




















89
90
91
92
93




94
95































96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

133

134
135
136
137
138
139
140
141









































142
143
144
145
146
147
148















+
+
+
+
+
+



-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






-
+
-
-








-
-
-
-
-
+
-
-
-
-








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+




-
-
-
-


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

















-
+





+
+
+
+
+
+
+
+
+
+




-
+
-








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+






-
-
-
-
-
-
-
;  Target OS: KolibriOS
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________



body _CreateNullWindow
begin
        return
endp

;_________________________________________________________________________________________


proc _CreateNullWindow

body _DestroyWindow
begin
        return
endp


;_________________________________________________________________________________________


body _GetWindowBounds
begin
        return
endp



;_________________________________________________________________________________________


body _SetWindowBounds
begin
        return
endp

;_________________________________________________________________________________________



body _ClientToScreen
begin

        return
endp



;_________________________________________________________________________________________

body _SetWindowBorder
begin
        return
endp

;_________________________________________________________________________________________


body _ShowWindow

proc _DestroyWindow, .hwnd
begin
        return
endp


;_________________________________________________________________________________________


proc _GetParent, .hwnd
begin
        return
endp

body _RefreshWindowRect
;_________________________________________________________________________________________


proc _GetChildren, .hwnd
begin
        return
endp


;_________________________________________________________________________________________



proc _GetVisible, .hwnd
begin
        return
endp

;_________________________________________________________________________________________


proc _GetWindowBounds, .hwnd, .pBounds
begin
        return
endp



;_________________________________________________________________________________________


proc _SetWindowBounds, .hwnd, .pBounds
body _SetWindowTextUtf8
begin
        return
endp





;_________________________________________________________________________________________

proc _SetWindowBorder, .hwnd, .brdType
begin
        return
endp

;_________________________________________________________________________________________

proc _ShowWindow, .hwnd, .flag
begin
        return
endp


;_________________________________________________________________________________________


proc _RefreshWindow, .hwnd
begin
        return
endp


;_________________________________________________________________________________________


proc _SetFocus, .hwnd
begin
        return
endp

;_________________________________________________________________________________________

proc _AddChild, .hwnd, .child
begin
        return
endp

;_________________________________________________________________________________________


; Common utility procedures.


;_________________________________________________________________________________________
;
; Returns the window TObject structure, from the window handle.
;_________________________________________________________________________________________

proc _GetWindowStruct, .hwin
body _GetWindowStruct
begin
        return
endp



;_________________________________________________________________________________________



body _SetWindowStruct
begin
        return
endp


;_________________________________________________________________________________________



body _SetModalTowards
proc _SetWindowStruct, .hwin, .value
begin
        return
endp


;_________________________________________________________________________________________



proc _SetWindowTextUtf8, .hwnd, .ptrUtf8
begin
        return
endp



;_________________________________________________________________________________________



proc _GetWindowTextUtf8, .hwnd, .ptrUtf8
begin
        return
endp



;_________________________________________________________________________________________


proc _EnableWindow, .hwnd, .flag
begin
        return
endp


;_________________________________________________________________________________________


proc _SetModalTowards, .hwnd, .hwndParent
begin
        return
endp


;_________________________________________________________________________________________


proc _FinalizeModal, .hwnd, .hwndParent
body _FinalizeModal
begin
        return
endp


;_________________________________________________________________________________________


proc __CommonWindowProc, .hwnd, .wmsg, .wparam, .lparam
begin
        return
endp

Changes to freshlib/gui/Linux/Main.asm.
15
16
17
18
19
20
21

22

23
24

25
26
27
28
29
30
31
15
16
17
18
19
20
21
22

23
24

25
26
27
28
29
30
31
32







+
-
+

-
+







uglobal
  if used fGlobalTerminate
    fGlobalTerminate dd ?
  end if
endg



proc ProcessSystemEvents
body ProcessSystemEvents
  .event  XEvent
          rd 256
          rb 256
begin
        push    ebx ecx edx

.event_loop:
; check for quit

        get     eax, [pApplication], TApplication:MainWindow
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121

122
123
124
125
126

127
128
129

130
131
132
133
134
135
136
137
138
139
140


141
142
143
144

145
146
147

148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177


178


179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194







195
196
197
198
199
200
201
202


203
204
205
206
207
208







209
210
211

212
213
214

215
216
217
218

219
220
221
222
223
224

225
226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242








243


244
245
246








247




248
249
250
251
252
253
254























255
256


257




258
259

260

261

262
263


264


265
266


267
268

269
270

271
272







273
274
275


276
277
278
279
280






281


282


283
284
285
286
287
288
289
290
291
292
293





























294

295
296
297
298
299
300



301
302
303
304
305
306
307
308
309
310
311
312
313
314



315
316
317
318
319
320
321
322
323
324
325
326
327
328
329








330
331
332
333
334






335
336
337
338
339


340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363




364

365


366

367

368


369


370
371
372
373
374
375
376


377
378
379




380
381
382
383
384
385
386
387
388
389








390
391
392
393





394
395
396
397
398
399
400
401
402
403
404
405








406
407
408
409
410
411
412
413
414
415
416
417




























418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85














86
87
88
89

90
91
92
93
94
95
96
97
98
99






100
101

102
103
104



105



106


107








108
109
110



111



112


113




114

115





116
117
118
119
120
121



122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
140
141
142






143
144
145
146
147
148
149


150





151
152
153





154
155
156
157
158
159
160



161
162


163




164


165



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182



183
184
185
186
187
188
189
190
191
192
193



194
195
196
197
198
199
200
201
202
203
204
205
206







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

234
235
236
237
238

239

240
241
242


243
244
245
246
247


248
249
250

251
252
253
254


255
256
257
258
259
260
261
262


263
264
265




266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282





283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317


318
319
320
321
322
323
324
325
326
327
328
329
330
331



332
333
334

335
336
337
338
339





340
341


342
343
344
345
346
347
348
349
350
351
352


353
354
355
356
357
358
359




360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381




382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402





403
404
405


406
407
408
409
410









411
412
413
414
415
416
417
418
419



420
421
422
423
424
425






426



427
428
429
430
431
432
433
434
435












436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464


465

466
















-
+











-
-
-
-
-
-
-
-
-
-
-
-
-
-




-










-
-
-
-
-
-
+

-
+


-
-
-
+
-
-
-
+
-
-

-
-
-
-
-
-
-
-
+
+

-
-
-
+
-
-
-
+
-
-

-
-
-
-
+
-

-
-
-
-
-






-
-
-







+
+
-
+
+










-
-
-
-
-
-
+
+
+
+
+
+
+
-
-

-
-
-
-
-
+
+

-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+

-
-
+
-
-
-
-
+
-
-

-
-
-
+











+




-
-
-
+
+
+
+
+
+
+
+

+
+
-
-
-
+
+
+
+
+
+
+
+

+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
-
+
+
+
+

-
+
-
+

+
-
-
+
+

+
+
-
-
+
+

-
+


+
-
-
+
+
+
+
+
+
+

-
-
+
+

-
-
-
-
+
+
+
+
+
+

+
+
-
+
+






-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+




-
-
+
+
+











-
-
-
+
+
+
-





-
-
-
-
-


-
-
+
+
+
+
+
+
+
+



-
-
+
+
+
+
+
+

-
-
-
-
+
+




















-
-
-
-
+
+
+
+

+

+
+

+

+

+
+

+
+


-
-
-
-
-
+
+

-
-
+
+
+
+

-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+

-
-
-
+
+
+
+
+

-
-
-
-
-
-

-
-
-

+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-

-

-
-
-
-
-
-
-
-
-
        pop     edx ecx ebx
        return

endp



proc WaitForSystemEvent
body WaitForSystemEvent
.event XEvent
begin
        push    eax ecx edx
        lea     eax, [.event]
        cinvoke XPeekEvent, [hApplicationDisplay], eax
        pop     edx ecx eax
        return
endp




;proc EventsQueued, .pWin
;begin
;        push    eax ecx edx
;        cinvoke XQLength, [hApplicationDisplay]
;        test    eax, eax
;        clc
;        jz      @f
;        stc
;@@:
;        pop     edx ecx eax
;        return
;endp




proc __ProcessOneSystemEvent, .linux_event
.event  rd 64
begin
        pushad

        mov     ebx, [.linux_event]

;        mov     eax, [ebx+XEvent.type]
;        cmp     eax, [ShmCompletionEvent]
;        je      .shm_completion

        stdcall _GetWindowStruct, [ebx+XEvent.window]
        mov     esi, eax
        lea     edi, [.event]
        mov     eax, [ebx+XEvent.type]

        cmp     eax, DestroyNotify
        je      .destroy
        jc      .notprocessed

        test    esi, esi
        test    eax, eax
        jz      .notprocessed

        cmp     eax, MotionNotify
        je      .mousemove

        mov     esi, eax
        cmp     eax, EnterNotify
        je      .mouseenter

        mov     ecx, [ebx+XEvent.type]
        cmp     eax, LeaveNotify
        je      .mouseleave

        cmp     eax, ButtonPress
        je      .mouse_btn_press

        cmp     eax, ButtonRelease
        je      .mouse_btn_release

        cmp     eax, Expose
        je      .expose
        cmp     ecx, LASTEvent
        jae     .notprocessed

        cmp     eax, ClientMessage        ; event from the window manager - button close for example.
        je      .clientmessage

        mov     ecx, [.jump_table+4*ecx]
        cmp     eax, KeyPress
        je      .key_press

        jecxz   .notprocessed
        cmp     eax, KeyRelease
        je      .key_release

        cmp     eax, MappingNotify
        je      .mapping_notify

        cmp     eax, FocusIn
        jmp     ecx
        je      .focusin

        cmp     eax, FocusOut
        je      .focusout

        cmp     eax, ConfigureNotify
        je      .moveresize

.notprocessed:
        popad
        stc
        return

.exec_event:
        exec    esi, TWindow:SysEventHandler, edi

.finish:
        popad
        clc
        return


;.shm_completion:
;        DebugMsg "Put back completion event!"
;
;        mov     [ShmImageLock], 0
;        int3
;        cinvoke XPutBackEvent, [hApplicationDisplay], ebx
;        jmp     .finish

;.........................................................................
; seMove and seResize events.
;-------------------------------------------------------------------------
.moveresize:
        cinvoke XCheckTypedWindowEvent, [hApplicationDisplay], [ebx+XConfigureEvent.window], ConfigureNotify, ebx
        test    eax, eax
        jnz     .moveresize

; seResize event...
        mov     [edi+TResizeEvent.event], seResize

        mov     eax, [ebx+XConfigureEvent.width]
        mov     ecx, [ebx+XConfigureEvent.height]

; resize event...
        mov     eax, [esi+TWindow._width]
        mov     edx, [esi+TWindow._height]
        cmp     eax, [ebx+XConfigureEvent.width]
        jne     .resize
        cmp     edx, [ebx+XConfigureEvent.height]
        je      .is_move
        mov     [edi+TResizeEvent.newWidth], eax
        mov     [edi+TResizeEvent.newHeight], ecx

        DebugMsg "Resize event sent."
        OutputRegister regEAX, 10
        OutputRegister regECX, 10

        exec    esi, TWindow:SysEventHandler, edi
.resize:
        exec    esi, TWindow:EventResize, [ebx+XConfigureEvent.width], [ebx+XConfigureEvent.height]

; seMove event...
        mov     [edi+TMoveEvent.event], seMove

        mov     eax, [ebx+XConfigureEvent.x]
        mov     ecx, [ebx+XConfigureEvent.y]
; move event...
.is_move:
        mov     eax, [esi+TWindow._x]
        mov     edx, [esi+TWindow._y]
        cmp     eax, [ebx+XConfigureEvent.x]
        jne     .move
        cmp     eax, [ebx+XConfigureEvent.y]
        mov     [edi+TMoveEvent.newX], eax
        mov     [edi+TMoveEvent.newY], ecx
        jmp     .exec_event
        je      .finish

;.........................................................................
; Focus events
.move:
.focusout:
        mov     [edi+TFocusOutEvent.event], seFocusOut
        jmp     .setIC

        exec    esi, TWindow:EventMove, [ebx+XConfigureEvent.x], [ebx+XConfigureEvent.y]
.focusin:
        mov     [edi+TFocusInEvent.event], seFocusIn

.setIC:
        cinvoke XSetICValues, [hInputContext], XNFocusWindow, [esi+TWindow.handle], 0
        jmp     .exec_event
        jmp     .finish

;.........................................................................
; DestroyNotify handler it invalidates the handle in TWindow structure and then destroys TWindow.
.destroy:
        test    esi, esi
        jz      .finish

        mov     [esi+TWindow.handle], 0

        destroy esi
        jmp     .finish


;.........................................................................
; Mouse event handlers

.mouseleave:
        mov     [edi+TMouseEnterEvent.event], seMouseLeave
        jmp     .exec_event
.mousemove:
        cinvoke XCheckTypedWindowEvent, [hApplicationDisplay], [ebx+XConfigureEvent.window], MotionNotify, ebx
        test    eax, eax
        jnz     .mousemove


        stdcall ServeMenuMouseMove, [ebx+XMotionEvent.window], [ebx+XMotionEvent.x], [ebx+XMotionEvent.y], [ebx+XMotionEvent.state]
        jc      .finish

        cinvoke XCheckTypedWindowEvent, [hApplicationDisplay], [ebx+XMotionEvent.window], MotionNotify, ebx
        test    eax, eax
.mouseenter:
        mov     [edi+TMouseEnterEvent.event], seMouseEnter
        jmp     .exec_event
        jnz     .mousemove

        mov     edi, [__MouseTarget]
        test    edi, edi
        jz      .search_target_move

        stdcall __GetRelativeXY, edi, [ebx+XMotionEvent.x], [ebx+XMotionEvent.y]
        jmp     .target_move

.search_target_move:
        exec    esi, TWindow:ChildByXY, [ebx+XMotionEvent.x], [ebx+XMotionEvent.y], TRUE
        mov     edi, eax

.mousemove:
        mov     [edi+TMouseMoveEvent.event], seMouseMove
        mov     eax, [ebx+XMotionEvent.x]
        mov     ecx, [ebx+XMotionEvent.y]
        mov     [edi+TMouseMoveEvent.x], eax
        mov     [edi+TMouseMoveEvent.y], ecx
        jmp     .exec_event
.target_move:
        cmp     edi, [__LastPointedWindow]
        je      .move_event

        cmp     [__LastPointedWindow], 0
        je      .leave_ok

        exec    [__LastPointedWindow], TWindow:EventMouseLeave

.leave_ok:

        mov     [__LastPointedWindow], edi
        exec    edi, TWindow:EventMouseEnter

.move_event:
        exec    edi, TWindow:EventMouseMove, ecx, edx, [ebx+XMotionEvent.state]
        jmp     .finish



;.........................................................................



.mouse_btn_press:
        stdcall ServeMenuButtonPress, [ebx+XButtonEvent.window], [ebx+XButtonEvent.button], [ebx+XButtonEvent.state], [ebx+XButtonEvent.x], [ebx+XButtonEvent.y]
        jc      .finish
.mouse_btn_release:

        mov     edi, [__MouseTarget]
        test    edi, edi
        jz      .search_target_press

        mov     eax, [ebx+XButtonEvent.type]
        stdcall __GetRelativeXY, edi, [ebx+XButtonEvent.x], [ebx+XButtonEvent.y]
        mov     [edi+TMouseButtonEvent.event], eax      ; seMouseBtnPress=ButtonPress and seMouseBtnRelease = ButtonRelease
        jmp     .target_press

.search_target_press:
        mov     eax, [ebx+XButtonEvent.button]
        dec     eax
        exec    esi, TWindow:ChildByXY, [ebx+XButtonEvent.x], [ebx+XButtonEvent.y], TRUE
        mov     edi, eax

.target_press:
        get     eax, eax, TWindow:GlobalEnabled
        cmp     [edi+TScrollEvent.event], seMouseBtnRelease
        je      @f
        test    eax, eax
        jz      .finish

        cmp     eax, 3
        cmp     [ebx+XButtonEvent.button], 4
        jge     .wheelscroll

; deal with focus
@@:
        mov     [edi+TMouseButtonEvent.Button], eax

        cmp     edi, [__FocusedWindow]
        je      .focusok

        get     eax, edi, TWindow:WantFocus
        test    eax, eax
        jz      .focusok

        mov     eax, [ebx+XButtonEvent.state]
        mov     [edi+TMouseButtonEvent.kbdStatus], eax
        mov     eax, [__FocusedWindow]
        mov     [__FocusedWindow], edi

        mov     eax, [ebx+XButtonEvent.x]
        mov     ecx, [ebx+XButtonEvent.y]
        mov     [edi+TMouseButtonEvent.x], eax
        mov     [edi+TMouseButtonEvent.y], ecx
        test    eax, eax
        jz      @f
        exec    eax, TWindow:EventFocusOut
@@:

        exec    edi, TWindow:EventFocusIn

.focusok:
        exec    edi, TWindow:EventButtonPress, [ebx+XButtonEvent.button], [ebx+XButtonEvent.state], ecx, edx
        jmp     .exec_event
        jmp     .finish


.wheelscroll:
        mov     ecx, scWheelUp
        je      @f
        mov     ecx, scWheelDn
@@:
        mov     [edi+TScrollEvent.event], seScroll
        mov     [edi+TScrollEvent.ScrollBar], scrollY
        mov     [edi+TScrollEvent.ScrollCmd], ecx
        mov     [edi+TScrollEvent.Value], 1
        jmp     .exec_event

        exec    edi, TWindow:EventScroll, scrollY, ecx, 1
        jmp     .finish



;.........................................................................



.mouse_btn_release:
        mov     edi, [__MouseTarget]
        test    edi, edi
        jz      .search_target_release

        stdcall __GetRelativeXY, edi, [ebx+XButtonEvent.x], [ebx+XButtonEvent.y]
        jmp     .target_release

.search_target_release:
        exec    esi, TWindow:ChildByXY, [ebx+XButtonEvent.x], [ebx+XButtonEvent.y], TRUE
        mov     edi, eax

.target_release:
        get     eax, eax, TWindow:GlobalEnabled
        test    eax, eax
        jz      .finish

        exec    edi, TWindow:EventButtonRelease, [ebx+XButtonEvent.button], [ebx+XButtonEvent.state], ecx, edx
        jmp     .finish


;.........................................................................
; Window paint event

.expose:
        lea     eax, [ebx+XExposeEvent.x]
        stdcall __PaintWindow, esi, eax
        get     edi, esi, TWindow:ImgScreen

        stdcall DrawImageRect, [esi+TWindow.handle], edi, [ebx+XExposeEvent.x], [ebx+XExposeEvent.y], [ebx+XExposeEvent.x], [ebx+XExposeEvent.y], [ebx+XExposeEvent.width], [ebx+XExposeEvent.height]
        jmp     .finish


;.........................................................................
; Keyboard events.

locals
  .utf8buff rb 16
endl

.key_press:
        mov     ecx, seKbdKeyPress
        mov     [edi+TKeyboardEvent.event], ecx
        mov     ecx, [ebx+XKeyEvent.state]

        cmp     [__FocusedWindow], 0
        je      .finish
        mov     [edi+TKeyboardEvent.kbdStatus], ecx

        mov     dword [.utf8buff], 0
        lea     eax, [.utf8buff]
        cinvoke Xutf8LookupString, [hInputContext], ebx, eax, 16, 0, 0

; here, .utg8buff contains the utf-8 string with the character typed on the keyboard.
        mov     eax, dword [.utf8buff]
        mov     [edi+TKeyboardEvent.key], eax

.scancode:
        mov     eax, [ebx+XKeyEvent.keycode]
        cinvoke XKeycodeToKeysym, [hApplicationDisplay], eax, 0
        mov     [edi+TKeyboardEvent.scancode], eax
        jmp     .exec_event

        exec    [__FocusedWindow], TWindow:EventKeyPress, dword [.utf8buff], eax, [ebx+XKeyEvent.state]
        jmp     .finish



;.........................................................................



.key_release:
        mov     ecx, seKbdKeyRelease
        mov     eax, [ebx+XKeyEvent.state]

        cmp     [__FocusedWindow], 0
        je      .finish

        mov     eax, [ebx+XKeyEvent.keycode]
        cinvoke XKeycodeToKeysym, [hApplicationDisplay], eax, 0

        mov     [edi+TKeyboardEvent.event], ecx
        mov     [edi+TKeyboardEvent.kbdStatus], eax
        mov     [edi+TKeyboardEvent.key], 0
        jmp     .scancode
        exec    [__FocusedWindow], TWindow:EventKeyRelease, eax, [ebx+XKeyEvent.state]
        jmp     .finish



; refreshes keyboard mapping information, stored locally in XLib.
.mapping_notify:
        cinvoke XRefreshKeyboardMapping, ebx
        jmp     .finish


;.........................................................................
; This event is sent from the window manager, when the user click on the close button of the
; window or close it some other way. So, the window have to decide whether to close or not.

.clientmessage:
        mov     eax, dword [ebx+XClientMessageEvent.data]
        cmp     eax, [atomWMDelete]
        jne     .finish

; The window is closed by click on close button or by pressing Alt+F4 or by other WM method
;.close_from_wm:
        mov     [edi+TCloseEvent.event], seCloseRequest
        mov     [edi+TCloseEvent.reason], cerFromUser
        jmp     .exec_event
endp

        exec    esi, TWindow:CloseRequest, cerFromUser
        jmp     .finish


; Focus handling events.

.focusin:
        call    .hide_menu

        stdcall __SearchWindowToFocus, esi

        mov     [__FocusedWindow], eax

        test    eax, eax
        jz      .finish

        exec    eax, TWindow:EventFocusIn
        jmp     .finish


proc __PaintWindow, .pWindow, .ptrBounds
.event TPaintEvent
.caret dd ?
begin
        pushad
.focusout:
        call    .hide_menu

        lea     edi, [.event]
        mov     esi, [.pWindow]
        xor     ebx, ebx
        xchg    [__FocusedWindow], ebx
        test    ebx, ebx
        jz      .finish

if defined Caret
        mov     [.caret], -1
        cmp     esi, [Caret.pWindow]
        jne     @f
        stdcall CaretShow, FALSE
        mov     [.caret], eax
@@:
end if
        mov     [edi+TPaintEvent.event], sePaint
        exec    ebx, TWindow:EventFocusOut
        jmp     .finish



.hideall:
        DebugMsg "Hide one menu"
        set     [__ActiveMenu], TWindow:Visible, FALSE

        stdcall AllocateContext, [esi+TWindow.handle]
        mov     ebx, eax
        mov     [edi+TPaintEvent.context], eax
.hide_menu:
        cmp     [__ActiveMenu], 0
        jne     .hideall

        retn

        xor     eax, eax
        mov     [edi+TPaintEvent.rect.left], eax
        mov     [edi+TPaintEvent.rect.top], eax
        mov     eax, $7fffffff
        mov     [edi+TPaintEvent.rect.right], eax
        mov     [edi+TPaintEvent.rect.bottom], eax

        mov     edx, [.ptrBounds]
        test    edx, edx
        jz      .rectok

.jump_table dd  0                   ; event 0
            dd  0                   ; event 1
            dd  .key_press              ; KeyPress = 2
            dd  .key_release            ; KeyRelease = 3
            dd  .mouse_btn_press        ; ButtonPress = 4
            dd  .mouse_btn_release      ; ButtonRelease = 5
            dd  .mousemove              ; MotionNotify = 6
            dd  0                       ; EnterNotify = 7
        mov     eax, [edx+TBounds.x]
        mov     ecx, [edx+TBounds.y]

        mov     [edi+TPaintEvent.rect.left], eax
        mov     [edi+TPaintEvent.rect.top], ecx

        mov     eax, [edx+TBounds.width]
        mov     ecx, [edx+TBounds.height]
        add     eax, [edi+TPaintEvent.rect.left]
        add     ecx, [edi+TPaintEvent.rect.top]
        mov     [edi+TPaintEvent.rect.right], eax
        mov     [edi+TPaintEvent.rect.bottom], ecx
            dd  0                       ; LeaveNotify = 8
            dd  .focusin                ; FocusIn = 9
            dd  .focusout               ; FocusOut = 10
            dd  0                       ; KeymapNotify = 11
            dd  .expose                 ; Expose = 12
            dd  0                       ; GraphicsExpose = 13
            dd  0                       ; NoExpose = 14
            dd  0                       ; VisibilityNotify = 15
            dd  0                       ; CreateNotify = 16
            dd  .destroy                ; DestroyNotify = 17
            dd  0                       ; UnmapNotify = 18
            dd  0                       ; MapNotify = 19
            dd  0                       ; MapRequest = 20
            dd  0                       ; ReparentNotify = 21
            dd  .moveresize             ; ConfigureNotify = 22
            dd  0                       ; ConfigureRequest = 23
            dd  0                       ; GravityNotify = 24
            dd  0                       ; ResizeRequest = 25
            dd  0                       ; CirculateNotify = 26
            dd  0                       ; CirculateRequest = 27
            dd  0                       ; PropertyNotify = 28
            dd  0                       ; SelectionClear = 29
            dd  0                       ; SelectionRequest = 30
            dd  0                       ; SelectionNotify = 31
            dd  0                       ; ColormapNotify = 32
            dd  .clientmessage          ; ClientMessage = 33
            dd  .mapping_notify         ; MappingNotify = 34
endp

.rectok:
        exec    esi, TWindow:SysEventHandler, edi

        stdcall ReleaseContext, ebx

if defined Caret
        cmp     [.caret], -1
        je      @f
        stdcall CaretShow, [.caret]
@@:
end if
        popad
        return
endp
Changes to freshlib/gui/Linux/TApplication.asm.
12
13
14
15
16
17
18
19
20


21
22
23


24

25




26











27






28
29
30
31
32
33





34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49


50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99















































100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
12
13
14
15
16
17
18


19
20
21


22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48





49
50
51
52
53
54
55
56





57
58






59
60
61

62
63















































64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

115
116
117


118
119
120
121
122
123
124







-
-
+
+

-
-
+
+

+
-
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+



-
-
-
-
-


-
-
-
-
-
-
+
+

-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+


-
-







;  Notes: TApplication by the idea is the base of GUI application, but the implementation
;         somehow need fixing...
;_________________________________________________________________________________________


uglobal
  if used hApplicationDisplay
    hApplicationDisplay dd ?
    hRootWindow         dd ?
    var hApplicationDisplay = ?
    var hRootWindow = ?

    hInputMethod        dd ?
    hInputContext       dd ?
    var hInputMethod = ?
    var hInputContext = ?

    var atomWMDelete = ?
    _SystemFont         dd ?

    var atomState = ?
    var atomStateAbove = ?
    var atomStateModal = ?

    var atomAllowedActions = ?
    var atomActionMove = ?
    var atomActionResize = ?
    var atomActionMinimize = ?
    var atomActionShade = ?
    var atomActionStick = ?
    var atomActionMaximizeHorz = ?
    var atomActionMaximizeVert = ?
    var atomActionFullscreen = ?
    var atomActionChangeDesktop = ?
    var atomActionClose = ?
    atomWMDelete        dd ?

    var atomWindowType = ?
    var atomWindowTypeMenu = ?
    var atomWindowTypeUtility = ?
    var atomWindowTypeDialog = ?
    var atomWindowTypeNormal = ?

    ShmCompletionEvent  dd ?
    FTLibrary           dd ?
    FTCManager          dd ?
    FTCImageCache       dd ?
    FTCCMapCache        dd ?
    var ShmCompletionEvent = ?
    var FTLibrary = ?
    var FTCManager = ?
    var FTCImageCache = ?
    var FTCCMapCache = ?
  end if
endg

;cDefaultFont text 'Tahoma-8'
cDefaultFont text 'Liberation Sans-9'
cDefaultFontSize = 9
;cDefaultFont text 'Ubuntu-9:rgba=rgb'
;cDefaultFont text 'Unifont-12' ; this one have unicode support;


; String constants needed for XLib
; Why, they needed so many strings????????????????? For arguments!??????????
_cWinDeleteName   text 'WM_DELETE_WINDOW'

XNVaNestedList                text "XNVaNestedList"
XNSeparatorofNestedList       text "separatorofNestedList"
;XNVaNestedList                text "XNVaNestedList"
;XNSeparatorofNestedList       text "separatorofNestedList"
XNQueryInputStyle             text "queryInputStyle"
XNClientWindow                text "clientWindow"
;XNClientWindow                text "clientWindow"
XNInputStyle                  text "inputStyle"
XNFocusWindow                 text "focusWindow"
XNResourceName                text "resourceName"
XNResourceClass               text "resourceClass"
XNGeometryCallback            text "geometryCallback"
XNDestroyCallback             text "destroyCallback"
XNFilterEvents                text "filterEvents"
XNPreeditStartCallback        text "preeditStartCallback"
XNPreeditDoneCallback         text "preeditDoneCallback"
XNPreeditDrawCallback         text "preeditDrawCallback"
XNPreeditCaretCallback        text "preeditCaretCallback"
XNPreeditStateNotifyCallback  text "preeditStateNotifyCallback"
XNPreeditAttributes           text "preeditAttributes"
XNStatusStartCallback         text "statusStartCallback"
XNStatusDoneCallback          text "statusDoneCallback"
XNStatusDrawCallback          text "statusDrawCallback"
XNStatusAttributes            text "statusAttributes"
XNArea                        text "area"
XNAreaNeeded                  text "areaNeeded"
XNSpotLocation                text "spotLocation"
XNColormap                    text "colorMap"
XNStdColormap                 text "stdColorMap"
XNForeground                  text "foreground"
XNBackground                  text "background"
XNBackgroundPixmap            text "backgroundPixmap"
XNFontSet                     text "fontSet"
XNLineSpace                   text "lineSpace"
XNCursor                      text "cursor"
XNQueryIMValuesList           text "queryIMValuesList"
XNQueryICValuesList           text "queryICValuesList"
XNStringConversionCallback    text "stringConversionCallback"
XNStringConversion            text "stringConversion"
XNResetState                  text "resetState"
XNHotKey                      text "hotkey"
XNHotKeyState                 text "hotkeyState"
XNPreeditState                text "preeditState"
XNVisiblePosition             text "visiblePosition"
XNR6PreeditCallbackBehavior   text "r6PreeditCallback"
XNRequiredCharSet             text "requiredCharSet"
XNQueryOrientation            text "queryOrientation"
XNDirectionalDependentDrawing text "directionalDependentDrawing"
XNContextualDrawing           text "contextualDrawing"
XNBaseFontName                text "baseFontName"
XNMissingCharSet              text "missingCharSet"
XNDefaultString               text "defaultString"
XNOrientation                 text "orientation"
XNFontInfo                    text "fontInfo"
XNOMAutomatic                 text "omAutomatic"
;XNFocusWindow                 text "focusWindow"
;XNResourceName                text "resourceName"
;XNResourceClass               text "resourceClass"
;XNGeometryCallback            text "geometryCallback"
;XNDestroyCallback             text "destroyCallback"
;XNFilterEvents                text "filterEvents"
;XNPreeditStartCallback        text "preeditStartCallback"
;XNPreeditDoneCallback         text "preeditDoneCallback"
;XNPreeditDrawCallback         text "preeditDrawCallback"
;XNPreeditCaretCallback        text "preeditCaretCallback"
;XNPreeditStateNotifyCallback  text "preeditStateNotifyCallback"
;XNPreeditAttributes           text "preeditAttributes"
;XNStatusStartCallback         text "statusStartCallback"
;XNStatusDoneCallback          text "statusDoneCallback"
;XNStatusDrawCallback          text "statusDrawCallback"
;XNStatusAttributes            text "statusAttributes"
;XNArea                        text "area"
;XNAreaNeeded                  text "areaNeeded"
;XNSpotLocation                text "spotLocation"
;XNColormap                    text "colorMap"
;XNStdColormap                 text "stdColorMap"
;XNForeground                  text "foreground"
;XNBackground                  text "background"
;XNBackgroundPixmap            text "backgroundPixmap"
;XNFontSet                     text "fontSet"
;XNLineSpace                   text "lineSpace"
;XNCursor                      text "cursor"
;XNQueryIMValuesList           text "queryIMValuesList"
;XNQueryICValuesList           text "queryICValuesList"
;XNStringConversionCallback    text "stringConversionCallback"
;XNStringConversion            text "stringConversion"
;XNResetState                  text "resetState"
;XNHotKey                      text "hotkey"
;XNHotKeyState                 text "hotkeyState"
;XNPreeditState                text "preeditState"
;XNVisiblePosition             text "visiblePosition"
;XNR6PreeditCallbackBehavior   text "r6PreeditCallback"
;XNRequiredCharSet             text "requiredCharSet"
;XNQueryOrientation            text "queryOrientation"
;XNDirectionalDependentDrawing text "directionalDependentDrawing"
;XNContextualDrawing           text "contextualDrawing"
;XNBaseFontName                text "baseFontName"
;XNMissingCharSet              text "missingCharSet"
;XNDefaultString               text "defaultString"
;XNOrientation                 text "orientation"
;XNFontInfo                    text "fontInfo"
;XNOMAutomatic                 text "omAutomatic"




method TApplication.Create
method TApplication.__create
.ptr dd ?
begin
        push    eax ecx edx

        cinvoke XInitThreads
        test    eax, eax
        jz      .exit_error

        cinvoke XSetErrorHandler, __FreshXErrorHandler

        mov     ecx, 5
155
156
157
158
159
160
161
162

163
164
165
166














































167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
164
165
166
167
168
169
170

171
172
173


174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245
246
247

248



249
250
251
252
253
254
255







-
+


-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
















-












-

-
-
-







        cinvoke XFree, [.ptr]

        stdcall InitMouseCursors

; Creating internal atoms that to be used with Window manager of the application windows...
; Maybe this code should reside somewhere else, not in application. In initialize TWindow???

        cinvoke XInternAtom, [hApplicationDisplay], _cWinDeleteName, 0
        cinvoke XInternAtom, [hApplicationDisplay], "WM_DELETE_WINDOW", 1
        mov     [atomWMDelete], eax

        cinvoke XftFontOpenName, [hApplicationDisplay], 0, cDefaultFont
        mov     [_SystemFont], eax
        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_STATE", 1
        mov     [atomState], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_STATE_ABOVE", 1
        mov     [atomStateAbove], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_STATE_MODAL", 1
        mov     [atomStateModal], eax

;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ALLOWED_ACTIONS", 1
;        mov     [atomAllowedActions], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_MOVE", 1
;        mov     [atomActionMove], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_RESIZE", 1
;        mov     [atomActionResize], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_MINIMIZE", 1
;        mov     [atomActionMinimize], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_SHADE", 1
;        mov     [atomActionShade], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_STICK", 1
;        mov     [atomActionStick], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_MAXIMIZE_HORZ", 1
;        mov     [atomActionMaximizeHorz], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_MAXIMIZE_VERT", 1
;        mov     [atomActionMaximizeVert], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_FULLSCREEN", 1
;        mov     [atomActionFullscreen], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_CHANGE_DESKTOP", 1
;        mov     [atomActionChangeDesktop], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_CLOSE", 1
;        mov     [atomActionClose], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE", 1
        mov     [atomWindowType], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE_POPUP_MENU", 1
        mov     [atomWindowTypeMenu], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE_UTILITY", 1
        mov     [atomWindowTypeUtility], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE_DIALOG", 1
        mov     [atomWindowTypeDialog], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE_NORMAL", 1
        mov     [atomWindowTypeNormal], eax


        cinvoke FT_Init_FreeType, FTLibrary
        test    eax, eax
        jnz     .error_ft

        cinvoke FTC_Manager_New, [FTLibrary], 0, 0, 0, FTCRequester, 0, FTCManager
        cinvoke FTC_ImageCache_New, [FTCManager], FTCImageCache
        cinvoke FTC_CMapCache_New, [FTCManager], FTCCMapCache

; clipboard initialization.
if __UseClipboard = 1
        stdcall   __InitLinuxClipboard
end if

        clc
        pop     edx ecx eax
        return

.error_ft:

        DebugMsg 'Error initializing FreeType library.'
        jmp      .exit_error

.error_disp:
        DebugMsg 'Error open display.'

.exit_error:
        stc
        pop     edx ecx eax
        return




endp



cXErrorMsg  text 'X server error:'
cXErrorMsg2 text 10, 0
Changes to freshlib/gui/Linux/mouse.asm.
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

iglobal
  if used _Xcursors
    _Xcursors db 68, 152, 34, 108, 116, 40, 40, 150   ; X standard cursor font
    _Xcursors db 68, 152, 34, 108, 116, 40, 40, 150, 58, 52, 86   ; X standard cursor font
  end if
endg


uglobal
  if used StockCursors
    StockCursors rd mcCount
58
59
60
61
62
63
64
65

66
67
68

69
70
71
72
73
74
75
76
77


78


79
80
81
82
83

84

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

58
59
60
61
62
63
64

65
66
67

68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105







-
+


-
+









+
+
-
+
+





+
-
+
















+

.exit:
        return
endp
end if


proc SetMouseCursor, .hCursor
proc SetMouseCursor, .hWindow, .hCursor
begin
        push    eax ecx edx
        cinvoke XDefineCursor, [hApplicationDisplay], [hRootWindow], [.hCursor]
        cinvoke XDefineCursor, [hApplicationDisplay], [.hWindow], [.hCursor]
        pop     edx ecx eax
        return
endp



proc GetStockCursor, .index
begin
        mov     eax, [.index]
        cmp     eax, mcCount
        jb      @f
        and     eax, 7
        xor     eax, eax
@@:
        mov     eax, [StockCursors+4*eax]
        return
endp



proc MouseCapture, .hwnd
proc __MouseCapture, .hwnd
begin
        push    eax ecx edx
        cmp     [.hwnd], 0
        je      .release

        cinvoke XGrabPointer, [hApplicationDisplay], [.hwnd], FALSE, PointerMotionMask or ButtonPressMask or ButtonReleaseMask, \
                              GrabModeAsync, GrabModeAsync, None, None, CurrentTime

.finish:
        pop     edx ecx eax
        return

.release:
        cinvoke XUngrabPointer, [hApplicationDisplay], CurrentTime
        jmp     .finish
endp

Changes to freshlib/gui/Linux/windows.asm.
9
10
11
12
13
14
15

16


17
18



19
20


21
22
23
24
25
26
27
28
29
30









31
32
33
34
35
36
37
38
39










40
41
42
43
44
45
46
47
48
49
50








51
52

53

54
55











56

57

58
59

60




61
62
63
64
65
66
67

68
69
70

71
72
73
74
75
76
77
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24

25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44









45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61




62
63
64
65
66
67
68
69
70

71
72
73


74
75
76
77
78
79
80
81
82
83
84
85
86

87
88

89
90
91
92
93
94
95
96
97
98
99
100

101
102
103

104
105
106
107
108
109
110
111







+
-
+
+


+
+
+

-
+
+



-






+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+







-
-
-
-
+
+
+
+
+
+
+
+

-
+

+
-
-
+
+
+
+
+
+
+
+
+
+
+

+
-
+

-
+

+
+
+
+






-
+


-
+







;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________



proc _CreateNullWindow
body _CreateWindow

.attr XSetWindowAttributes
.vis  XVisualInfo

.prop dd ?

begin
        push    ecx edx esi
        pushad
        mov     esi, [.pWindow]

        cinvoke XDefaultScreen, [hApplicationDisplay]
        mov     edx, eax

        lea     eax, [.vis]
        cinvoke XMatchVisualInfo, [hApplicationDisplay], edx, $20, TrueColor, eax

        cinvoke XCreateColormap, [hApplicationDisplay], [hRootWindow], [.vis.Visual], AllocNone
        mov     [.attr.colormap], eax

; border

        xor     eax, eax
        mov     ecx, [esi+TWindow._border]

        test    ecx, ecx        ; borderNone = 0
        jnz     @f
        inc     eax
@@:
        mov     [.attr.override_redirect], 0
        mov     [.attr.backing_store], NotUseful
        mov     [.attr.background_pixmap], None
        mov     eax, [clDialogBk]
        mov     [.attr.background_pixel], eax
        mov     [.attr.border_pixel], 0
        mov     [.attr.override_redirect], 0
        mov     [.attr.backing_store], NotUseful
        mov     [.attr.background_pixmap], None
        mov     [.attr.override_redirect], eax

        and     ecx, $3
        mov     eax, [.types+4*ecx]
        mov     [.prop], eax

        xor     eax, eax
        mov     [.attr.backing_store], eax              ; NotUseful
        mov     [.attr.background_pixmap], eax          ; None
        mov     [.attr.border_pixel], eax               ; 0
        mov     [.attr.event_mask], ExposureMask or FocusChangeMask or       \
                                    KeyPressMask or KeyReleaseMask or        \
                                    ButtonPressMask or ButtonReleaseMask or  \
                                    EnterWindowMask or LeaveWindowMask or    \
                                    PointerMotionMask or StructureNotifyMask

        lea     eax, [.attr]
        cinvoke XCreateWindow, [hApplicationDisplay], [hRootWindow], 0, 0, 1, 1, 0, $20, InputOutput, [.vis.Visual],       \
                               CWBackPixmap or CWBackingStore or CWOverrideRedirect or CWBorderPixel or          \
                               CWColormap or CWBackPixel or CWEventMask, eax
        mov     esi, eax
        cinvoke XCreateWindow, [hApplicationDisplay], [hRootWindow],                                            \
                               [esi+TWindow._x], [esi+TWindow._y], [esi+TWindow._width], [esi+TWindow._height], \
                               0, $20, InputOutput, [.vis.Visual],                                              \
                               CWBackingStore or CWOverrideRedirect or                                          \
                               CWBorderPixel or CWColormap or                                                   \
                               CWEventMask or CWBackPixmap, eax

        mov     edi, eax
        test    eax, eax
        jz      .exit
        jz      .exit           ; Error processing???

        cinvoke XChangeProperty, [hApplicationDisplay], edi, [atomWindowType], XA_ATOM, 32, PropModeReplace, [.prop], 1
        cinvoke XSetWMProtocols, [hApplicationDisplay], esi, atomWMDelete, 1
        mov     eax, esi
        cinvoke XSetWMProtocols, [hApplicationDisplay], edi, atomWMDelete, 1
        cinvoke XSaveContext,    [hApplicationDisplay], edi, win_structure_context, esi

; the caption
        mov     eax, [esi+TWindow._caption]
        test    eax, eax
        jz      .exit

        stdcall StrPtr, eax
        cinvoke XStoreName, [hApplicationDisplay], edi, eax

.exit:
        mov     [esp+4*regEAX], edi
        pop     esi edx ecx
        popad
        return
endp


.types  dd  atomWindowTypeMenu, atomWindowTypeNormal, atomWindowTypeDialog, atomWindowTypeUtility


endp


;_________________________________________________________________________________________



proc _DestroyWindow, .hwnd
body _DestroyWindow
begin
        push    eax ecx edx
        stdcall _SetWindowStruct, [.hwnd], 0
        cinvoke XSaveContext,   [hApplicationDisplay], [.hwnd], win_structure_context, 0
        cinvoke XDestroyWindow, [hApplicationDisplay], [.hwnd]
        pop     edx ecx eax
        return
endp



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

169
170
171
172



173
174
175


176
177

178
179

180
181



182


183
184
185
186




187
188
189




190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284

285
286
287

288












































289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

413
414
415
416
417

418
419


420
421
422
423
424
425
426
427
428
429
430
431
432
433








434
435
436
437
438
439
440
441
442
443

444
445
446
447
448
449
450
451
452
453
454
455
139
140
141
142
143
144
145








146














































147
148

149
150



151
152
153



154
155


156


157
158

159
160
161
162
163
164
165



166
167
168
169
170


171
172
173
174
175
176
177
178
179
180
181



































































182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

203
204
205

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259







260


















































































261
262
263
264
265


266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292


293
294
295
296
297
298
299
300








301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

318
319
320
321
322
323
324
325
326
327
328
329
330







-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
+

-
-
-
+
+
+
-
-
-
+
+
-
-
+
-
-
+

-
+
+
+

+
+

-
-
-
+
+
+
+

-
-
+
+
+
+







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+




















-
+


-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+




-
-


+

















-
+





+
-
-
+
+






-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+









-
+












endp



;_________________________________________________________________________________________


proc _GetChildren, .hwnd
  .root dd ?
  .parent dd ?
  .children dd ?
  .count    dd ?
begin
        push    ebx ecx edx esi

body _ClientToScreen

        lea     ebx, [.count]
        lea     edx, [.children]
        lea     ecx, [.parent]
        lea     eax, [.root]
        cinvoke XQueryTree, [hApplicationDisplay], [.hwnd], eax, ecx, edx, ebx
        test    eax, eax
        jz      .exit   ; function failed

        xor     ebx, ebx
        mov     esi, [.children]
        test    esi, esi
        jz      .endchildren

        stdcall CreateArray, sizeof.TWinArrayItem
        mov     ebx, eax
        mov     ecx, [.count]

.loophwnd:
        dec     ecx
        js      .endchildren_free

        stdcall AddArrayItems, ebx, 1
        mov     ebx, edx

        mov     edx, [esi+4*ecx]
        mov     [eax+TWinArrayItem.handle], edx

        jmp     .loophwnd

.endchildren_free:
        cinvoke XFree, esi

.endchildren:
        mov     eax, ebx
.exit:
        pop     esi edx ecx ebx
        return
endp


;_________________________________________________________________________________________



proc _GetVisible, .hwnd
.attr XWindowAttributes
begin
        push    ebx ecx edx
        push    eax

        lea     ebx, [.attr]
        cinvoke XGetWindowAttributes, [hApplicationDisplay], [.hwnd], ebx
        mov     eax, [ebx+XWindowAttributes.map_state]
        lea     ecx, [.attr]
        cinvoke XGetWindowAttributes, [hApplicationDisplay], [.hwnd], ecx

        test    eax, eax
        jz      @f
        mov     eax, 1
        mov     ecx, [.attr.x]
        mov     edx, [.attr.y]
@@:
        pop     edx ecx ebx
        add     [.x], ecx
        return
endp
        add     [.y], edx

;_________________________________________________________________________________________
        stdcall _GetParent, [.hwnd]
        test    eax, eax
        jz      .finish

        lea     ecx, [.attr]
        cinvoke XGetWindowAttributes, [hApplicationDisplay], eax, ecx

proc _GetWindowBounds, .hwnd, .pBounds
begin
        push    eax ecx edx
        mov     ecx, [.attr.x]
        mov     edx, [.attr.y]
        add     [.x], ecx
        add     [.y], edx

        int3
        pop     edx ecx eax
.finish:
        mov     ecx, [.x]
        mov     edx, [.y]
        pop     eax
        return
endp


;_________________________________________________________________________________________


proc _SetWindowBounds, .hwnd, .pBounds
  .wch XWindowChanges
begin
        push    eax ecx edx

        mov     edx, [.pBounds]

        mov     eax, [edx+TBounds.x]
        mov     ecx, [edx+TBounds.y]

        mov     [.wch.x], eax
        mov     [.wch.y], ecx

        mov     eax, [edx+TBounds.width]
        mov     ecx, [edx+TBounds.height]

        test    eax, eax
        jnz     @f
        inc     eax
@@:
        test    ecx, ecx
        jnz     @f
        inc     ecx
@@:
        mov     [.wch.width], eax
        mov     [.wch.height], ecx

        lea     eax, [.wch]
        cinvoke XConfigureWindow, [hApplicationDisplay], [.hwnd], CWX or CWY or CWWidth or CWHeight, eax

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________



proc _SetWindowBorder, .hwnd, .brdType
  .attr XSetWindowAttributes
begin
        push    eax ecx edx

        mov     [.attr.override_redirect], 1
;        mov     [.attr.event_mask], ExposureMask or FocusChangeMask or KeyPressMask or KeyReleaseMask or                \
;                                    ButtonPressMask or ButtonReleaseMask or EnterWindowMask or LeaveWindowMask or       \
;                                    PointerMotionMask

        cmp     [.brdType], borderNone
        je      @f
        mov     [.attr.override_redirect], 0
;        mov     [.attr.event_mask], ExposureMask or FocusChangeMask or KeyPressMask or KeyReleaseMask or                \
;                                    ButtonPressMask or ButtonReleaseMask or EnterWindowMask or LeaveWindowMask or       \
;                                    PointerMotionMask; or StructureNotifyMask
@@:
        lea     eax, [.attr]
        cinvoke XChangeWindowAttributes, [hApplicationDisplay], [.hwnd], CWOverrideRedirect, eax

        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________


proc _ShowWindow, .hwnd, .flag
body _ShowWindow
begin
        push    eax ecx edx

        mov     ecx, XUnmapWindow
        cmp     [.flag], 0
        je      @f
        mov     ecx, XMapWindow
@@:
        push    [.hwnd] [hApplicationDisplay]
        call    dword [ecx]
        add     esp, 8

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _RefreshWindow, .hwnd
body _RefreshWindowRect
begin
        push    eax ecx edx
        cinvoke XClearArea, [hApplicationDisplay], [.hwnd], 0, 0, 0, 0, TRUE
        cinvoke XClearArea, [hApplicationDisplay], [.hwnd], [.x], [.y], [.width], [.height], TRUE
        cinvoke XFlush, [hApplicationDisplay]
        pop     edx ecx eax
        return
endp


;body _RefreshWindowRect
;begin
;        push    eax ecx edx
;
;        stdcall _GetWindowStruct, [.hwnd]
;        get     eax, eax, TWindow:ImgScreen
;
;        stdcall DrawImageRect, [.hwnd], eax, [.x], [.y], [.x], [.y], [.width], [.height]
;        pop     edx ecx eax
;        return
;endp


;_________________________________________________________________________________________


body _SetWindowTextUtf8
begin
        push    eax ecx edx
        cinvoke XStoreName, [hApplicationDisplay], [.hwnd], [.ptrUtf8]
        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________


body _SetModalTowards
begin
        push    eax ecx edx


        cinvoke XSetTransientForHint, [hApplicationDisplay], [.hwnd], [.hwndParent]

; The following is not working for every window manager!!! It is not a problem of the below code. (probably... :)

        cinvoke XChangeProperty, [hApplicationDisplay], [.hwnd], [atomState], XA_ATOM, 32, PropModeAppend, atomStateAbove, 1
        cinvoke XChangeProperty, [hApplicationDisplay], [.hwnd], [atomState], XA_ATOM, 32, PropModeAppend, atomStateModal, 1

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _SetFocus, .hwnd
begin
        push    eax ecx edx
        cinvoke XSetInputFocus, [hApplicationDisplay], [.hwnd], RevertToParent, CurrentTime
        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________

proc _AddChild, .hwnd, .child
begin
        push    eax ecx edx
        cinvoke XReparentWindow, [hApplicationDisplay], [.child], [.hwnd], 10, 10
        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________


proc _SetWindowTextUtf8, .hwnd, .ptrUtf8
begin
        push    eax ecx edx
        cinvoke XStoreName, [hApplicationDisplay], [.hwnd], [.ptrUtf8]
        pop     edx ecx eax
        return
endp



;_________________________________________________________________________________________



proc _GetWindowTextUtf8, .hwnd, .ptrUtf8
begin
        return
endp




;_________________________________________________________________________________________

proc _EnableWindow, .hwnd, .flag
begin
        push    eax ecx edx

        stdcall _GetChildren, [.hwnd]
        test    eax, eax
        jz      .children_ok

        mov     edx, [eax+TArray.count]
.child_loop:
        dec     edx
        js      .end_children

        stdcall _EnableWindow, [eax+TArray.array+sizeof.TWinArrayItem*edx+TWinArrayItem.handle], [.flag]
        jmp     .child_loop

.end_children:
        stdcall FreeMem, eax

.children_ok:
        mov     ecx, ExposureMask or StructureNotifyMask or EnterWindowMask or LeaveWindowMask or PointerMotionMask
        cmp     [.flag], 0
        je      @f
        or      ecx, FocusChangeMask or KeyPressMask or KeyReleaseMask or    \
                     ButtonPressMask or ButtonReleaseMask
@@:
        cinvoke XSelectInput, [hApplicationDisplay], [.hwnd], ecx

        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________

proc _SetModalTowards, .hwnd, .hwndParent
begin
        push    eax ecx edx
        cinvoke XSetTransientForHint, [hApplicationDisplay], [.hwnd], [.hwndParent]
        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________

proc _FinalizeModal, .hwnd, .hwndParent
body _FinalizeModal
  .flushevent XEvent
begin
        push    eax ecx edx

        DebugMsg "Finalize modal"

; dirty hack, but the button receives LeaveNotify after DestroyNotify
        cinvoke XSync, [hApplicationDisplay], FALSE

.loop_flush:
        lea     eax, [.flushevent]
        cinvoke XCheckMaskEvent, [hApplicationDisplay], LeaveWindowMask, eax
        test    eax, eax
        jnz     .loop_flush

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


win_structure_context = 1


proc _GetWindowStruct, .hwin
body _GetWindowStruct
  .user_data dd ?
begin
        push    ecx edx
        lea     eax, [.user_data]
        cinvoke XFindContext, [hApplicationDisplay], [.hwin], win_structure_context, eax

        test    eax, eax
        jnz     .error
;        test    eax, eax
;        jnz     .error

        mov     eax, [.user_data]
        clc
        pop     edx ecx
        return

.error:
        DebugMsg 'FreshLib: Error find context.'
        mov      edx, [ebp+4]
        OutputRegister regEDX, 16

        xor      eax, eax
        pop      edx ecx
        return
;.error:
;        DebugMsg 'FreshLib: Error find context.'
;        mov      edx, [ebp+4]
;        OutputRegister regEDX, 16
;
;        stc
;        pop      edx ecx
;        return
endp




;_________________________________________________________________________________________



proc _SetWindowStruct, .hwin, .value
body _SetWindowStruct
begin
        push    eax ecx edx
        cinvoke XSaveContext, [hApplicationDisplay], [.hwin], win_structure_context, [.value]
        pop     edx ecx eax
        return
endp






Changes to freshlib/gui/Main.asm.
11
12
13
14
15
16
17
18
19
20







21

























22
23
24
25
26
27
28
11
12
13
14
15
16
17



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57







-
-
-
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







;
;  Notes: Organize the main message/event loop needed by every GUI engine.
;         This file contains only OS independent part and includes OS dependent files.
;_________________________________________________________________________________________
module "Main library"

uglobal
  if used pApplication
    pApplication dd ?
  end if
  var pApplication = ?

  var __LastPointedWindow = ?
  var __FocusedWindow = ?
  var __MouseTarget = ?

  var __ActiveMenu = ?
endg


;_________________________________________________________________________________________
;
; Process all the events queued from the system and exits.
; Arguments: none
; Returns: CF = 1 if the termination event has been received.
;_________________________________________________________________________________________

interface ProcessSystemEvents




;_________________________________________________________________________________________
;
; Waits for system events to arive.
; During the wait, the application
; does not use CPU resources.
;_________________________________________________________________________________________

interface WaitForSystemEvent





proc Run
begin
.mainloop:
        stdcall ProcessSystemEvents
        jc      .terminate
37
38
39
40
41
42
43

44
45
46
47









































48
49
50
51
52
53

54
55


56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

134
135

136
137
138
139
140
141
142
143







+




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






+


+
+




-


-
+







        stdcall ecx, eax

.eventok:
        stdcall WaitForSystemEvent
        jmp     .mainloop

.terminate:
        DebugMsg "Terminate GUI application!"
        return
endp



proc ServeMenuMouseMove, .window, .x, .y, .kbdState
begin
        cmp     [__ActiveMenu], 0
        jne     .serve_menu

        clc
        return

.serve_menu:
        pushad

        stdcall _ClientToScreen, [.window], [.x], [.y]
        exec    [__ActiveMenu], TWindow:EventMouseMove, ecx, edx, [.kbdState]

        popad
        stc
        return
endp



proc ServeMenuButtonPress, .window, .button, .kbdState, .x, .y
begin
        cmp     [__ActiveMenu], 0
        jne     .serve_menu

        clc
        return

.serve_menu:
        pushad

        stdcall _ClientToScreen, [.window], [.x], [.y]
        exec    [__ActiveMenu], TWindow:EventButtonPress, [.button], [.kbdState], ecx, edx

        popad
        stc
        return
endp



proc ShowModal, .pForm, .pParent
.prev dd ?
begin
        push    ecx edx

        mov     ecx, [.pParent]
        mov     edx, [.pForm]

        set     edx, TForm:Visible, TRUE

        jecxz   @f
        stdcall _SetModalTowards, [edx+TForm.handle], [ecx+TWindow.handle]
@@:
        set     edx, TForm:Visible, TRUE

        jecxz   @f
        stdcall _EnableWindow, [ecx+TWindow.handle], FALSE
        set     ecx, TWindow:Enabled, FALSE
@@:

        set     edx, TForm:ModalResult, 0

        get     eax, edx, TForm:OnClose
        mov     [.prev], eax

84
85
86
87
88
89
90
91

92
93
94
95
96
97
98

99
100
101

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119




















































































120
121
122
157
158
159
160
161
162
163

164
165
166
167

168
169

170
171

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278







-
+



-


-
+

-

+


















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




.vis_ok:
        stdcall WaitForSystemEvent
        jmp     .modal_loop

.exit_modal:
        jecxz   @f
        stdcall _EnableWindow, [ecx+TWindow.handle], TRUE
        set     ecx, TWindow:Enabled, TRUE
@@:

        set     edx, TForm:OnClose, [.prev]
        set     edx, TForm:Visible, FALSE

        jecxz   @f
        mov     ecx, [ecx+TWindow.handle]
        stdcall _FinalizeModal, [edx+TForm.handle], [ecx+TWindow.handle]
@@:
        stdcall _FinalizeModal, [edx+TForm.handle], ecx

        set     edx, TForm:Visible, FALSE
        get     eax, edx, TForm:ModalResult
        pop     edx ecx
        return
endp


; prevent destroy of the form from the close button or Alt+F4
proc __ModalOnClose, .self, .reason
begin
        set     [.self], TForm:ModalResult, mrCancel
        stc
        return
endp





proc __GetRelativeXY, .window, .x, .y
begin
        push    eax esi

        mov     ecx, [.x]
        mov     edx, [.y]
        mov     esi, [.window]

.loop:
        get     eax, esi, TWindow:Parent
        test    eax, eax
        jz      .finish

        sub     ecx, [esi+TWindow._x]
        sub     edx, [esi+TWindow._y]

        mov     esi, eax
        jmp     .loop

.finish:
        pop     esi eax
        return
endp



proc __SearchWindowToFocus, .pWindow
begin
        pushad
        mov     esi, [.pWindow]

        get     eax, esi, TWindow:Enabled
        test    eax, eax
        jz      .no

        get     eax, esi, TWindow:Visible
        test    eax, eax
        jz      .no

        get     eax, esi, TWindow:WantFocus
        test    eax, eax
        jz      .children

        mov     [esp+4*regEAX], esi
        popad
        return


.children:
        get     edi, esi, TWindow:Children
        test    edi, edi
        jnz     .loopit

.no:
        xor     eax, eax
        mov     [esp+4*regEAX], eax
        popad
        return

.loopit:
        mov     ecx, [edi+TArray.count]
        jecxz   .no

.children_loop:
        dec     ecx
        js      .no

        mov     esi, [edi+TArray.array+4*ecx]

        istype  esi, TWindow
        jne     .children_loop

        stdcall __SearchWindowToFocus, esi
        test    eax, eax
        jz      .children_loop

        mov     [esp+4*regEAX], eax
        popad
        return
endp




include '%TargetOS%/Main.asm'

endmodule
Changes to freshlib/gui/ObjTemplates.asm.
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50













51
52

53


54
55
56
57
58














59
60
61
62
63
64
65
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67





68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88







-
+















+

-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+


+

+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  .vtable    dd  ?         ; pointer to the virtual methods table.
  .paramsize dd  ?
  .ptrVar    dd  ?
  .params:
ends


macro ObjTemplate  flags, class, name, [id, param] {
macro ObjTemplate  flags, class, name, [idparam] {
common
local ..paramsize, ..prms, ..here

   if ~defined used.#class | defined ..here
     used.#class = 1
     ..here = 1
   end if

      dd  flags
      dd  sizeof.#class
      dd  vtables.#class
      dd  ..paramsize
      dd  name

..prms:

forward
local ..value
      dd  class#.#id#.#set
      dd  ..value
local ..value, ..ofs, ..valid

  ..valid equ FALSE
  match  id == param, idparam \{
    ..ofs dd  class\#.\#id\#.#set
          dd  ..value
    ..valid EQU TRUE
  \}

  match =FALSE, ..valid \{
    error Invalid parameter definition in template.
  \}

common
      dd  -1

forward

    match  id == param, idparam \{
  if param eqtype 2
    ..value = param
  else
    ..value db param, 0
  end if
      if param eqtype 2
        ..value = param
      else
        if param eqtype [2]
           match =[par=], param \\{
           ..value = par
        \\}
          store byte $fe at ..ofs+3
        else
          ..value db param, 0
        end if
      end if
    \}

common
local ..here

    if ~defined name | defined ..here
      name dd ?
      ..here = 1
    end if
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116










117


118
119
120
121

122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

152
153

154
155
156
157
158
159
160
109
110
111
112
113
114
115

116
117















118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138


139
140
141
142


143
144
145
146
147
148
149
150
151
152
153
154
155
156
157






158
159
160
161
162
163
164

165
166
167
168
169
170
171
172







-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







+
+
+
+
+
+
+
+
+
+
-
+
+


-
-
+



-
-
+














-
-
-
-
-
-





+

-
+








.createloop:
        stdcall GetMem, [esi+TObjTemplate.size]
        mov     ebx, eax
        mov     edi, [esi+TObjTemplate.vtable]
        mov     [ebx], edi

        exec    ebx, TObject:Create
        exec    ebx, TWindow:Create, [.parent]

        cmp     [.parent], 0
        je      .parent_ok

        exec    [.parent], TObject:AddChild, ebx

.parent_ok:
        istype  ebx, TWindow
        jne     .border_ok

        cmp     [.parent], 0
        jne     .border_ok

        set     ebx, TWindow:borderKind, borderFull

.border_ok:
        lea     ecx, [esi+TObjTemplate.params]

.paramloop:
        cmp     dword [ecx], -1
        je      .paramsok

        mov     eax, [ecx]
        bswap   eax

        mov     edx, [ecx+4]            ; value

        cmp     al, $fe                 ; Is it indirect?
        jne     @f
        mov     edx, [edx]              ; the value is an address of a variable.
@@:
        bswap   eax

        test    eax, $ffff0000
        test    eax, $00ff0000
        movzx   eax, ax                 ; not changing flags!
        jnz     .method

        push    dword [ecx+4]
        pop     dword [ebx+eax]
        mov     [ebx+eax], edx
        jmp     .param_set

.method:
        and     eax, $0000ffff
        stdcall dword [edi+4*eax+8], ebx, [ecx+4]
        stdcall dword [edi+4*eax+8], ebx, edx

.param_set:
        add     ecx, 8
        jmp     .paramloop

.paramsok:
        mov     eax, [esi+TObjTemplate.ptrVar]
        test    eax, eax
        jz      .var_ok

        mov     [eax], ebx      ; returned pointer/handle to the object.
        set     ebx, TObject:ptrVar, eax

.var_ok:
        istype  ebx, TWindow
        jne     .oncreate

        exec    ebx, TWindow:UpdateBounds

.oncreate:
        get     eax, ebx, TObject:OnCreate
        test    eax, eax
        jz      .gonext

; execute user OnCreate event.

        pushad
        stdcall dword [ebx+TObject.OnCreate], ebx
        stdcall eax, ebx
        popad

.gonext:
        mov     edx, [esi+TObjTemplate.flags]

        mov     eax, sizeof.TObjTemplate
        add     eax, [esi+TObjTemplate.paramsize]
Changes to freshlib/gui/SplitGrid.asm.
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78







+










-
+










+







struct TSplitTemplate
  .type  dw ?
  .width dw ?
  .pos   dd ?
  .min   dd ?
  .max   dd ?
ends


struct TCellTemplate
  .type  dw ?
  .id    dw ?
ends


macro SplitStart name {
  local ..expected, ..id
  ..expected = 1
  ..id = 1000
  ..id = 0

  cell@expected equ ..expected
  cell@id equ ..id
  cell@name equ name

  label name byte

  macro Split type, width, pos, min, max \{
    dw type, width
    dd pos, min, max
    cell@id = cell@id + 1
    cell@expected = cell@expected + 1
  \}

  macro Cell name \{
    .\#name = cell@id
    dw stNone, cell@id
    cell@id = cell@id + 1
123
124
125
126
127
128
129




130
131
132
133
134
135



136
137
138
139





140
141
142
143
144
145
146
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160







+
+
+
+






+
+
+




+
+
+
+
+







  end repeat

  if ..expected <> 0
    disp 1, 'WARNING! "', `., '" split template is not consistent! Automatically added  ', <..expected, 10>, " empty cells. FIXIT!", 13
  end if
}

uglobal
  RealignCnt dd ?
endg


proc RealignGrid, .ptrSplitter, .ptrRect
.rect RECT
begin
        pushad

        stdcall GetTimestamp
        mov     [RealignCnt], eax

        mov     edi, [.ptrSplitter]
        mov     esi, [.ptrRect]
        call    _DoRealign

        stdcall GetTimestamp
        sub     eax, [RealignCnt]

        OutputValue "Realign time:", eax, 10, 4

        popad
        return
endp


; edi is pointer to the current TSplitRect
; esi is pointer to the rect that have to be assigned to the current TSplitRect
188
189
190
191
192
193
194









195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224







+
+
+
+
+
+
+
+
+








        mov     ebx, [esi+ecx+TSplitRect.rect.right]
        sub     ebx, [esi+ecx+TSplitRect.rect.left]     ; size of rect (x or y depending on type)
        mov     edx, [esi+TSplitRect.spWidth]
        sub     ebx, edx

        mov     eax, [esi+TSplitRect.pos]

        cmp     eax, [esi+TSplitRect.min]
        cmovl   eax, [esi+TSplitRect.min]

        cmp     eax, [esi+TSplitRect.max]
        cmovg   eax, [esi+TSplitRect.max]

        mov     [esi+TSplitRect.pos],eax


        mov     ecx, [esi+TSplitRect.type]
        and     ecx, $ff

        test    [esi+TSplitRect.type], stRelative
        jz      .posready

229
230
231
232
233
234
235
236
237



238
239
240












241
242
243
244
245
246
247
248
249









250
251

252
253
254
255
256
257
258
259
260

261
262
263
264

265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
252
253
254
255
256
257
258


259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276









277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
295

296
297
298
299

300
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315







-
-
+
+
+



+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
+








-
+



-
+







-
+








        lea     esi, [.rect2]
        call _DoRealign

        pop     esi

.endsplit:
        cmp     [esi+TSplitRect.pWindow], 0
        je      .endresize
        mov     ebx, [esi+TSplitRect.pWindow]
        test    ebx, ebx
        jz      .endresize

        mov     eax, [esi+TSplitRect.rect.right]
        mov     ecx, [esi+TSplitRect.rect.bottom]
        sub     eax, [esi+TSplitRect.rect.left]
        sub     ecx, [esi+TSplitRect.rect.top]

        mov     [ebx+TWindow._width], eax
        mov     [ebx+TWindow._height], ecx

        mov     eax, [esi+TSplitRect.rect.left]
        mov     ecx, [esi+TSplitRect.rect.top]

        mov     [ebx+TWindow._x], eax
        mov     [ebx+TWindow._y], ecx

        mov     ebx, [esi+TSplitRect.rect.left]
        mov     edx, [esi+TSplitRect.rect.top]
        sub     eax, ebx
        sub     ecx, edx

        set     [esi+TSplitRect.pWindow], TWindow:width, eax
        set     [esi+TSplitRect.pWindow], TWindow:height, ecx
        set     [esi+TSplitRect.pWindow], TWindow:x, ebx
        set     [esi+TSplitRect.pWindow], TWindow:y, edx
;        mov     ebx, [esi+TSplitRect.rect.left]
;        mov     edx, [esi+TSplitRect.rect.top]
;        sub     eax, ebx
;        sub     ecx, edx
;
;        set     [esi+TSplitRect.pWindow], TWindow:width, eax
;        set     [esi+TSplitRect.pWindow], TWindow:height, ecx
;        set     [esi+TSplitRect.pWindow], TWindow:x, ebx
;        set     [esi+TSplitRect.pWindow], TWindow:y, edx

        exec    [esi+TSplitRect.pWindow], TWindow:UpdateBounds
;        exec    [esi+TSplitRect.pWindow], TWindow:UpdateBounds
        exec    [esi+TSplitRect.pWindow], TWindow:Refresh

.endresize:
        return
endp



proc DrawSplitters, .context, .ptrSplitters
proc DrawSplitters, .pImage, .ptrSplitters
begin
        pushad
        mov     esi, [.ptrSplitters]
        mov     edi, [.context]
        mov     edi, [.pImage]
        call    _DoDrawSplitters
        popad
        return
endp


;esi - pointer to TSplitRect
; edi - hDC
; edi - TImage

proc _DoDrawSplitters
begin
        mov     ebx, esi
        add     esi, sizeof.TSplitRect

        test    [ebx+TSplitRect.type], stNone
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
467
468
469
470
471
472
473
474









































475








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

        popad
        return
endp





proc DrawSplitterDefault, .context, .pRect, .type
begin
        pushad

        mov     esi, [.pRect]
        mov     eax, [esi+RECT.right]
        mov     ecx, [esi+RECT.bottom]
        sub     eax, [esi+RECT.left]
        sub     ecx, [esi+RECT.top]

        stdcall DrawFillRect, [.context], [esi+RECT.left], [esi+RECT.top], eax, ecx, [clSplitter]
        popad
        return
endp


proc DrawSplitterDefault2, .context, .pRect, .type
.bounds TBounds
begin
        pushad

        mov     esi, [.pRect]
        mov     eax, [esi+RECT.left]
        mov     ecx, [esi+RECT.top]
        mov     edx, [esi+RECT.right]
        mov     ebx, [esi+RECT.bottom]
        sub     edx, eax
        sub     ebx, ecx
        mov     [.bounds.x], eax
        mov     [.bounds.y], ecx
        mov     [.bounds.width], edx
        mov     [.bounds.height], ebx
        lea     eax, [.bounds]

        stdcall [DrawBox], [.context], eax, [clDialogBk], bxSunken

        popad
        return
endp


endmodule
Changes to freshlib/gui/TAction.asm.
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
30



31
32
33

34
35
36
37
38
39

40
41
42
43

44
45
46
47



48
49
50
51

52





53
54
55
56
57
58
59
60
61








































































































62
63
64





































































































65


66


67



68
69
70
71

































































































72
73
74
75
76
77
78
79






































































































12
13
14
15
16
17
18


19










20
21
22



23
24





25




26
27



28
29
30

31
32
33
34
35
36
37
38
39
40









41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145


146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

250
251
252
253
254
255




256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353







354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455







-
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+

-
-
-
-
-
+
-
-
-
-
+

-
-
-
+
+
+
-



+

+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
-
+
+

+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
;  Notes: "Action" is set of executable code, combined with user interface attributes -
;         caption, accelerator keys, enable/disable status flag etc.
;         Different UI elements, such as buttons, menu items etc. can be attached to
;         the action object and to use its attributes. When the programmer changes
;         something in the action, all UI elements are updated automatically.
;_________________________________________________________________________________________

struc TAction caption, hint, icon, FastKey, enabled, OnExecute, OnIdle {
common
module "TAction"
  .Text      dd  caption    ; handle or pointer to the caption string.
  .Hint      dd  hint       ; handle or pointer to the Hint text.
  .icon      dd  icon       ; pointer to TImage
  .FastKey   dd  FastKey    ; pointer to keyboard accelerator combination.
  .Enabled   dd  enabled    ; if FALSE, the action is not active.
  .OnExecute dd  OnExecute  ; pointer to procedure to be executed on activation of the action.
  .OnIdle    dd  OnIdle     ; pointer to procedure that to be executed once, when there is no other events in the queue.
}

virtual at 0

Ctrl = maskCtrl
Alt = maskAlt
  TAction TAction ?, ?, ?, ?, ?, ?, ?
end virtual

Shift = maskShift

struc TFastKey flags, key, action {
  .flags  dd flags
  .key    dd key
  .action dd action
}

virtual at 0
  TFastKey TFastKey ?, ?, ?
end virtual

fkScancode = $80000000

struct TActionList
  .count dd ?
  .accelerators dd ?
struct TFastKey
 .flags  dd ?
 .key    dd ?
  .actions:
ends


object TAction, TObject

  ._caption    dd ?
  ._hint_text  dd ?
  ._icon_index dd ?
  ._enabled    dd ?
  ._checked    dd ?
macro ActionList name, [actname, caption, hint, icon, FastKey, OnExecute, OnIdle] {
common
  local i, count, acclist
  i = 0
  label name dword
  .count dd count
  .accelerators dd acclist
forward
  local .accitem, txtlbl, hintlbl

  ._accel      TFastKey

  ._on_execute dd ?
  ._on_idle    dd ?

  ._ctrl_list  dd ?

  ._icon_cache_gray  dd ?
  ._icon_cache       dd ?

  param .Caption,   ._caption,    .SetCaption
  param .HintText,  ._hint_text,  .SetHintText
  param .IconIndex, ._icon_index, .SetIconIndex
  param .Enabled,   ._enabled,    .SetEnabled
  param .Checked,   ._checked,    .SetChecked
  param .AccelStr,  .GetAccelStr, NONE
  param .Icon, .GetIcon, NONE

  param .OnExecute, ._on_execute, ._on_execute
  param .OnIdle,    ._on_idle,    ._on_idle

  method .GetIcon
  method .GetAccelStr

  method .SetParent, .value

  method .SetCaption, .value
  method .SetHintText, .value
  method .SetIconIndex, .value
  method .SetEnabled, .value
  method .SetChecked, .value

  method .UpdateControls

  method .SetAccelerator, .flags, .key

  method .Execute, .fromCtrl
  method .Attach,  .ctrl
  method .Detach,  .ctrl

  method .Create, .parent
  method .Destroy

  method .__clear_cache

endobj



interface TAction.OnExecute, .Action, .Ctrl



method TAction.Create
begin
        inherited [.parent]

        mov     eax, [.self]
        mov     [eax+TAction._enabled], 1
        return
endp




method TAction.Destroy
begin
        pushad

        mov     esi, [.self]
        exec    esi, TAction:__clear_cache

        mov     edi, [esi+TAction._ctrl_list]
        test    edi, edi
        je      .finish

        mov     ecx, [edi+TArray.count]

.loop:
        dec     ecx
        js      .end_loop

        set     [edi+TArray.array+4*ecx], TWindow:Action, 0
        jmp     .loop

.end_loop:
        stdcall FreeMem, edi


.finish:
        popad
        inherited
        return
endp



method TAction.SetParent
begin
        inherited [.value]
        exec      [.self], TAction:UpdateControls
        return
endp

  txtlbl text caption
  hintlbl text hint


method TAction.Execute
begin
        pushad

        mov     esi, [.self]

        cmp     [esi+TAction._enabled], 0
        je      .finish

        mov     edi, [esi+TAction._on_execute]
        test    edi, edi
        jz      .finish

        stdcall edi, esi, [.fromCtrl]

.finish:
        popad
        return
endp




method TAction.Attach
begin
        pushad

        mov     esi, [.self]
        mov     edx, [esi+TAction._ctrl_list]
        test    edx, edx
        jnz     @f

        stdcall CreateArray, 4
        mov     edx, eax
@@:

        stdcall AddArrayItems, edx, 1
        mov     ecx, [.ctrl]
        mov     [eax], ecx

        mov     [esi+TAction._ctrl_list], edx

        popad
        return
endp




method TAction.Detach
begin
        pushad

        mov     esi, [.self]
        mov     edx, [esi+TAction._ctrl_list]
        test    edx, edx
        jz      .finish

        stdcall ListIndexOf, edx, [.ctrl]
        jc      .finish                         ; not found

        stdcall DeleteArrayItems, edx, eax, 1

        cmp     [edx+TArray.count], 0
        jne     @f

        stdcall FreeMem, edx
        xor     edx, edx

@@:
        mov     [esi+TAction._ctrl_list], edx

.finish:
        popad
        return
endp




method TAction.GetIcon
.list dd ?
begin
        pushad
        mov     esi, [.self]

        mov     edi, [esi+TAction._enabled]
        and     edi, 1

        mov     eax, [esi+TAction._icon_cache_gray+4*edi]
        test    eax, eax
        jnz     .finish

        mov     edx, [esi+TAction._icon_index]
        test    edx, edx
        js      .finish         ; return 0

        get     [.list], esi, TAction:Parent
        get     ecx, [.list], TActionList:IconSize

        stdcall CreateImage, ecx, ecx
        mov     [esi+TAction._icon_cache_gray+4*edi], eax
  actname TAction txtlbl, hintlbl, icon, accitem, 1, OnExecute, OnIdle

        imul    edx, ecx                                ; x coordinate.

        get     ebx, [.list], TActionList:ImgIcons
        test    ebx, ebx
        jz      .finish
  i = i + 1
common
  count = i
  label acclist dword

        stdcall CopyImageRect, eax, 0, 0, ebx, edx, 0, ecx, ecx
        test    edi, edi
        jnz     .finish

        stdcall FilterDisabled, eax, FALSE

.finish:
        mov     [esp+regEAX*4], eax
        popad
        return
endp


method TAction.GetAccelStr
begin
        mov     eax, [.self]
        lea     eax, [eax+TAction._accel]
        stdcall AcceleratorToStr, eax
        return
endp



method TAction.__clear_cache
begin
        push    eax edx

        mov     edx, [.self]

        xor     eax, eax
        xchg    eax, [edx+TAction._icon_cache]
        test    eax, eax
        jz      .cache_ok1

        stdcall DestroyImage, eax

.cache_ok1:
        xor     eax, eax
        xchg    eax, [edx+TAction._icon_cache_gray]
        test    eax, eax
        jz      .cache_ok2

        stdcall DestroyImage, eax

.cache_ok2:

        pop     edx eax
        return
endp



method TAction.UpdateControls
begin
        push    eax ecx edx

        mov     edx, [.self]

        exec    edx, TAction:__clear_cache

        mov     edx, [edx+TAction._ctrl_list]
        test    edx, edx
        jz      .finish

        mov     ecx, [edx+TArray.count]

.loop:
        dec     ecx
        js      .finish

        exec    [edx+TArray.array+4*ecx], TWindow:UpdateAction, [.self]
        jmp     .loop

.finish:
        pop     edx ecx eax
        return
endp




method TAction.SetCaption      ;, .value
begin
        pushad
        mov     esi, [.self]
        mov     eax, [.value]
        cmp     eax, [esi+TAction._caption]
        je      .finish

        mov     [esi+TAction._caption], eax
        exec    esi, TAction:UpdateControls

.finish:
        popad
        return
endp

forward
  if FastKey eq NONE
    accitem = 0
  else
    .accitem TFastKey FastKey, name#actname
  end if
}


method TAction.SetHintText     ;, .value
begin
        pushad
        mov     esi, [.self]
        mov     eax, [.value]
        cmp     eax, [esi+TAction._hint_text]
        je      .finish

        mov     [esi+TAction._hint_text], eax
        exec    esi, TAction:UpdateControls

.finish:
        popad
        return
endp



method TAction.SetIconIndex    ;, .value
begin
        pushad
        mov     esi, [.self]
        mov     eax, [.value]
        cmp     eax, [esi+TAction._icon_index]
        je      .finish

        mov     [esi+TAction._icon_index], eax
        exec    esi, TAction:UpdateControls

.finish:
        popad
        return
endp



method TAction.SetEnabled      ;, .value
begin
        pushad
        mov     esi, [.self]
        mov     eax, [.value]
        cmp     eax, [esi+TAction._enabled]
        je      .finish

        mov     [esi+TAction._enabled], eax
        exec    esi, TAction:UpdateControls

.finish:
        popad
        return
endp



method TAction.SetChecked      ;, .value
begin
        pushad
        mov     esi, [.self]
        mov     eax, [.value]
        cmp     eax, [esi+TAction._checked]
        je      .finish

        mov     [esi+TAction._checked], eax

        exec    esi, TAction:UpdateControls

.finish:
        popad
        return
endp



method TAction.SetAccelerator
begin
        pushad

        mov     esi, [.self]

        mov     eax, [.flags]
        mov     ecx, [.key]

        test    eax, fkScancode
        jz      @f

        or      ecx, fkScancode

@@:
        and     eax, not fkScancode
        mov     [esi+TAction._accel.flags], eax
        mov     [esi+TAction._accel.key], ecx

        exec    esi, TAction:UpdateControls

        popad
        return
endp


endmodule
Added freshlib/gui/TActionList.asm.






















































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Actions management library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: TActionList is set of TAction that provides some common functionality
;         for example the common icons. It is implemented as a parent object for
;         several TAction objects.
;_________________________________________________________________________________________

module "TActionList"


object TActionList, TObject

  ._img_icons dd ?
  ._icon_size  dd ?

  param .ImgIcons, ._img_icons, .SetIcons
  param .IconSize, ._icon_size, .SetIconSize

  method .Create, .parent

  method .SetIcons, .value
  method .SetIconSize, .value

  method .UpdateActions

endobj



method TActionList.Create
begin
        inherited [.parent]
        set     [.self], TActionList:IconSize, 16
        return
endp


method TActionList.SetIconSize
begin
        push    eax ecx

        mov     ecx, [.self]
        mov     eax, [.value]
        xchg    eax, [ecx+TActionList._icon_size]
        cmp     eax, [ecx+TActionList._icon_size]
        je      .finish

        exec    ecx, TActionList:UpdateActions

.finish:
        pop     ecx eax
        return
endp



method TActionList.UpdateActions
begin
        pushad

        get     edx, [.self], TActionList:Children
        test    edx, edx
        jz      .finish

        mov     ecx, [edx+TArray.count]

.loop:
        dec     ecx
        js      .finish

        exec    [edx+TArray.array+4*ecx], TAction:UpdateControls
        jmp     .loop

.finish:
        popad
        return
endp



method TActionList.SetIcons
begin
        pushad

; the .value parameter points to a PNG image in the memory.
        mov     esi, [.self]

        get     ecx, esi, TActionList:ImgIcons
        jecxz   .old_ok

        stdcall DestroyImage, ecx

.old_ok:
        mov     eax, [.value]
        test    eax, eax
        jz      .new_ok

        stdcall CreateImagePNG, eax, [eax-4]

.new_ok:
        mov     [esi+TActionList._img_icons], eax

        exec    [.self], TActionList:UpdateActions
        popad
        return
endp


endmodule
Changes to freshlib/gui/TApplication.asm.
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30


31



32




















33
34
35
36
37
38
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64







+








+
+

+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








; The root object in the application.
; every other object will be child on the TApplication.MainWindow.
; only one instance of TApplication should be created.
;
object TApplication, TObject

  .FMainWindow   dd ?
  .FAccelerators dd ?
  .FOnIdle       dd ?

  param .MainWindow, .FMainWindow, .FMainWindow
  param .Accelerators, .FAccelerators, .FAccelerators
  param .OnIdle, .FOnIdle, .FOnIdle

  method .__create      ; OS dependent create handler.

  method .Create

  method .ProcessIdle   ; calls all TAction idle handlers if any.

endobj



method TApplication.Create
begin
        inherited 0     ; no parent for the application!
        exec    [.self], TApplication:__create
        return
endp




method TApplication.ProcessIdle
begin


        return
endp



include '%TargetOS%/TApplication.asm'


endmodule
Changes to freshlib/gui/TButton.asm.
10
11
12
13
14
15
16
17
18
19
20
21







22

23





24
25
26



27



28
29
30
31
32
33
34


35
36
37
38
39
40




41
42




43
44
45
46




47











48
49
50
51
52




































































































































































































































































































































































53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
10
11
12
13
14
15
16





17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42

43
44
45
46
47
48
49
50
51



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463







-
-
-
-
-
+
+
+
+
+
+
+

+

+
+
+
+
+



+
+
+
-
+
+
+


-




+
+



-
-
-
+
+
+
+


+
+
+
+




+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+





+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+














+







;  Dependencies:
;
;  Notes: Represents GUI button.
;_________________________________________________________________________________________
module "TButton library"


; Button states for the field TButton.state
btnNormal    = 0
btnPressed   = 1
btnPointed   = 2
btnChecked   = 3
; Button states for the field TButton._state

bsNeutral    = 0
bsHovered    = 1
bsPressed    = 2

bsDisabled   = 3

; icon positions

iposLeft   = 0
iposRight  = 1
iposTop    = 2
iposBottom = 3
iposCenter = 4


object TButton, TWindow

; private fields

  .state      dd ?
  ._state      dd ?      ; internal state variable.

  ._textalign dd ?
  ._icon      dd ?
  ._iconpos   dd ?
  ._textalign dd ?

  ._OnClick   dd ?

  ._ModalResult dd ?

; parameters

  param .OnClick, ._OnClick, ._OnClick

  param .TextAlign, ._textalign, .SetTextAlign
  param .Icon,      ._icon, .SetIcon
  param .IconPosition, ._iconpos, .SetIconPos
  param .TextAlign,    ._textalign,  .SetTextAlign
  param .Icon,         ._icon,       .SetIcon
  param .IconPosition, ._iconpos,    .SetIconPos

  param .ModalResult, ._ModalResult, ._ModalResult

; methods

  ; parameters handling methods

  method .SetTextAlign, .value
  method .SetIcon, .value
  method .SetIconPos, .value

  ; system events methods

  method .Create, .Parent

  method .SysEventHandler, .pEvent
  method .Paint

  method .EventMouseEnter
  method .EventMouseLeave

  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventButtonRelease, .button, .kbdState, .x, .y

  method .EventKeyPress, .utf8, .scancode, .kbdState
  method .EventKeyRelease, .scancode, .kbdState

endobj


interface TButton.OnClick, .self, .button




; new


method TButton.Create
begin
        inherited [.Parent]

        mov     eax, [.self]
        mov     [eax+TButton._cursor], mcHand
        mov     [eax+TButton.__want_focus], TRUE

        return
endp





method TButton.Paint

 .bounds TBounds
 .clTxt dd ?
 .canvas dd ?

 .caption dd ?
 .enabled dd ?
 .icon    dd ?

begin
        pushad

        mov     esi, [.self]

        get     edx, esi, TButton:Action
        test    edx, edx
        jz      .get_normal

        get     [.caption], edx, TAction:Caption
        get     [.icon],    edx, TAction:Icon
        jmp     .get_enabled

.get_normal:

        get     [.caption], esi, TButton:Caption
        get     [.icon], esi, TButton:Icon

.get_enabled:
        get     [.enabled], esi, TButton:Enabled        ; it will return the TAction:Enabled if attached.

.paint_it:
        get     eax, esi, TWindow:Canvas
        mov     [.canvas], eax

        mov     eax, [esi+TButton._state]
        cmp     [.enabled], 0
        jne     .state_ok

        mov     eax, bsDisabled

.state_ok:
        mov     edi, [GUI.clBtnBk+4*eax]           ; background color
        mov     ecx, [GUI.clBtnTxt+4*eax]          ; text color
        mov     edx, [GUI.btnBorder+4*eax]
        cmp     [.enabled], 0
        jne     .border_ok

        or      edx, bxDisabled

.border_ok:
        mov     [.clTxt], ecx

        mov     ecx, [esi+TButton._width]
        mov     eax, [esi+TButton._height]

        mov     [.bounds.x], 0
        mov     [.bounds.y], 0
        mov     [.bounds.width], ecx
        mov     [.bounds.height], eax
        lea     eax, [.bounds]



        stdcall [DrawBox], [.canvas], eax, edi, edx, [GUI.boxBorderWidth]

; first draw the icon and then resize bounds for the text.

        mov     ebx, [GUI.btnMarginX]
        mov     edx, [GUI.btnMarginY]

        add     [.bounds.x], ebx
        add     [.bounds.y], edx
        sub     [.bounds.width], ebx
        sub     [.bounds.height], edx
        sub     [.bounds.width], ebx
        sub     [.bounds.height], edx


        mov     edi, [.icon]
        test    edi, edi
        jz      .draw_text

        cmp     [esi+TButton._iconpos], iposCenter
        jne     @f

        mov     eax, [.bounds.width]
        sub     eax, [edi+TImage.width]
        sar     eax, 1
        add     eax, [.bounds.x]

        mov     ecx, [.bounds.height]
        sub     ecx, [edi+TImage.height]
        sar     ecx, 1
        add     ecx, [.bounds.y]                ; x coordinate of the icon.

        jmp     .draw_icon

@@:
        cmp     [esi+TButton._iconpos], iposLeft
        jne     @f

; align left
        mov     eax, [.bounds.x]

        mov     ecx, [.bounds.height]
        sub     ecx, [edi+TImage.height]
        sar     ecx, 1
        add     ecx, [.bounds.y]                ; x coordinate of the icon.

        add     ebx, [edi+TImage.width]
        add     [.bounds.x], ebx
        sub     [.bounds.width], ebx
        jmp     .draw_icon

@@:
        cmp     [esi+TButton._iconpos], iposRight
        jne     @f

; align right
        mov     eax, [.bounds.x]
        add     eax, [.bounds.width]
        sub     eax, [edi+TImage.width]

        add     ebx, [edi+TImage.width]
        sub     [.bounds.width], ebx

        mov     ecx, [.bounds.height]
        sub     ecx, [edi+TImage.height]
        sar     ecx, 1
        add     ecx, [.bounds.y]
        jmp     .draw_icon

@@:
        cmp     [esi+TButton._iconpos], iposTop
        jne     @f

; align top
        mov     eax, [.bounds.width]
        sub     eax, [edi+TImage.width]
        sar     eax, 1
        add     eax, [.bounds.x]

        mov     ecx, [.bounds.y]

        add     edx, [edi+TImage.height]

        add     [.bounds.y], edx
        sub     [.bounds.height], edx
        jmp     .draw_icon

@@:
        cmp     [esi+TButton._iconpos], iposBottom
        jne     .draw_text

; align bottom
        mov     ecx, [.bounds.y]
        add     ecx, [.bounds.height]
        sub     ecx, [edi+TImage.height]

        add     edx, [edi+TImage.height]
        sub     [.bounds.height], edx

        mov     eax, [.bounds.width]
        sub     eax, [edi+TImage.width]
        sar     eax, 1
        add     eax, [.bounds.x]

.draw_icon:
        cmp     [esi+TButton._state], bsPressed
        jne     .blend_icon

        add     eax, [GUI.btnPressedOfsX]
        add     ecx, [GUI.btnPressedOfsY]

.blend_icon:
        stdcall BlendImage, [.canvas], eax, ecx, edi, 0, 0, [edi+TImage.width], [edi+TImage.height]

.draw_text:
        get     edi, esi, TButton:TextAlign

        mov     eax, [.caption]
        test    eax, eax
        jz      .textok

        cmp     [esi+TButton._state], bsPressed
        jne     .textofsok

        mov     ecx, [GUI.btnPressedOfsX]
        add     [.bounds.x], ecx
        mov     ecx, [GUI.btnPressedOfsY]
        add     [.bounds.y], ecx

.textofsok:
        stdcall DrawTextBox, [.canvas], eax, [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], 2, edi, [GUI.DefaultFont], [.clTxt]
        stdcall StrDel, eax


.textok:
        cmp     esi, [__FocusedWindow]
        jne     .not_focused

        mov     eax, [esi+TButton._height]
        mov     ecx, [esi+TButton._width]
        sub     eax, 2
        sub     ecx, 4
        stdcall DrawSolidRect, [.canvas], 0, eax, [esi+TButton._width], 2, [GUI.clBorderFocused]

.not_focused:

        inherited

        popad
        return
endp




method TButton.EventMouseEnter
begin
        mov     eax, [.self]
        mov     [eax+TButton._state], bsHovered
        exec    eax, TButton:Refresh

        inherited
        return
endp




method TButton.EventMouseLeave
begin
        mov     eax, [.self]

        mov     [eax+TButton._state], bsNeutral
        exec    eax, TButton:Refresh

        inherited
        return
endp



method TButton.EventButtonPress
begin
        mov     eax, [.self]

        mov     [eax+TButton._state], bsPressed
        exec    eax, TButton:Refresh
        return
endp



method TButton.EventButtonRelease
begin
        pushad

        mov     esi, [.self]

        cmp     [esi+TButton._state], bsPressed
        jne     .finish

        mov     [esi+TButton._state], bsHovered
        exec    esi, TButton:Refresh

        cmp     [esi+TButton._ModalResult], mrNone
        je      @f

        get     eax, esi, TButton:Parent

        istype  eax, TForm
        jne     @f

        set     eax, TForm:ModalResult, [esi+TButton._ModalResult]

@@:
        get     eax, esi, TButton:OnClick
        test    eax, eax
        jz      .click_ok

        stdcall eax, esi, [.button]       ; OnClick event

.click_ok:
        get     eax, esi, TButton:Action
        test    eax, eax
        jz      .finish

        exec    eax, TAction:Execute, [.self]

.finish:
        popad
        return
endp




method TButton.EventKeyPress
begin
        push    ecx

        cmp     [.utf8], ' '
        jne     .finish

        mov     ecx, [.self]
        mov     [ecx+TButton._state], bsPressed

        exec    ecx, TWindow:EventButtonRelease, mbLeft, [.kbdState], 0, 0

        mov     [ecx+TButton._state], bsPressed
        exec    ecx, TWindow:Refresh

.finish:
        inherited [.utf8], [.scancode], [.kbdState]
        pop     ecx
        return
endp



method TButton.EventKeyRelease
begin
        push    ecx
        mov     ecx, [.self]
        mov     [ecx+TButton._state], bsNeutral

        exec    ecx, TWindow:Refresh
        pop     ecx

        return
endp



method TButton.SetTextAlign
begin
        push    ecx

        mov     ecx, [.self]
        push    [.value]
        pop     [ecx+TButton._textalign]

        exec    ecx, TWindow:Refresh
        pop     ecx
        return
endp



method TButton.SetIcon
begin
        push    ecx

        mov     ecx, [.self]
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
480
481
482
483
484
485
486
487





















































































































































































































488








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


        exec    ecx, TWindow:Refresh
        pop     ecx
        return
endp



method TButton.SysEventHandler
begin
        pushad

        mov     esi, [.self]
        mov     ebx, [.pEvent]

        dispatch [ebx+TSysEvent.event]

.finish:
        popad
        return

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

oncase sePaint
; PAINT event is very important.
        mov     edx, bxFlat
        mov     edi, [clButtonBk]       ; background
        mov     ecx, [clButtonTxt]      ; text

        cmp     [esi+TButton.state], btnNormal
        je      .drawit

        mov     edx, bxRaised
        mov     edi, [clButtonHotBk]
        mov     ecx, [clButtonHotTxt]

        cmp     [esi+TButton.state], btnPointed
        je      .drawit

        mov     edx, bxSunken
        mov     edi, [clButtonBk]
        mov     ecx, [clButtonHotTxt]

        cmp     [esi+TButton.state], btnPressed
        je      .drawit

        mov     edx, bxFlat

.drawit:
locals
 .bounds TBounds
 .clTxt dd ?
endl
        mov     [.clTxt], ecx

        mov     ecx, [esi+TButton._width]
        mov     eax, [esi+TButton._height]
        mov     [.bounds.x], 0
        mov     [.bounds.y], 0
        mov     [.bounds.width], ecx
        mov     [.bounds.height], eax
        lea     eax, [.bounds]
        stdcall [DrawBox], [ebx+TPaintEvent.context], eax, edi, edx

; first draw the icon and then resize bounds for the text.
        mov     edi, [esi+TButton._icon]
        test    edi, edi
        jz      .draw_text

        cmp     [esi+TButton._iconpos], AlignLeft
        jne     @f

; align left
        mov     eax, [.bounds.x]
        mov     ecx, [.bounds.height]
        add     eax, 2
        sub     ecx, [edi+TImage.height]
        sar     ecx, 1
        add     ecx, [.bounds.y]

        mov     edx, [edi+TImage.width]
        add     edx, 4
        add     [.bounds.x], edx
        sub     [.bounds.width], edx
        jmp     .draw_icon

@@:
        cmp     [esi+TButton._iconpos], AlignRight
        jne     @f

; align right
        mov     edx, [edi+TImage.width]

        mov     eax, [.bounds.x]
        add     eax, [.bounds.width]
        sub     eax, edx
        sub     eax, 2
        sub     [.bounds.width], edx
        sub     [.bounds.width], 4

        mov     ecx, [.bounds.height]
        sub     ecx, [edi+TImage.height]
        sar     ecx, 1
        add     ecx, [.bounds.y]
        jmp     .draw_icon

@@:
        cmp     [esi+TButton._iconpos], AlignTop
        jne     @f

; align top
        mov     ecx, [.bounds.y]
        add     ecx, 2
        mov     eax, [.bounds.width]
        sub     eax, [edi+TImage.width]
        sar     eax, 1
        add     eax, [.bounds.x]

        mov     edx, [edi+TImage.height]
        add     edx, 4
        add     [.bounds.y], edx
        sub     [.bounds.height], edx
        jmp     .draw_icon

@@:
        cmp     [esi+TButton._iconpos], AlignBottom
        jne     .draw_text

; align bottom
        mov     edx, [edi+TImage.height]

        mov     ecx, [.bounds.y]
        add     ecx, [.bounds.height]
        sub     ecx, edx
        sub     ecx, 2
        sub     [.bounds.height], edx
        sub     [.bounds.height], 4

        mov     eax, [.bounds.width]
        sub     eax, [edi+TImage.width]
        sar     eax, 1
        add     eax, [.bounds.x]

.draw_icon:
        stdcall DrawImage, [ebx+TPaintEvent.context], [esi+TButton._icon], eax, ecx

.draw_text:
        get     eax, esi, TWindow:Caption
        test    eax, eax
        jz      .finish

        push    eax eax
        stdcall StrLen, eax
        mov     ecx, eax
        pop     eax
        lea     edx, [.bounds]
        stdcall DrawTextBox, [ebx+TPaintEvent.context], eax, edx, [esi+TButton._textalign], 0, [.clTxt]
        stdcall StrDel ; from the stack
        jmp     .finish


;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

oncase seMouseEnter

        mov     [esi+TButton.state], btnPointed
        exec    esi, TButton:Refresh
        jmp     .finish


;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


oncase seMouseLeave
        mov     [esi+TButton.state], btnNormal
        exec    esi, TButton:Refresh
        jmp     .finish


;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


oncase seMouseBtnPress
        mov     [esi+TButton.state], btnPressed
        exec    esi, TButton:Refresh
        jmp     .finish


;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


oncase seMouseBtnRelease

        cmp     [esi+TButton.state], btnPressed
        jne     .finish

        mov     [esi+TButton.state], btnPointed
        exec    esi, TButton:Refresh

        cmp     [esi+TButton._ModalResult], mrNone
        je      @f

        get     eax, esi, TButton:Parent

        istype  eax, TForm
        jne     @f

        set     eax, TForm:ModalResult, [esi+TButton._ModalResult]

@@:
        get     eax, esi, TButton:OnClick
        test    eax, eax
        jz      .finish

        stdcall eax, esi, [ebx+TMouseButtonEvent.Button]
        jmp     .finish

        enddispatch
endp


endmodule
Added freshlib/gui/TCheckbox.asm.






















































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: TCheckbox object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Represents GUI checkbox.
;_________________________________________________________________________________________
module "TCheckbox library"


; Button states for the field TCheckbox._state

cbsNeutral    = 0
cbsHovered    = 1
cbsPressed    = 2

cbsDisabled   = 3


object TCheckbox, TWindow

; private fields

  ._state       dd ?      ; internal state variable.

  ._OnClick     dd ?

  ._checked     dd ?

; parameters

  param .Checked, .GetChecked, .SetChecked
  param .OnClick, ._OnClick, ._OnClick

; methods

  ; parameters handling methods

  method .GetChecked
  method .SetChecked, .value

  ; system events methods

  method .Create, .Parent

  method .Paint

  method .EventMouseEnter
  method .EventMouseLeave

  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventButtonRelease, .button, .kbdState, .x, .y

  method .EventKeyPress, .utf8, .scancode, .kbdState
  method .EventKeyRelease, .scancode, .kbdState

endobj


; new


method TCheckbox.Create
begin
        inherited [.Parent]

        mov     eax, [.self]
        mov     [eax+TCheckbox.__want_focus], TRUE
        mov     [eax+TCheckbox._cursor], mcHand
        return
endp





method TCheckbox.Paint

 .bounds TBounds
 .canvas dd ?

 .caption dd ?
 .enabled dd ?
 .checked dd ?

begin
        pushad

        mov     esi, [.self]

        get     edx, esi, TCheckbox:Action
        test    edx, edx
        jz      .get_normal

        get     eax, edx, TAction:Caption
        stdcall StrDupMem, eax
        mov     [.caption], eax

        get     [.checked], edx, TAction:Checked
        jmp     .get_enabled

.get_normal:

        get     [.caption], esi, TCheckbox:Caption
        get     [.checked], esi, TCheckbox:Checked


.get_enabled:
        get     [.enabled], esi, TCheckbox:Enabled

.paint_it:
        get     eax, esi, TWindow:Canvas
        mov     [.canvas], eax

        mov     eax, [esi+TCheckbox._state]
        cmp     [.enabled], 0
        jne     .state_ok

        mov     eax, cbsDisabled

.state_ok:
        mov     edi, [GUI.clCheckboxBack+4*eax]    ; background color

        get     ecx, esi, TCheckbox:height
        mov     edx, [GUI.cbIconSize]
        sub     ecx, edx
        sar     ecx, 1

        mov     [.bounds.x], 0
        mov     [.bounds.y], ecx
        mov     [.bounds.width], edx
        mov     [.bounds.height], edx

        mov     eax, [GUI.clDialogBk]
        and     eax, $00ffffff
        or      eax, $01000000
        stdcall DrawSolidRect, [.canvas], 0, 0, [esi+TCheckbox._width], [esi+TCheckbox._height], eax

        lea     eax, [.bounds]

        mov     ebx, [GUI.borderCheckbox]
        cmp     [.enabled], 0
        jne     .border_ok

        or      ebx, bxDisabled

.border_ok:
        stdcall DrawBoxDefault, [.canvas], eax, edi, ebx, [GUI.boxBorderWidth]

        mov     [.bounds.x], 0
        mov     [.bounds.y], ecx
        mov     [.bounds.width], edx
        mov     [.bounds.height], edx

; first draw the icon and then resize bounds for the text.

        cmp     [.checked], 0
        je      .icon_ok

        mov     eax, [GUI.iconCheckedGray]
        cmp     [.enabled], 0
        je      .draw_icon

        mov     eax, [GUI.iconChecked]

.draw_icon:

        stdcall BlendImage, [.canvas], [.bounds.x], [.bounds.y], eax, 0, 0, [eax+TImage.width], [eax+TImage.height]

.icon_ok:
        mov     ecx, [.bounds.width]
        mov     edx, [esi+TCheckbox._width]
        mov     ebx, [esi+TCheckbox._height]

        add     ecx, [GUI.cbMargin]
        sub     edx, ecx

        mov     eax, [.caption]
        test    eax, eax
        jz      .textok

        mov     edi, [GUI.clCheckboxTxt]
        cmp     [.enabled], 0
        jne     .txt_color_ok

        mov     edi, [GUI.clCheckboxTxtGray]

.txt_color_ok:
        stdcall DrawTextBox, [.canvas], eax, ecx, 0, edx, ebx, 0, dtfAlignLeft or dtfAlignMiddle, [GUI.DefaultFont], edi
        stdcall StrDel, eax

.textok:
        cmp     esi, [__FocusedWindow]
        jne     .not_focused

        mov     eax, [.bounds.y]
        add     eax, 15
        stdcall DrawSolidRect, [.canvas], 0, eax, 13, 2, [GUI.clBorderFocused]

.not_focused:

        inherited

        popad
        return
endp




method TCheckbox.EventMouseEnter
begin
        mov     eax, [.self]
        mov     [eax+TCheckbox._state], cbsHovered
        exec    eax, TCheckbox:Refresh

        inherited
        return
endp




method TCheckbox.EventMouseLeave
begin
        mov     eax, [.self]

        mov     [eax+TCheckbox._state], cbsNeutral
        exec    eax, TCheckbox:Refresh

        inherited
        return
endp




method TCheckbox.EventButtonPress
begin
        push    eax

        mov     eax, [.self]
        mov     [eax+TCheckbox._state], cbsPressed

        get     eax, [.self], TCheckbox:Checked
        xor     eax, 1
        set     [.self], TCheckbox:Checked, eax

        get     eax, [.self], TCheckbox:OnClick
        test    eax, eax
        jz      .finish

        stdcall eax, [.self], [.button]

.finish:
        exec    [.self], TCheckbox:Refresh
        pop     eax
        return
endp



method TCheckbox.EventButtonRelease
begin
        pushad

        mov     esi, [.self]
        mov     [esi+TCheckbox._state], cbsHovered
        exec    esi, TCheckbox:Refresh

        popad
        return
endp




method TCheckbox.EventKeyPress
begin
        push    ecx

        cmp     [.utf8], ' '
        jne     .finish

        mov     ecx, [.self]
        cmp     [ecx+TCheckbox._state], cbsPressed
        je      .finish

        exec    ecx, TWindow:EventButtonPress, mbLeft, [.kbdState], 0, 0

        mov     [ecx+TCheckbox._state], cbsPressed
        exec    ecx, TWindow:Refresh

.finish:
        inherited [.utf8], [.scancode], [.kbdState]
        pop     ecx
        return
endp




method TCheckbox.EventKeyRelease
begin
        push    ecx

        mov     ecx, [.self]
        mov     [ecx+TCheckbox._state], cbsNeutral

        exec    ecx, TWindow:Refresh
        pop     ecx

        return
endp



method TCheckbox.GetChecked
begin
        push    ecx edx

        mov     edx, [.self]
        mov     ecx, [edx+TCheckbox.__action]
        jecxz   .native

        get     eax, ecx, TAction:Checked
        jmp     .finish

.native:
        mov     eax, [edx+TCheckbox._checked]

.finish:
        pop     edx ecx
        return
endp



method TCheckbox.SetChecked
begin
        pushad

        mov     ecx, [.self]
        mov     eax, [.value]

        get     edx, ecx, TCheckbox:Checked

        cmp     eax, edx
        je      .finish

        cmp     [ecx+TCheckbox.__action], 0
        je      .action_ok

        set     [ecx+TCheckbox.__action], TAction:Checked, eax

.action_ok:
        mov     [ecx+TCheckbox._checked], eax
        exec    ecx, TWindow:Refresh

.finish:
        popad
        return
endp




endmodule
Changes to freshlib/gui/TEdit.asm.
10
11
12
13
14
15
16
17

18
19
20
21
22
23


24
25
26
27

28
29


30
31

32
33

34
35
36
37

38






39








40

41
42
43
44
45
46


47
48
49
50
51
52


53
54
55
56

57
58
59
60
61
62
63
64
65


66
67
68
69
70
71
72


73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
95
96
97
98

99
100
101

102
103



104
105

106

107
108
109
110










111

112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130









131
132
133
134
135
136
137
138
139
140
141
142

143
144




145
146
147
148





149
150
151
152


153
154
155


156

157
158


159
160
161

162
163
164
165


166
167
168
169

170
171
172


173
174

175
176
177
178

179
180

181
182
183
184
185
186
187
188

189
190

191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209

210
211

212
213
214
215
216
217
218

219
220
221
222
223
224
225
226

227
228
229

230
231
232
233
234

235
236
237
238

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259

260
261
262
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286
287


288
289
290
291

292
293
294
295
296
297
298
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28

29
30

31
32
33

34
35

36
37
38
39
40
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114


115
116
117
118
119
120
121

122
123
124
125
126


127
128
129
130
131
132
133
134
135



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184



185
186
187
188
189
190
191




192
193
194
195
196
197



198
199
200


201
202
203
204


205
206



207

208


209
210
211



212
213


214
215
216

217




218


219


220





221


222






223
224


225

226
227
228
229
230
231
232

233


234




235


236




237



238



239


240


241




242

243



















244



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268


269
270
271
272
273

274
275
276
277
278
279
280
281







-
+






+
+



-
+

-
+
+

-
+

-
+




+

+
+
+
+
+
+
-
+
+
+
+
+
+
+
+

+






+
+




-
-
+
+




+









+
+







+
+













+



-
-







-
+



+
-
-
+
+
+


+

+

-
-
-
+
+
+
+
+
+
+
+
+
+

+









+









-
+
+
+
+
+
+
+
+
+









-
-
-
+


+
+
+
+
-
-
-
-
+
+
+
+
+

-
-
-
+
+

-
-
+
+

+
-
-
+
+
-
-
-
+
-

-
-
+
+

-
-
-
+

-
-
+
+

-
+
-
-
-
-
+
-
-
+
-
-

-
-
-
-
-
+
-
-
+
-
-
-
-
-
-


-
-
+
-







-
+
-
-
+
-
-
-
-

-
-
+
-
-
-
-

-
-
-
+
-
-
-
+
-
-

-
-
+
-
-
-
-
+
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-








+







-
+







-
-
+
+



-
+







;  Dependencies:
;
;  Notes: Represents single line edit control.
;_________________________________________________________________________________________
module "TEdit library"


object TEdit, TBackWindow
object TEdit, TWindow
  ._Text  dd ?
  ._Len   dd ?  ; the length of the string in characters. (UTF-8)
  ._Start dd ?  ; Where the string begins to be displayed in the edit window.
  ._Pos   dd ?  ; Position of the caret in the string.
  ._Sel   dd ?  ; Position of the selction in the string.

  ._need_refresh dd ?

  ._MarginLeft dd ?
  ._MarginRight dd ?

  ._Focused dd ? ; flag
  param .Text, .GetText, .SetText

  param .Text, .GetText, .SetText
  param .MarginLeft,  ._MarginLeft, ._MarginLeft
  param .MarginRight, ._MarginRight, ._MarginRight

  method ._RedrawShadow
  param .CaretPos, ._Pos, .SetCaretPos

  method .Create
  method .Create, .parent
  method .Destroy

  method .GetText
  method .SetText, .value
  method .SetCaretPos, .value

  method .HitTest, .x, .y               ; returns the position inside the string.

; system event methods

  method .UpdateCaretPos

  method   .SysEventHandler, .pEvent
  method .Paint

  method .EventKeyPress, .utf8, .scancode, .kbdState
  method .EventKeyRelease, .scancode, .kbdState

  method .EventFocusIn
  method .EventFocusOut

endobj



method TEdit.Create
begin
        push    ecx eax

        inherited [.parent]

        stdcall StrNew
        mov     ecx, [.self]
        mov     [ecx+TEdit._Text], eax
        mov     [ecx+TEdit._cursor], mcText

        inherited
        mov     [ecx+TEdit.__want_focus], TRUE
        mov     [ecx+TEdit._need_refresh], TRUE

        pop     eax ecx
        return
endp



method TEdit.Destroy
begin
        mov     eax, [.self]
        stdcall StrDel, [eax+TEdit._Text]
        return
endp




method TEdit.GetText
begin
        mov     eax, [.self]
        stdcall StrDup, [eax+TEdit._Text]
        return
endp




method TEdit.SetText
begin
        push    esi eax
        mov     esi, [.self]

        mov     [esi+TEdit._Start], 0
        mov     [esi+TEdit._Pos], 0
        mov     [esi+TEdit._Sel], 0

        lea     eax, [esi+TEdit._Text]
        stdcall SetString, eax, [.value]

        stdcall StrLenUtf8, [esi+TEdit._Text], -1
        mov     [esi+TEdit._Len], eax

        mov     [esi+TEdit._fShadowReady], 0

        exec    esi, TEdit:Refresh
        pop     eax esi
        return
endp



method TEdit._RedrawShadow
method TEdit.Paint
 .bounds  TBounds
 .selbeg  dd ?
 .selend  dd ?

 .ypos    dd ?
 .context dd ?
 .clBack  dd ?
 .border  dd ?

begin
        pushad

        mov     esi, [.self]
        exec    esi, TEdit:__UpdateCanvas

        mov     eax, [esi+TEdit._pShadow]
        stdcall AllocateContext, [eax+TBackBuffer.raster]
        mov     [.context], eax
        mov     eax, [GUI.clEditBk]
        mov     ecx, [GUI.editBorder]

        cmp     esi, [__FocusedWindow]
        jne     @f
        mov     eax, [GUI.clEditBkFocused]
        mov     ecx, [GUI.editBorderFocused]
@@:
        mov     [.clBack], eax
        mov     [.border], ecx

; selection sort positions.
        mov     eax, [esi+TEdit._Pos]
        mov     ecx, [esi+TEdit._Sel]
        cmp     eax,ecx
        jle     @f
        xchg    eax, ecx
@@:
        mov     [.selbeg], eax
        mov     [.selend], ecx

; drawing bounds
        mov     ecx, [esi+TEdit._width]
        mov     eax, [esi+TEdit._height]

        mov     [.bounds.x], 0
        mov     [.bounds.y], 0
        mov     [.bounds.width], ecx
        mov     [.bounds.height], eax

        lea     eax, [.bounds]
        stdcall [DrawBox], [.context], eax, [clEditBk], bxSunken

        stdcall [DrawBox], [esi+TWindow._canvas], eax, [.clBack], [.border], [GUI.boxBorderWidth]

        mov     eax, [GUI.boxBorderWidth]
        add     [.bounds.x], eax
        add     [.bounds.y], eax
        shl     eax, 1
        sub     [.bounds.width], eax
        sub     [.bounds.height], eax

        mov     eax, [esi+TEdit._MarginLeft]
        mov     ecx, [esi+TEdit._MarginRight]
        add     [.bounds.x], eax
        sub     [.bounds.width], eax
        sub     [.bounds.width], ecx
        cmp     [.bounds.width], 0
        jle     .enddraw

        mov     ecx, [esi+TEdit._Start]

        stdcall StrOffsUtf8, [esi+TEdit._Text], ecx
        stdcall StrOffsUtf8, [esi+TEdit._Text], [esi+TEdit._Start]
        mov     edi, eax

        stdcall DrawTextBox, [esi+TEdit._canvas], edi, [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], 0, dtfAlignLeft or dtfAlignMiddle or dtfSingleLine, [GUI.DefaultFont], [GUI.clEditTxt]

; determine the selection

        mov     eax, [.bounds.y]
        add     eax, [.bounds.height]
        sub     eax, 4
        mov     [.ypos], eax   ; y position of the characters.
        mov     eax, [.selbeg]
        mov     ecx, [esi+TEdit._MarginLeft]

        sub     eax, [esi+TEdit._Start]
        jle     .xsel_ok

.drawloop:
        stdcall DecodeUtf8, [edi]
        jc      .enddraw
        stdcall StrOffsUtf8, edi, eax
        sub     eax, edi

        test    eax, eax
        jz      .eraseremaining
        stdcall GetTextBounds, edi, eax, [GUI.DefaultFont]
        mov     ecx, eax

.xsel_ok:
        mov     eax, [clEditTxt]
        cmp     ecx, [.selbeg]
        mov     eax, [.selend]
        sub     eax, [esi+TEdit._Start]
        jl      .colorok
        cmp     ecx, [.selend]
        jge     .colorok
        jle     .enddraw
        mov     eax, [clEditSelTxt]

.colorok:
        push    eax  0 [.ypos] [.bounds.x] edx edi
        stdcall StrOffsUtf8, edi, eax
        sub     eax, edi

        push    0 edx edi
        add     edi, edx
        stdcall GetTextBounds, [.context] ; remaining from the stack
        stdcall GetTextBounds, edi, eax, [GUI.DefaultFont]

        sub     [.bounds.width], eax
        js      .nodraw
        mov     edx, [.bounds.width]
        add     edx, [.bounds.x]

        cmp     ecx, [.selbeg]
        cmp     eax, edx
        jl      .drawtxt
        cmp     ecx, [.selend]
        jge     .drawtxt

        cmovg   eax, edx
        mov     esi, [.ypos]
        sub     esi, edx
        sub     eax, ecx
        add     edx, 2
        stdcall DrawFillRect, [.context], [.bounds.x], [.bounds.y], eax, [.bounds.height], [clEditSel]

.drawtxt:
        add     [.bounds.x], eax
        stdcall DrawString, [.context] ; remaining from the stack

        inc     ecx
        add     ecx, [.bounds.x]
        jmp     .drawloop

        stdcall BlendSolidRect, [esi+TWindow._canvas], ecx, [.bounds.y], eax, [.bounds.height], [GUI.clEditSel]
.nodraw:
        add     esp, 24 ; 6*4
        jmp     .enddraw

.eraseremaining:
        stdcall DrawFillRect, [.context], [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], [clEditBk]

.enddraw:
        stdcall ReleaseContext, [.context]

        inherited
        stc
        popad
        return
endp





method TEdit.EventKeyPress      ;, .utf8, .scancode, .kbdState
method TEdit.SysEventHandler
.changes dd ?
.time    dd ?
.prevpos dd ?
.PosChanged  = 1
.NeedRefresh = 2
.ShowCaret   = 4
begin
        push    eax ebx ecx edx esi edi

        pushad
        mov     [.changes], 0
        mov     esi, [.self]
        mov     ebx, [.pEvent]
        mov     eax, [ebx+TSysEvent.event]

        cmp     eax, seKbdKeyPress
        je      .keypress

        stdcall GetTimestamp
        cmp     eax, seFocusIn
        je      .focusin

        mov     [.time], eax
        cmp     eax, seFocusOut
        je      .focusout

        inherited [.pEvent]

        mov     esi, [.self]
.finish:
        pop     edi esi edx ecx ebx eax
        return

        get     ebx, esi, TEdit:CaretPos
;............................................................................................

.focusin:
        mov     [esi+TEdit._Focused], TRUE
        stdcall CaretAttach, esi
        or      [.changes], .PosChanged or .ShowCaret
        jmp     .endmove

.focusout:
        stdcall CaretShow, FALSE
        mov     [esi+TEdit._Focused], FALSE
        or      [.changes], .PosChanged
        jmp     .endmove

;............................................................................................

.keypress:
;        mov     eax, [ebx+TKeyboardEvent.kbdStatus]
;        OutputRegister regEAX, 16

        mov     eax, [esi+TEdit._Pos]
        mov     eax, [.utf8]
        mov     [.prevpos], eax

        mov     eax, [ebx+TKeyboardEvent.key]
        test    eax, eax
        jz      .no_char

        cmp     eax, $20
        jb      .no_char

        cmp     eax, $7f
        je      .no_char


        push    eax

        call    .ClearSelection

        stdcall StrPtr, [esi+TEdit._Text]
        mov     ecx, eax
        stdcall StrOffsUtf8, eax, [esi+TEdit._Pos]
        stdcall StrOffsUtf8, eax, ebx
        sub     ecx, eax
        neg     ecx

        pop     eax
        stdcall StrCharInsert, [esi+TEdit._Text], eax, ecx
        inc     [esi+TEdit._Len]

        mov     [ebx+TKeyboardEvent.kbdStatus], 0
        or      [.changes], .NeedRefresh
        mov     [.kbdState], 0
        inc     [esi+TEdit._need_refresh]
        jmp     .right

.no_char:
        mov     eax, [ebx+TKeyboardEvent.scancode]
        mov     eax, [.scancode]

        cmp     eax, keyLeftNumpad
        je      .left
        cmp     eax, keyLeft
        je      .left

        cmp     eax, keyRightNumpad
317
318
319
320
321
322
323
324

325
326
327
328

329
330
331
332
333
334


335
336
337

338
339
340
341

342
343
344
345

346
347

348
349
350

351
352
353
354
355
356

357
358
359
360

361
362
363
364
365
366
367
368


369
370
371
372

373

374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396


397
398
399
400
401
402
403
404

405
406
407
408

409
410
411

412
413
414

415
416
417
418
419

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

442
443
444
445
446
447

448
449
450
451

452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467
468
469
470

471
472
473
474
475


476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

495
496
497


498
499
500
501



502
503
504
505

506
507

508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527




































































































































528
529

































































































































































































































































































































530
531
532
533
534
535
536
300
301
302
303
304
305
306

307
308
309


310
311
312
313



314
315
316


317
318
319
320

321


322
323
324
325

326


327
328
329
330
331
332
333

334
335
336


337
338
339
340
341
342



343
344
345
346

347
348

349
350
351
352
353
354
355
356
357
358
359
360
361
362

363
364

365


366


367
368
369







370
371



372



373
374


375
376
377



378






















379


380



381




382








383


384








385


386


387
388


389

390










391

392

393
394


395
396
397



398
399
400

401
402

403
404

405
406
407
408
409
410
411
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886







-
+


-
-
+



-
-
-
+
+

-
-
+



-
+
-
-


+

-
+
-
-

+





-
+


-
-
+





-
-
-
+
+


-

+
-
+













-


-

-
-

-
-
+
+

-
-
-
-
-
-
-
+

-
-
-
+
-
-
-
+

-
-
+


-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-

-
-
-
+
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-

-
-
-
-
-
-
-
-
+
-
-

-
-
+
+
-
-

-

-
-
-
-
-
-
-
-
-
-

-

-
+

-
-
+
+

-
-
-
+
+
+
-


-
+

-
+













-






+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








        cmp     eax, keyBackSpace
        je      .backdel

        jmp     .finish

.left:
        cmp     [esi+TEdit._Pos], 0
        cmp     ebx, 0
        jle     .endmove

        or      [.changes], .PosChanged
        dec     [esi+TEdit._Pos]
        dec     ebx
        jmp     .endmove

.right:
        mov     eax, [esi+TEdit._Pos]
        cmp     eax, [esi+TEdit._Len]
        jae     .finish
        cmp     ebx, [esi+TEdit._Len]
        jae     .endmove

        or      [.changes], .PosChanged
        inc     [esi+TEdit._Pos]
        inc     ebx
        jmp     .endmove

.home:
        mov     [esi+TEdit._Pos], 0
        xor     ebx, ebx
        mov     [esi+TEdit._Start], 0
        mov     [.changes], .PosChanged or .NeedRefresh
        jmp     .endmove


.end:
        mov     eax, [esi+TEdit._Len]
        mov     ebx, [esi+TEdit._Len]
        mov     [esi+TEdit._Pos], eax
        or      [.changes], .PosChanged
        jmp     .endmove


.backdel:
        call    .ClearSelection
        jnc     .endmove

        cmp     [esi+TEdit._Pos], 0
        cmp     ebx, 0
        jle     .endmove

        or      [.changes], .PosChanged
        dec     [esi+TEdit._Pos]
        dec     ebx

.del:
        call    .ClearSelection
        jnc     .endmove

        mov     eax, [esi+TEdit._Pos]
        cmp     eax, [esi+TEdit._Len]
        jae     .finish                ; can't delete after the end of string.
        cmp     ebx, [esi+TEdit._Len]
        jge     .finish                ; can't delete after the end of string.

        stdcall StrPtr, [esi+TEdit._Text]

        mov     ecx, eax

        stdcall StrOffsUtf8, eax, [esi+TEdit._Pos]
        stdcall StrOffsUtf8, eax, ebx
        sub     eax, ecx

        stdcall StrSplit, [esi+TEdit._Text], eax
        mov     ebx, eax

        stdcall StrPtr, ebx
        stdcall DecodeUtf8, [eax]

        stdcall StrCopyPart, ebx, ebx, edx, -1
        stdcall StrCat, [esi+TEdit._Text], ebx
        stdcall StrDel, ebx

        dec     [esi+TEdit._Len]
        or      [.changes], .NeedRefresh

.endmove:
        mov     ebx, [.pEvent]
        mov     eax, [esi+TEdit._Pos]
        cmp     [ebx+TSysEvent.event], seKbdKeyPress
        jne     .setselection

        test    [ebx+TKeyboardEvent.kbdStatus], maskShift
        jnz     .refresh
        test    [.kbdState], maskShift
        jnz     .set_pos

.setselection:
        mov     ecx, [.prevpos]
        cmp     ecx, [esi+TEdit._Sel]
        je      @f
        or      [.changes], .NeedRefresh
@@:
        mov     [esi+TEdit._Sel], eax
        mov     [esi+TEdit._Sel], ebx

        test    [.changes], .NeedRefresh
        jz      .caretmove

.set_pos:
.refresh:
        mov     [esi+TEdit._fShadowReady], 0
        exec    [.self], TEdit:Refresh
        set     esi, TEdit:CaretPos, ebx

.caretmove:
        cmp     [esi+TEdit._Focused], 0
        cmp     [esi+TEdit._need_refresh], 0
        je      .finish

        test    [.changes], .PosChanged
        jz      .showcaret

        exec    esi, TEdit:Update
        mov     eax, [esi+TEdit._Pos]
        cmp     eax, [esi+TEdit._Start]
        jl      .scroll

        stdcall StrPtr, [esi+TEdit._Text]
        mov     edi, eax

        stdcall StrOffsUtf8, edi, [esi+TEdit._Pos]
        mov     ecx, eax

        stdcall StrOffsUtf8, edi, [esi+TEdit._Start]
        sub     ecx, eax                           ; offset to char under cursor.
        jns     .leftok

.scroll:
        mov     eax, [esi+TEdit._Start]
        sub     eax, 8
        test    eax, eax
        jns         @f
        xor     eax, eax
@@:
        mov     [esi+TEdit._Start], eax
        mov     [esi+TEdit._need_refresh], 0
        mov     [.changes], .PosChanged or .NeedRefresh
        jmp     .endmove

.leftok:
        mov     edi, eax                           ; pointer to start of the text.

.finish:
        stdcall AllocateContext, [esi+TEdit.handle]
        push    eax

        stdcall GetTextBounds, eax, edi, ecx, 0
        stdcall GetTimestamp
        lea     ecx, [eax+2]       ; x coordinate of the cursor.
        add     ecx, [esi+TEdit._MarginLeft]

        stdcall ReleaseContext ; from the stack.

        mov     eax, [esi+TEdit._width]
        sub     eax, [esi+TEdit._MarginRight]
        sub     eax, ecx
        sub     eax, [.time]
        cmp     eax, 2
        jge     .caretok

        mov     eax, [esi+TEdit._Start]
        add     eax, 8
        cmp     eax, [esi+TEdit._Len]
        jle     @f
        mov     eax, [esi+TEdit._Len]
@@:
        mov     [esi+TEdit._Start], eax

        OutputValue "Key press:", eax, 10, 4
        mov     [.changes], .PosChanged or .NeedRefresh
        jmp     .endmove


.caretok:
        popad
        return
        mov     edx, [esi+TEdit._height]
        sub     edx, 4

        stdcall CaretChange, ecx, 2, 1, edx

.showcaret:
        test    [.changes], .ShowCaret
        jz      .finish

        stdcall CaretShow, TRUE
        jmp     .finish

;............................................................................................


.ClearSelection:
        mov     eax, [esi+TEdit._Pos]
        mov     ecx, [esi+TEdit._Sel]
        cmp     eax, [esi+TEdit._Sel]
        cmp     ebx, [esi+TEdit._Sel]
        je      .noselection            ; there is no selection.
        jg      @f
        xchg    eax, ecx        ; eax=end_selection; ecx=beg_selection
        jl      @f
        xchg    ebx, ecx        ; ebx=beg_selection; ecx=end_selection
@@:
        add     [esi+TEdit._Len], ecx
        sub     [esi+TEdit._Len], eax
        mov     [esi+TEdit._Pos], ecx
        add     [esi+TEdit._Len], ebx
        sub     [esi+TEdit._Len], ecx
        mov     [esi+TEdit._Sel], ebx
        mov     [esi+TEdit._Sel], ecx

        push    -1
        stdcall StrOffsUtf8, [esi+TEdit._Text], eax
        stdcall StrOffsUtf8, [esi+TEdit._Text], ecx
        push    eax
        stdcall StrOffsUtf8, [esi+TEdit._Text], ecx
        stdcall StrOffsUtf8, [esi+TEdit._Text], ebx
        push    eax
        stdcall StrPtr, [esi+TEdit._Text]
        sub     [esp], eax     ; begin of the selection
        sub     [esp+4], eax
        mov     eax, [esp]
        sub     [esp+4], eax   ; length of the selection

        stdcall StrSplit, [esi+TEdit._Text]  ; position from the stack
        mov     ecx, eax
        stdcall StrCopyPart, ecx, ecx   ; pos and length from the stack.
        stdcall StrCat, [esi+TEdit._Text], ecx
        stdcall StrDel, ecx

        or      [.changes], .PosChanged or .NeedRefresh
        clc
        retn

.noselection:
        stc
        retn

endp



method TEdit.EventKeyRelease  ;, .scancode, .kbdState
begin

        return
endp



method TEdit.SetCaretPos
begin
        pushad

        mov     ecx, [.self]
        mov     eax, [.value]
        cmp     eax, [ecx+TEdit._Pos]
        je      .finish

        mov     [ecx+TEdit._Pos], eax
        exec    ecx, TEdit:UpdateCaretPos

.finish:
        popad
        return
endp



method TEdit.UpdateCaretPos
.refresh dd ?
begin
        pushad
        mov     esi, [.self]

        xor     eax, eax
        mov     [.refresh], eax

        mov     eax, [esi+TEdit._Pos]
        cmp     eax, [esi+TEdit._Start]
        jge     .compute_x

; scroll the text
        and     eax, $fffffff8
        mov     [esi+TEdit._Start], eax
        inc     [.refresh]

.compute_x:
        stdcall StrPtr, [esi+TEdit._Text]
        mov     edi, eax

        stdcall StrOffsUtf8, edi, [esi+TEdit._Pos]
        mov     ecx, eax

        stdcall StrOffsUtf8, edi, [esi+TEdit._Start]
        sub     ecx, eax                           ; offset to char under cursor.

.leftok:
        mov     edi, eax                           ; StrOffsUtf8 returns pointer to start of the text.

        mov     eax, ecx
        jecxz   @f

        stdcall GetTextBounds, edi, ecx, [GUI.DefaultFont]

@@:
        lea     ecx, [eax+1]                       ; x coordinate of the cursor.
        add     ecx, [esi+TEdit._MarginLeft]

        mov     eax, [esi+TEdit._width]
        sub     eax, [esi+TEdit._MarginRight]
        sub     eax, ecx
        cmp     eax, 1
        jge     .caretok

        mov     eax, [esi+TEdit._Start]
        add     eax, 8
        cmp     eax, [esi+TEdit._Len]
        jle     @f
        mov     eax, [esi+TEdit._Len]
@@:
        mov     [esi+TEdit._Start], eax
        inc     [.refresh]
        jmp     .compute_x

.caretok:
        cmp     [.refresh], 0
        je      .canvas_ok

        exec    esi, TEdit:Paint
        inc     [esi+TEdit._need_refresh]

.canvas_ok:
        mov     edx, [esi+TEdit._height]
        sub     edx, 4

        add     ecx, [GUI.boxBorderWidth]
        stdcall CaretChange, ecx, 2, 1, edx

        popad
        return
endp



method TEdit.HitTest
begin


        return
endp



method TEdit.EventFocusIn
begin
        stdcall CaretAttach, [.self]
        stdcall CaretShow, TRUE
        exec    [.self], TEdit:UpdateCaretPos
        return
endp


method TEdit.EventFocusOut
begin
        stdcall CaretShow, FALSE

        inherited
        return
endp


;method TEdit.SysEventHandler
;.changes dd ?
;.prevpos dd ?
;.PosChanged  = 1
;.NeedRefresh = 2
;.ShowCaret   = 4
;begin
;        push    eax ebx ecx edx esi edi
;
;        mov     [.changes], 0
;        mov     esi, [.self]
;        mov     ebx, [.pEvent]
;        mov     eax, [ebx+TSysEvent.event]
;
;        cmp     eax, seKbdKeyPress
;        je      .keypress
;
;        cmp     eax, seFocusIn
;        je      .focusin
;
;        cmp     eax, seFocusOut
;        je      .focusout
;
;        inherited [.pEvent]
;
;.finish:
;        pop     edi esi edx ecx ebx eax
;        return
;
;;............................................................................................
;
;.focusin:
;        mov     [esi+TEdit._Focused], TRUE
;        stdcall CaretAttach, esi
;        or      [.changes], .PosChanged or .ShowCaret
;        jmp     .endmove
;
;.focusout:
;        stdcall CaretShow, FALSE
;        mov     [esi+TEdit._Focused], FALSE
;        or      [.changes], .PosChanged
;        jmp     .endmove
;
;;............................................................................................
;
;.keypress:
;;        mov     eax, [ebx+TKeyboardEvent.kbdStatus]
;;        OutputRegister regEAX, 16
;
;        mov     eax, [esi+TEdit._Pos]
;        mov     [.prevpos], eax
;
;        mov     eax, [ebx+TKeyboardEvent.key]
;        test    eax, eax
;        jz      .no_char
;
;        cmp     eax, $20
;        jb      .no_char
;
;        cmp     eax, $7f
;        je      .no_char
;
;        push    eax
;
;        call    .ClearSelection
;
;        stdcall StrPtr, [esi+TEdit._Text]
;        mov     ecx, eax
;        stdcall StrOffsUtf8, eax, [esi+TEdit._Pos]
;        sub     ecx, eax
;        neg     ecx
;
;        pop     eax
;        stdcall StrCharInsert, [esi+TEdit._Text], eax, ecx
;        inc     [esi+TEdit._Len]
;
;        mov     [ebx+TKeyboardEvent.kbdStatus], 0
;        or      [.changes], .NeedRefresh
;        jmp     .right
;
;.no_char:
;        mov     eax, [ebx+TKeyboardEvent.scancode]
;
;        cmp     eax, keyLeftNumpad
;        je      .left
;        cmp     eax, keyLeft
;        je      .left
;
;        cmp     eax, keyRightNumpad
;        je      .right
;        cmp     eax, keyRight
;        je      .right
;
;        cmp     eax, keyHomeNumpad
;        je      .home
;        cmp     eax, keyHome
;        je      .home
;
;        cmp     eax, keyEndNumpad
;        je      .end
;        cmp     eax, keyEnd
;        je      .end
;
;        cmp     eax, keyDelNumpad
;        je      .del
;        cmp     eax, keyDelete
;        je      .del
;
;        cmp     eax, keyBackSpace
;        je      .backdel
;
;        jmp     .finish
;
;.left:
;        cmp     [esi+TEdit._Pos], 0
;        jle     .endmove
;
;        or      [.changes], .PosChanged
;        dec     [esi+TEdit._Pos]
;        jmp     .endmove
;
;.right:
;        mov     eax, [esi+TEdit._Pos]
;        cmp     eax, [esi+TEdit._Len]
;        jae     .finish
;
;        or      [.changes], .PosChanged
;        inc     [esi+TEdit._Pos]
;        jmp     .endmove
;
;.home:
;        mov     [esi+TEdit._Pos], 0
;        mov     [esi+TEdit._Start], 0
;        mov     [.changes], .PosChanged or .NeedRefresh
;        jmp     .endmove
;
;.end:
;        mov     eax, [esi+TEdit._Len]
;        mov     [esi+TEdit._Pos], eax
;        or      [.changes], .PosChanged
;        jmp     .endmove
;
;.backdel:
;        call    .ClearSelection
;        jnc     .endmove
;
;        cmp     [esi+TEdit._Pos], 0
;        jle     .endmove
;
;        or      [.changes], .PosChanged
;        dec     [esi+TEdit._Pos]
;
;.del:
;        call    .ClearSelection
;        jnc     .endmove
;
;        mov     eax, [esi+TEdit._Pos]
;        cmp     eax, [esi+TEdit._Len]
;        jae     .finish                ; can't delete after the end of string.
;
;        stdcall StrPtr, [esi+TEdit._Text]
;
;        mov     ecx, eax
;        stdcall StrOffsUtf8, eax, [esi+TEdit._Pos]
;        sub     eax, ecx
;
;        stdcall StrSplit, [esi+TEdit._Text], eax
;        mov     ebx, eax
;
;        stdcall StrPtr, ebx
;        stdcall DecodeUtf8, [eax]
;
;        stdcall StrCopyPart, ebx, ebx, edx, -1
;        stdcall StrCat, [esi+TEdit._Text], ebx
;        stdcall StrDel, ebx
;
;        dec     [esi+TEdit._Len]
;        or      [.changes], .NeedRefresh
;
;.endmove:
;        mov     ebx, [.pEvent]
;        mov     eax, [esi+TEdit._Pos]
;        cmp     [ebx+TSysEvent.event], seKbdKeyPress
;        jne     .setselection
;
;        test    [ebx+TKeyboardEvent.kbdStatus], maskShift
;        jnz     .refresh
;
;.setselection:
;        mov     ecx, [.prevpos]
;        cmp     ecx, [esi+TEdit._Sel]
;        je      @f
;        or      [.changes], .NeedRefresh
;@@:
;        mov     [esi+TEdit._Sel], eax
;
;        test    [.changes], .NeedRefresh
;        jz      .caretmove
;
;.refresh:
;        mov     [esi+TEdit._fShadowReady], 0
;        exec    [.self], TEdit:Refresh
;
;.caretmove:
;        cmp     [esi+TEdit._Focused], 0
;        je      .finish
;
;        test    [.changes], .PosChanged
;        jz      .showcaret
;
;        mov     eax, [esi+TEdit._Pos]
;        cmp     eax, [esi+TEdit._Start]
;        jl      .scroll
;
;        stdcall StrPtr, [esi+TEdit._Text]
;        mov     edi, eax
;
;        stdcall StrOffsUtf8, edi, [esi+TEdit._Pos]
;        mov     ecx, eax
;
;        stdcall StrOffsUtf8, edi, [esi+TEdit._Start]
;        sub     ecx, eax                           ; offset to char under cursor.
;        jns     .leftok
;
;.scroll:
;        mov     eax, [esi+TEdit._Start]
;        sub     eax, 8
;        test    eax, eax
;        jns         @f
;        xor     eax, eax
;@@:
;        mov     [esi+TEdit._Start], eax
;        mov     [.changes], .PosChanged or .NeedRefresh
;        jmp     .endmove
;
;.leftok:
;        mov     edi, eax                           ; pointer to start of the text.
;
;        stdcall AllocateContext, [esi+TEdit.handle]
;        push    eax
;
;        stdcall GetTextBounds, eax, edi, ecx, 0
;        lea     ecx, [eax+2]       ; x coordinate of the cursor.
;        add     ecx, [esi+TEdit._MarginLeft]
;
;        stdcall ReleaseContext ; from the stack.
;
;        mov     eax, [esi+TEdit._width]
;        sub     eax, [esi+TEdit._MarginRight]
;        sub     eax, ecx
;        cmp     eax, 2
;        jge     .caretok
;
;        mov     eax, [esi+TEdit._Start]
;        add     eax, 8
;        cmp     eax, [esi+TEdit._Len]
;        jle     @f
;        mov     eax, [esi+TEdit._Len]
;@@:
;        mov     [esi+TEdit._Start], eax
;
;        mov     [.changes], .PosChanged or .NeedRefresh
;        jmp     .endmove
;
;
;.caretok:
;        mov     edx, [esi+TEdit._height]
;        sub     edx, 4
;
;        stdcall CaretChange, ecx, 2, 1, edx
;
;.showcaret:
;        test    [.changes], .ShowCaret
;        jz      .finish
;
;        stdcall CaretShow, TRUE
;        jmp     .finish
;
;;............................................................................................
;
;
;.ClearSelection:
;        mov     eax, [esi+TEdit._Pos]
;        mov     ecx, [esi+TEdit._Sel]
;        cmp     eax, [esi+TEdit._Sel]
;        je      .noselection            ; there is no selection.
;        jg      @f
;        xchg    eax, ecx        ; eax=end_selection; ecx=beg_selection
;@@:
;        add     [esi+TEdit._Len], ecx
;        sub     [esi+TEdit._Len], eax
;        mov     [esi+TEdit._Pos], ecx
;        mov     [esi+TEdit._Sel], ecx
;
;        push    -1
;        stdcall StrOffsUtf8, [esi+TEdit._Text], eax
;        push    eax
;        stdcall StrOffsUtf8, [esi+TEdit._Text], ecx
;        push    eax
;        stdcall StrPtr, [esi+TEdit._Text]
;        sub     [esp], eax     ; begin of the selection
;        sub     [esp+4], eax
;        mov     eax, [esp]
;        sub     [esp+4], eax   ; length of the selection
;
;        stdcall StrSplit, [esi+TEdit._Text]  ; position from the stack
;        mov     ecx, eax
;        stdcall StrCopyPart, ecx, ecx   ; pos and length from the stack.
;        stdcall StrCat, [esi+TEdit._Text], ecx
;        stdcall StrDel, ecx
;
;        or      [.changes], .PosChanged or .NeedRefresh
;        clc
;        retn
;
;.noselection:
;        stc
;        retn
;endp


endmodule


;        stdcall DecodeUtf8, [edi]
;        jc      .finish
;
Changes to freshlib/gui/TForm.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31




32
33
34
35

















36


37
















38
39
40
41
42

43

44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64

65
66
67
68














69
70

71






72
73
74
75










76
77

78


79




80
81
82


83




84


85
86

87
88

89
90


91
92
93














































































































































































































































94
95
96




97
98
99


100

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

83
84

85
86
















87
88
89
90




91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113




114
115
116
117
118
119
120
121
122
123
124

125
126
127
128

129
130
131
132
133


134
135
136
137
138
139
140

141
142
143

144
145

146
147
148
149
150



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389


390
391
392
393
394
395
396
397
398
399
400













+


















+
+
+
+




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





+
-
+

-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

+

+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+

+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
+

+
+
-
+
+
+
+

-
-
+
+

+
+
+
+
-
+
+

-
+

-
+


+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
+
+
+
+



+
+

+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: TForm object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Represents form window that to serve as parent window for other controls.
;_________________________________________________________________________________________

module "TForm library"


mrNone   = 0
mrOK     = 1
mrCancel = 2
mrAbort  = 3
mrRetry  = 4
mrIgnore = 5
mrYes    = 6
mrNo     = 7
mrMaybe  = 8


object TForm, TWindow

  ._modal_result dd ?
  ._OnClose      dd ?         ; On close window event handler.

  ._p_split_grid     dd ?
  ._p_split_template dd ?
  ._drag_splitter    dd ?

  param .ModalResult, ._modal_result, ._modal_result
  param .OnClose, ._OnClose, ._OnClose

  param .SplitGrid, ._p_split_grid, .SetSplitGrid

  method .__RealignSplitGrid

  method .SetSplitGrid, .value
  method .AttachControlToCell, .pWindow, .idCell

  method .SetWidth, .value
  method .SetHeight, .value

  method .EventMouseMove, .x, .y, .kbdState
  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventButtonRelease, .button, .kbdState, .x, .y

  method .EventResize, .newWidth, .newHeight

  method .CloseRequest, .reason
  method .SysEventHandler, .pEvent
  method .Paint

endobj


;----------------------------------------------------------------------
; Interface for TForm.OnClose user handler.
; Arguments:
;   .self - pointer to the TForm object
;   .reason - the reason for the close request.
;
; Returns:
;   CF = 1 - Ignore the request. The form will not be closed.
;   CF = 0 - Destroy the object.
;
; If the OnClose event handler is not set, the form will be destroyed.
;----------------------------------------------------------------------
interface TForm.OnClose, .self, .reason



; OS independent code.



method TForm.SysEventHandler
method TForm.Paint
begin
        push    ebx esi
        pushad

        mov     ebx, [.pEvent]
        cmp     [ebx+TSysEvent.event], sePaint
        je      .onpaint

        cmp     [ebx+TSysEvent.event], seCloseRequest
        je      .close_request

        ; call the inherited event handler...
.inherited:
        inherited [.pEvent]

.finish:
        pop     esi ebx
        return

.onpaint:
        mov     esi, [.self]
        get     edi, esi, TWindow:Canvas

        stdcall DrawSolidRect, edi, 0, 0, [esi+TWindow._width], [esi+TWindow._height], [GUI.clDialogBk]
        mov     eax, [ebx+TPaintEvent.rect.right]
        mov     ecx, [ebx+TPaintEvent.rect.bottom]
        sub     eax, [ebx+TPaintEvent.rect.left]
        sub     ecx, [ebx+TPaintEvent.rect.top]

        mov     ebx, [esi+TForm._p_split_grid]
        test    ebx, ebx
        jz      .finish

        lea     ebx, [ebx+TArray.array]
        stdcall DrawSplitters, edi, ebx

.finish:
        inherited
        popad
        return
endp


        stdcall DrawFillRect, [ebx+TPaintEvent.context], [ebx+TPaintEvent.rect.left], [ebx+TPaintEvent.rect.top], eax, ecx, [clDialogBk]


method TForm.EventResize        ;, .newWidth, .newHeight
begin
        inherited [.newWidth], [.newHeight]
        exec      [.self], TForm:__RealignSplitGrid
        return
endp
  if defined options.DebugMode & options.DebugMode
        stdcall DrawLine, [ebx+TPaintEvent.context], 0, 0, [esi+TWindow._width], [esi+TWindow._height]
        stdcall DrawLine, [ebx+TPaintEvent.context], [esi+TWindow._width], 0, 0, [esi+TWindow._height]
  end if




method TForm.SetWidth
begin
        inherited [.value]
        exec      [.self], TForm:__RealignSplitGrid
        return
endp

        DebugMsg "Window OnPaing event."


method TForm.SetHeight
begin
        jmp     .inherited
        inherited [.value]
        exec      [.self], TForm:__RealignSplitGrid
        return
endp

.close_request:
;        DebugMsg "Close request"



method TForm.CloseRequest     ;, .reason
begin
        push    eax

        get     eax, esi, TForm:OnClose
        get     eax, [.self], TForm:OnClose

        test    eax, eax
        jz      @f
        jz      .destroy

        stdcall eax, esi, [ebx+TCloseEvent.reason]      ; if OnClose return CF=0 the form is destroyed. Else, the form is not destroyed.
        stdcall eax, [.self], [.reason]
        jc      .finish

.destroy:
        destroy [.self]
@@:
        set     esi, TForm:Visible, FALSE
        destroy esi

.finish:
        pop     eax
        return
endp



; sets the splitgrid from a template.

method TForm.SetSplitGrid
begin
        pushad
        mov     esi, [.self]
        mov     edx, [.value]
        cmp     edx, [esi+TForm._p_split_template]
        je      .finish

        mov     [esi+TForm._p_split_template], edx

        mov     ecx, [esi+TForm._p_split_grid]
        test    ecx, ecx
        jz      .old_ok

        stdcall FreeMem, ecx

.old_ok:
        test    edx, edx
        jz      .finish

        stdcall ReadSplitGridTemplate, edx
        mov     [esi+TForm._p_split_grid], eax

        exec    esi, TForm:__RealignSplitGrid

.finish:
        popad
        return
endp





method TForm.AttachControlToCell;, .pWindow, .idCell
begin
        pushad
        mov     esi, [.self]
        mov     edi, [esi+TForm._p_split_grid]
        test    edi, edi
        jz      .finish

        mov     eax, [.idCell]
        cmp     eax, [edi+TArray.count]
        jae     .finish

        imul    eax, sizeof.TSplitRect
        lea     edi, [edi+TArray.array+eax]

        push    [.pWindow]
        pop     [edi+TSplitRect.pWindow]

        exec    [.self], TForm:__RealignSplitGrid

.finish:
        popad
        return
endp



method TForm.__RealignSplitGrid
.rect RECT
begin
        pushad

        mov     esi, [.self]
        mov     ebx, [esi+TForm._p_split_grid]
        test    ebx, ebx
        jz      .finish

        lea     ebx, [ebx+TArray.array]

        xor     eax, eax
        get     ecx, esi, TWindow:width
        get     edx, esi, TWindow:height

        mov     [.rect.left], eax
        mov     [.rect.top], eax
        mov     [.rect.right], ecx
        mov     [.rect.bottom], edx

        lea     eax, [.rect]
        stdcall RealignGrid, ebx, eax

        exec    esi, TWindow:Refresh

.finish:
        popad
        return
endp






method TForm.EventMouseMove     ;, .x, .y, .kbdState
begin
        pushad

        mov     ebx, [.self]

        mov     esi, [ebx+TForm._drag_splitter]
        test    esi, esi
        jz      .find_splitter

        mov     ecx, [esi+TSplitRect.type]
        and     ecx, stVert
        mov     eax, [.x+ecx] ; the respective coordinate.

        sub     eax, [esi+TSplitRect.rect.left+ecx]

        test    [esi+TSplitRect.type], stOriginBR
        jz      .sizeok

        mov     edx, [esi+TSplitRect.rect.right+ecx]
        sub     edx, [esi+TSplitRect.rect.left+ecx]
        sub     eax, edx
        neg     eax

        sub     eax, [esi+TSplitRect.spWidth]

.sizeok:
        test    [esi+TSplitRect.type], stRelative
        jz      .posok

        cdq
        mov     ebx, $8000
        imul    ebx

        mov     ebx, [esi+ecx+TSplitRect.rect.right]
        sub     ebx, [esi+ecx+TSplitRect.rect.left]     ; size of rect (x or y depending on type)

        idiv    ebx

.posok:
        mov     [esi+TSplitRect.pos], eax
        stdcall RealignGrid, esi, esi

        exec    [.self], TWindow:RectChanged, esi
        exec    [.self], TWindow:Refresh

.finish:
        popad
        inherited [.x], [.y], [.kbdState]
        return


.find_splitter:
        mov     edi, [ebx+TForm._p_split_grid]
        test    edi, edi
        jnz     .found

.set_default:
        mov     ecx, [ebx+TForm._cursor]
        jmp     .setit

.found:
        lea     edi, [edi+TArray.array]

        lea     eax, [.x]
        stdcall FindSplitter, edi, eax
        jnc     .set_default

        test    [eax+TSplitRect.type], stJustGap
        jnz     .finish

        mov     ecx, mcSizeH
        test    [eax+TSplitRect.type], stVert
        jz      .setit
        mov     ecx, mcSizeV

.setit:
        stdcall GetStockCursor, ecx

        get     edx, ebx, TWindow:OSWindow
        stdcall SetMouseCursor, [edx+TWindow.handle], eax
        jmp     .finish

endp



method TForm.EventButtonPress   ;, .button, .kbdState, .x, .y
  .pnt POINT
  .cliprect RECT
begin
        pushad

        mov     esi, [.self]
        mov     ebx, [esi+TForm._p_split_grid]
        test    ebx, ebx
        jz      .finish

        lea     ebx, [ebx+TArray.array]

        mov     eax, [.x]
        mov     ecx, [.y]
        mov     [.pnt.x], eax
        mov     [.pnt.y], ecx

        lea     eax, [.pnt]
        stdcall FindSplitter, ebx, eax
        jnc     .finish

        test    [eax+TSplitRect.type], stJustGap
        jnz     .finish

        mov     [esi+TForm._drag_splitter], eax

        stdcall SetMouseCapture, esi

.finish:
        popad
        inherited [.button], [.kbdState], [.x], [.y]
        return
endp



method TForm.EventButtonRelease ;, .button, .kbdState, .x, .y
begin
        push    eax

        mov     eax, [.self]
        mov     [eax+TForm._drag_splitter], 0
        stdcall SetMouseCapture, 0

        DebugMsg "Form destroyed"
        jmp      .finish
.finish:
        pop     eax
        inherited [.button], [.kbdState], [.x], [.y]
        return
endp




endmodule

Changes to freshlib/gui/TImageLabel.asm.
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92

93
94
95
96
97
98
99
100

101
102
103

104
105
106
107
108
109
110
111
112


113
114
115
116
117
118
119

120
121
122
123
124
125
126







127
128
129

130
131

132
133

134
135

136
137
138

139
140

141
142

143
144

145
146
147








148
149
150
151
152
153
154
155
156
157
19
20
21
22
23
24
25
26
27
28
29
30


31
32
33


34
35
36

37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70



71













72
73

74
75
76


77



78



79

80




81


82
83



84



85





86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121


122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138







+




-
-



-
-



-

-
+
















+















-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
+

-
+


-
-

-
-
-
+
-
-
-
+
-

-
-
-
-

-
-
+
+
-
-
-

-
-
-
+
-
-
-
-
-


+
+
+
+
+
+
+



+


+


+


+



+


+


+


+

-
-
+
+
+
+
+
+
+
+

-








iaCenter = 2
iaStretchH = 3

iaTop = $0
iaBottom = $100
iaMiddle = $200
iaStrechV = $300


object TImageLabel, TWindow
  ._ImageAlign dd ?
  ._Image      dd ?
  ._Mask       dd ?
  ._Background dd ?

  param .ImageAlign, ._ImageAlign, .SetImageAlign       ; image align flags.
  param .Image, ._Image, .SetImage                      ; TImage object
  param .Mask, ._Mask, .SetMask
  param .Background, ._Background, ._Background

  method .SetImageAlign, .value
  method .SetImage, .value
  method .SetMask, .value

  method .SysEventHandler, .pEvent
  method .Paint
endobj


method TImageLabel.SetImageAlign
begin
        push    eax

        mov     eax, [.self]
        push    [.value]
        pop     [eax+TImageLabel._ImageAlign]

        exec    eax, TWindow:Refresh
        pop     eax
        return
endp



method TImageLabel.SetImage
begin
        push    eax

        mov     eax, [.self]
        push    [.value]
        pop     [eax+TImageLabel._Image]

        exec    eax, TWindow:Refresh
        pop     eax
        return
endp


method TImageLabel.SetMask
begin
        push    eax

        mov     eax, [.self]
        push    [.value]
        pop     [eax+TImageLabel._Mask]

        exec    eax, TWindow:Refresh
        pop     eax
        return
endp




method TImageLabel.SysEventHandler
method TImageLabel.Paint
begin
        push    eax ebx ecx edx esi
        pushad

        mov     esi, [.self]
        mov     ebx, [.pEvent]
        mov     eax, [ebx+TSysEvent.event]

        cmp     eax, sePaint
        je      .onpaint

        exec    esi, TWindow:__UpdateCanvas
.finish:
        stc
        pop     esi edx ecx ebx eax
        mov     edi, [esi+TWindow._canvas]
        return

.onpaint:
  locals
   .bounds TBounds
  endl
        mov     ecx, [esi+TImageLabel._width]
        mov     eax, [esi+TImageLabel._height]
        mov     [.bounds.x], 0
        mov     edx, [esi+TImageLabel._height]
        xor     eax, eax
        mov     [.bounds.y], 0
        mov     [.bounds.width], ecx
        mov     [.bounds.height], eax

        stdcall SetDrawMode, [ebx+TPaintEvent.context], cmCopy
        stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], [clDialogBk]

        stdcall DrawSolidRect, edi, eax, eax, ecx, edx, eax    ; clear with transparency.
        mov     eax, [esi+TImageLabel._Image]
        mov     ecx, [.bounds.width]
        mov     edx, [.bounds.height]
        sub     ecx, [eax+TImage.width]
        sub     edx, [eax+TImage.height]

        mov     eax, [esi+TImageLabel._ImageAlign]
        mov     esi, [esi+TImageLabel._Image]

        test    esi, esi
        jz      .finish

        sub     ecx, [esi+TImage.width]
        sub     edx, [esi+TImage.height]

        cmp     al, iaRight
        je      .x_ok

        cmp     al, iaCenter
        je      .x_center

        xor     ecx, ecx
        jmp     .x_ok

.x_center:
        sar     ecx, 1

.x_ok:
        cmp     ah, iaBottom /256
        je      .y_ok

        cmp     ah, iaMiddle / 256
        je      .y_center

        xor     edx, edx
        jmp     .y_ok

.y_center:
        sar     edx, 1

.y_ok:
        stdcall DrawMaskedImage, [ebx+TPaintEvent.context], [esi+TImageLabel._Mask], [esi+TImageLabel._Image], ecx, edx
        jmp     .finish

        xor     eax, eax
;        stdcall BlendImage, edi, ecx, edx, esi, eax, eax, [esi+TImage.width], [esi+TImage.height]
        stdcall CopyImageRect, edi, ecx, edx, esi, eax, eax, [esi+TImage.width], [esi+TImage.height]

.finish:
        popad
        return
endp








endmodule
Changes to freshlib/gui/TLabel.asm.
9
10
11
12
13
14
15
16

17


18

19

20
21
22

23
24



25


26
27















28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45


46
47
48
49
50
51
52

53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
68
69


70
71

72

73












74
75
76
77
78
79
80
81
82




83
84
85
86





87
88
89
90
91
92
93
94
95
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25

26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66


67
68
69
70
71
72



73


74





75





76
77


78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101




102
103
104
105




106
107
108
109
110
111
112
113
114
115
116
117
118
119








+

+
+
-
+

+


-
+


+
+
+
-
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
















-
-
+
+




-
-
-
+
-
-

-
-
-
-
-
+
-
-
-
-
-


-
-
+
+


+

+
-
+
+
+
+
+
+
+
+
+
+
+
+





-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
+









;
;  Dependencies:
;
;  Notes: Not finished.
;_________________________________________________________________________________________
module "TLabel library"



object TLabel, TWindow

; private fields
  ._textalign dd ?
  ._textalign  dd ?

; parameters
  param .TextAlign, ._textalign, .SetTextAlign        ; text align flags.


; parameter methods
  method .SetTextAlign, .value

; other methods
  method .Create, .parent

  method .SysEventHandler, .pEvent
  method .Paint

endobj



method TLabel.Create
begin
        push    eax ecx

        inherited [.parent]

        mov     eax, [.self]
        mov     [eax+TLabel._textalign], dtfAlignLeft or dtfAlignMiddle or dtfCRLF or dtfWordWrap

        pop     ecx eax
        return
endp


method TLabel.SetTextAlign
begin
        push    eax

        mov     eax, [.self]
        push    [.value]
        pop     [eax+TLabel._textalign]

        exec    eax, TWindow:Refresh
        pop     eax
        return
endp




method TLabel.SysEventHandler
method TLabel.Paint
 .bounds TBounds
begin
        pushad

        mov     esi, [.self]
        mov     ebx, [.pEvent]
        mov     eax, [ebx+TSysEvent.event]

        exec    esi, TWindow:__UpdateCanvas
        cmp     eax, sePaint
        je      .onpaint

.finish:
        stc
        popad
        return

        xor     edx, edx
.onpaint:
  locals
   .bounds TBounds
  endl

        mov     ecx, [esi+TLabel._width]
        mov     eax, [esi+TLabel._height]
        mov     [.bounds.x], 0
        mov     [.bounds.y], 0
        mov     [.bounds.x], edx
        mov     [.bounds.y], edx
        mov     [.bounds.width], ecx
        mov     [.bounds.height], eax

        lea     eax, [.bounds]
        stdcall [DrawBox], [esi+TWindow._canvas], eax, [GUI.clLabelBk], bxNone, [GUI.boxBorderWidth]
        stdcall [DrawBox], [ebx+TPaintEvent.context], eax, [clDialogBk], bxNone

        mov     eax, [GUI.btnMarginX]
        mov     ecx, [GUI.btnMarginY]

        add     [.bounds.x], eax
        add     [.bounds.y], ecx

        shl     eax, 1
        shl     ecx, 1

        sub     [.bounds.width], eax
        sub     [.bounds.height], ecx

        get     eax, esi, TWindow:Caption
        test    eax, eax
        jz      .finish

        push    eax eax
        stdcall StrLen, eax
        mov     ecx, eax
        pop     eax
        stdcall DrawTextBox, [esi+TWindow._canvas], eax, [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], 2, [esi+TLabel._textalign], [GUI.DefaultFont], [GUI.clLabelTxt]
        stdcall StrDel, eax


        lea     edx, [.bounds]
        stdcall DrawTextBox, [ebx+TPaintEvent.context], eax, edx, [esi+TLabel._textalign], 0, [clDialogTxt]
        stdcall StrDel ; from the stack
        jmp     .finish
.finish:
        inherited

        popad
        return
endp







endmodule
Changes to freshlib/gui/TMenu.asm.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23


















24

25
26
27
28
29
30

















31
32





33
34
35
36




37


38


39

40









41


42
43















































































44
45

46
47
48
49






































































































50


51

52
53






54




















55
56





































































57


58
59





60



61
62






63























































































64
65
66
67
68
























































69


70
71












































72



































































73
74
75
76
77
78





































79


















































80
81




82

83

84



85





86



















































87
88
89
90




91


92









































93































94

95
96
97
98
99
100
9
10
11
12
13
14
15








16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35






36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170




171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277


278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378


379
380
381
382
383
384
385
386
387


388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481





482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540


541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652






653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740


741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813

814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902







-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+
+
+
+
+




+
+
+
+

+
+

+
+

+
-
+
+
+
+
+
+
+
+
+

+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+

+
-
-
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
-
-
+
+
+
+
+

+
+
+
-
-
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+

+

+

+
+
+

+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
+
+
+
+

+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+






;
;  Dependencies:
;
;  Notes: Represents main menu or popup menu objects.
;_________________________________________________________________________________________
module "TMenu library"

;ObjectClass Menu,         \
;            Window,       \
;            TMenu.Create, \
;            TMenu.Destroy,\
;            TMenu.Get,    \
;            TMenu.Set,    \
;            TMenu.ExecCmd,\
;            TMenu.SysEventHandler

mitSeparator = 0
mitAction    = 1
mitSubmenu   = 2
mitString    = 3        ; contains simple text string can't have accelerator and icons.


struct TMenuItem
  .type dd ?
  .item dd ?    ; different for the different types of items: NULL, pointer to TAction, pointer to TMenu, handle of string.
ends



object TMenu, TWindow
  ._p_items   dd ?
  ._selected  dd ?
  .__caller   dd ?

  .__icon_size dd ?
; The inherited TWindow.caption serves as a menu item caption in the parent menu.
; The children TMenu objects are reparent to the root, and their pointers are stored in the
; list of TMenuItem elements.
object TMenu, TWindow
  .pForm  dd ?       ; pointer to TForm object. If NULL, the menu is popup menu.
  .pItems dd ?       ;

  param .Selected, ._selected, .SetSelected
  param .Items, ._p_items, .SetItems
  param .LineHeight, .GetLineHeight, NONE

  method .GetLineHeight

  method .SetSelected, .value
  method .SetItems, .menu_template
  method .SetVisible, .value

  method .AddItem, .Type, .Item

  method .Paint

  method .Create, .Parent
  method .Destroy

  method .Show, .parent, .kind
  method .Show, .parent, .x, .y

  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventMouseMove, .x, .y, .kbdState

endobj



method TMenu.Create
begin
        stdcall CreateArray, 8
        push    eax

        mov     eax, [.self]
        pop     [eax+TMenu._p_items]

        mov     [eax+TMenu.__want_focus], 0
        mov     [eax+TMenu._selected], -1

        inherited 0
proc TMenu.Create, .obj

        set     [.self], TWindow:border, borderNone
        return
endp




method TMenu.Destroy
begin
        mov     eax, [.self]
        stdcall FreeMem, [eax+TMenu._p_items]
        return
endp



method TMenu.GetLineHeight
begin
        pushad
        mov     esi, [.self]

        stdcall GetFontMetrics, [GUI.DefaultFont]

        mov     ecx, [esi+TMenu.__icon_size]
        mov     edx, [GUI.menuIconMargin]
        add     ecx, edx

        cmp     eax, ecx
        cmovb   eax, ecx

        mov     [esp+4*regEAX], eax
        popad
        return
endp



method TMenu.SetItems
begin
        pushad




        popad
        return
endp


method TMenu.AddItem
begin
        pushad

        mov     esi, [.self]
        mov     edx, [esi+TMenu._p_items]

        stdcall AddArrayItems, edx, 1

        pushd   [.Type]
        pushd   [.Item]
        popd    [eax+TMenuItem.item]
        popd    [eax+TMenuItem.type]

        mov     [esi+TMenu._p_items], edx

        popad
        return
endp




method TMenu.SetVisible ;
.max dd ?
.str dd ?
begin
        pushad

        mov     esi, [.self]

        cmp     [.value], FALSE
        je      .switch_off

        get     edx, esi, TMenu:Items

        mov     ecx, [edx+TArray.count]
        test    ecx, ecx
        jnz     .compute_width

        stdcall GetTextBounds, "Empty menu", 10, [GUI.DefaultFont]
        add     eax, 20
        jmp     .set_width


.compute_width:
proc TMenu.Destroy, .obj
begin
        return
endp

        mov     [.max], 0
        mov     [esi+TMenu.__icon_size], 0

.loop:
        dec     ecx
        js      .end_width

        lea     ebx, [edx+TArray.array+8*ecx]    ; pointer to TMenuItem

        cmp     [ebx+TMenuItem.type], mitSeparator
        je      .loop

        cmp     [ebx+TMenuItem.type], mitAction
        je      .action

        cmp     [ebx+TMenuItem.type], mitSubmenu
        je      .submenu

; it is string.

        stdcall StrDup, [ebx+TMenuItem.item]
        push    eax
        jmp     .str_width

.submenu:
        get     eax, [ebx+TMenuItem.item], TMenu:Caption
        push    eax

        stdcall StrCat, eax, txt "  >"
        jmp     .str_width

.action:
        get     eax, [ebx+TMenuItem.item], TAction:Icon
        test    eax, eax
        jz      .icon_ok

        mov     eax, [eax+TImage.height]

        cmp     eax, [esi+TMenu.__icon_size]
        jbe     .icon_ok
        mov     [esi+TMenu.__icon_size], eax

.icon_ok:

        get     eax, [ebx+TMenuItem.item], TAction:AccelStr
        push    eax

        get     edi, [ebx+TMenuItem.item], TAction:Caption
        stdcall StrCat, eax, edi


.str_width:
        stdcall StrPtr, eax
        push    edx
        stdcall GetTextBounds, eax, [eax+string.len], [GUI.DefaultFont]
        pop     edx

        stdcall StrDel ; from the stack

        cmp     eax, [.max]
        jbe     .loop

        mov     [.max], eax

        jmp     .loop

.end_width:


; here compute the size of the menu and set .width and .height fields.

        mov     edx, [GUI.iconMenuChecked]
        mov     eax, [edx+TImage.width]
        add     eax, [esi+TMenu.__icon_size]

        add     eax, [.max]
        add     eax, [GUI.menuMinTextDist]

        mov     edx, [GUI.menuIconMargin]
        lea     edx, [3*edx]
        add     eax, edx
        mov     edx, [GUI.boxBorderWidth]
        lea     eax, [eax+2*edx]


.set_width:
        set     esi, TWindow:width, eax

        get     ecx, esi, TMenu:LineHeight
        get     edx, esi, TMenu:Items

        mov     eax, [edx+TArray.count]
        imul    eax, ecx

        test    eax, eax
        jnz     @f
        add     eax, ecx
@@:

        mov     ecx, [GUI.boxBorderWidth]
        lea     eax, [eax+2*ecx]

        mov     ecx, [GUI.menuIconMargin]
        lea     eax, [eax+2*ecx]

        set     esi, TWindow:height, eax
proc TMenu.Get, .obj, .param
begin


.finish:
        popad

        inherited [.value]
        return


.switch_off:
        xor     ecx, ecx

        mov     eax, [esi+TMenu.__caller]
        test    eax, eax
        jz      .set_active

        istype  eax, TMenu
        cmove   ecx, eax
        je      .set_active

; remove capture.
        stdcall SetMouseCapture, ecx    ; ecx is 0 here!!!

.set_active:
        mov     [__ActiveMenu], ecx
        jmp     .finish

endp



method TMenu.Paint

.bounds TBounds

.y    dd ?
.yTxt dd ?
.xTxt dd ?
.clTxt dd ?

.line dd ?

.canvas dd ?

; item parameters, depend on the item type.

.text    dd ?
.accel   dd ?
.icon    dd ?
.check   dd ?
.enabled dd ?
.subicon dd ?

begin
        pushad
        mov     esi, [.self]

        get     ebx, esi, TWindow:Canvas
        mov     [.canvas], ebx

        xor     eax, eax
        mov     [.bounds.x], eax
        mov     [.bounds.y], eax

        mov     eax, [ebx+TImage.width]
        mov     ecx, [ebx+TImage.height]
        mov     [.bounds.width], eax
        mov     [.bounds.height], ecx

        get     eax, esi, TMenu:LineHeight
        mov     [.line], eax

        lea     eax, [.bounds]
        stdcall [DrawBox], [.canvas], eax, [GUI.clMenuBack], [GUI.borderMenu], [GUI.boxBorderWidth]

        get     edi, esi, TMenu:Items
        test    edi, edi
        jz      .end_loop


; compute the text base line.

        stdcall GetFontMetrics, [GUI.DefaultFont]

        mov     ecx, [.line]
        sub     ecx, eax
        lea     ecx, [ecx+2*ebx]
        sar     ecx, 1
        mov     [.yTxt], ecx

        mov     ecx, [GUI.boxBorderWidth]
        add     ecx, [GUI.menuIconMargin]
        mov     [.y], ecx
        add     [.yTxt], ecx

        mov     ecx, [GUI.menuIconMargin]
        lea     ecx, [3*ecx]
        mov     eax, [esi+TMenu.__icon_size]

        add     ecx, eax
        add     ecx, [GUI.boxBorderWidth]
proc TMenu.Set, .obj, .param
begin

        mov     eax, [GUI.iconMenuChecked]
        add     ecx, [eax+TImage.width]

        mov     [.xTxt], ecx

        xor     ecx, ecx
        cmp     [edi+TArray.count], ecx
        je      .empty_menu
        return
endp

.loop:
        cmp     ecx, [edi+TArray.count]
        jae     .end_loop

        lea     edx, [edi+TArray.array + 8*ecx]         ; pointer to TMenuItem

        mov     eax, [edx+TMenuItem.type]

        cmp     eax, mitSeparator
        je      .draw_separator

        cmp     eax, mitAction
        je      .action

        cmp     eax, mitSubmenu
        je      .submenu

        cmp     eax, mitString
        jne     .next_item

.string:
        stdcall StrDup, [edx+TMenuItem.item]
        mov     [.text], eax

        xor     eax, eax
        mov     [.accel], eax
        mov     [.icon], eax
        mov     [.check], eax
        mov     [.subicon], eax
        inc     eax
        mov     [.enabled], eax
        jmp     .draw_background

.submenu:
        get     eax, [edx+TMenuItem.item], TMenu:Caption
        mov     [.text], eax

        get     eax, [edx+TMenuItem.item], TMenu:Enabled
        mov     [.enabled], eax

        mov     ebx, [GUI.menuSubIconGray]
        test    eax, eax
        jz      @f

        mov     ebx, [GUI.menuSubIcon]

        cmp     ecx, [esi+TMenu._selected]
        jne     @f
        mov     ebx, [GUI.menuSubIconSel]

@@:
        mov     [.subicon], ebx

        xor     eax, eax
        mov     [.icon], eax
        mov     [.check], eax
        mov     [.accel], eax
        jmp     .draw_background


.action:
        mov     [.subicon], 0

        get     eax, [edx+TMenuItem.item], TAction:Caption
        mov     [.text], eax

        get     eax, [edx+TMenuItem.item], TAction:AccelStr
        mov     [.accel], eax

        get     eax, [edx+TMenuItem.item], TAction:Enabled
        mov     [.enabled], eax

        get     eax, [edx+TMenuItem.item], TAction:Icon
        mov     [.icon], eax

        get     eax, [edx+TMenuItem.item], TAction:Checked
        mov     [.check], eax
        jmp     .draw_background


.draw_separator:
        mov     eax, [.bounds.x]
        mov     ebx, [.bounds.width]
        mov     edx, [GUI.menuIconMargin]
        add     eax, edx
        sub     ebx, edx
        sub     ebx, edx

;        stdcall DrawSolidRect, [.canvas], eax, [.y], ebx, 1, $ffff0000
;
;        mov     edx, [.line]
;        add     edx, [.y]
;        dec     edx

proc TMenu.ExecCmd, .obj, .method
begin
        cmp     [.method], TMenu.Show
        je      .show
;
;        stdcall DrawSolidRect, [.canvas], eax, edx, ebx, 1, $ffff0000

        mov     edx, [.line]
        add     edx, [.y]
        add     edx, [.y]
        sar     edx, 1

        stdcall DrawSolidRect, [.canvas], eax, edx, ebx, 1, [GUI.clBorderDark]
        inc     edx
        stdcall DrawSolidRect, [.canvas], eax, edx, ebx, 1, [GUI.clBorderLight]
        jmp     .next_item


; draw the background
.draw_background:
        cmp     ecx, [esi+TMenu._selected]
        jne     .selected_ok

        cmp     [.enabled], 0
        je      .selected_ok

        stdcall DrawSolidRect, [.canvas], [.bounds.x], [.y], [.bounds.width], [.line], [GUI.clEditSel]

.selected_ok:

; draw the icon

        cmp     [.icon], 0
        je      .icon_ok

        mov     ebx, [GUI.iconMenuChecked]
        mov     eax, [ebx+TImage.width]

        add     eax, [GUI.menuIconMargin]
        add     eax, [GUI.menuIconMargin]
        add     eax, [GUI.boxBorderWidth]       ; x-coordinate

        mov     ebx, [.icon]
        test    ebx, ebx
        jz      .icon_ok

        mov     edx, [.line]
        sub     edx, [ebx+TImage.height]
        add     edx, [.y]
        add     edx, [.y]
        sar     edx, 1

        stdcall BlendImage, [.canvas], eax, edx, ebx, 0, 0, [ebx+TImage.width], [ebx+TImage.height]

.icon_ok:

; draw the checkbox

        cmp     [.check], 0
        je      .draw_text

        mov     eax, [GUI.menuIconMargin]
        add     eax, [GUI.boxBorderWidth]
        stc
        return

        mov     ebx, [GUI.iconMenuChecked]

        cmp     [.enabled], 0
        jne     .check_ok

        mov     ebx, [GUI.iconMenuCheckedGray]

.check_ok:
        mov     edx, [.line]
        sub     edx, [ebx+TImage.height]
        add     edx, [.y]
        add     edx, [.y]
        sar     edx, 1

        stdcall BlendImage, [.canvas], eax, edx, ebx, 0, 0, [ebx+TImage.width], [ebx+TImage.height]


.draw_text:

        mov     eax, [GUI.clMenuTextGray]

        cmp     [.enabled], 0
        je      .txt_color_ok

        mov     eax, [GUI.clMenuText]

        cmp     ecx, [esi+TMenu._selected]
        jne     .txt_color_ok

        mov     eax, [GUI.clEditSelTxt]

.txt_color_ok:
        mov     [.clTxt], eax

        push    eax
        push    [GUI.DefaultFont]
        push    [.yTxt]
        pushd   [.xTxt]

        stdcall StrLen, [.text]
        push    eax

        stdcall StrPtr, [.text]

        stdcall DrawString, [.canvas], eax    ; remaining from the stack

        stdcall StrDel, [.text]

; draw the submenu arrow
        mov     ebx, [.subicon]
        test    ebx, ebx
        jz      .draw_accelerator

        mov     eax, [.bounds.width]
        sub     eax, [ebx+TImage.width]
        sub     eax, [GUI.menuIconMargin]

        mov     edx, [.line]
        sub     edx, [ebx+TImage.height]
        add     edx, [.y]
        add     edx, [.y]
        sar     edx, 1

        stdcall BlendImage, [.canvas], eax, edx, ebx, 0, 0, [ebx+TImage.width], [ebx+TImage.height]
        jmp     .next_item

; draw the accelerator
.draw_accelerator:
        cmp     [.accel], 0
        je      .next_item

        stdcall StrPtr, [.accel]
        push    eax

        stdcall GetTextBounds, eax, [eax+string.len], [GUI.DefaultFont]

        mov     edx, [.bounds.width]
        sub     edx, [GUI.boxBorderWidth]
        sub     edx, [GUI.menuIconMargin]
        sub     edx, eax

        pop     eax
        stdcall DrawString, [.canvas], eax, [eax+string.len], edx, [.yTxt], [GUI.DefaultFont], [.clTxt]

        stdcall StrDel, [.accel]


.next_item:
        mov     eax, [.line]
        add     [.y], eax
        add     [.yTxt], eax

        inc     ecx
        jmp     .loop


.end_loop:

        popad
        return

.empty_menu:
        stdcall DrawString, [.canvas], "Empty menu", 10, 10, 14, [GUI.DefaultFont], [GUI.clMenuText]
        stdcall FilterDisabled, [.canvas], FALSE
        jmp     .end_loop

endp




; Method show
.show:
virtual at esi
  .parent dd ?
  .kind   dd ?
end virtual
method TMenu.Show
begin
        pushad

        mov     esi, [.self]
        mov     edi, [.parent]

        istype edi, TMenu
        je     .capture_ok

        stdcall SetMouseCapture, edi

.capture_ok:
        exec    edi, TWindow:ClientToScreenXY, [.x], [.y]

        mov     [esi+TWindow._x], ecx
        mov     [esi+TWindow._y], edx
        mov     [esi+TMenu._selected], 0

        mov     [esi+TMenu.__caller], edi
        mov     [__ActiveMenu], esi
        set     esi, TMenu:Visible, TRUE

        popad
        return
endp




proc AcceleratorToStr, .pFastKey
begin
        push    ecx edx

        mov     edx, [.pFastKey]
        test    edx, edx
        jz      .empty

        mov     eax, [edx+TFastKey.key]         ; scan code
        xor     ecx, ecx                        ; utf8

        test    eax, eax
        js      @f
        xchg    ecx, eax
@@:
        and     eax, $7fffffff
        stdcall CreateKeyName, ecx, eax, [edx+TFastKey.flags]
        jnc     .finish

.empty:
        stdcall StrNew
        stc

.finish:
        pop     edx ecx
        return
endp



method TMenu.SetSelected
begin
        pushad

        mov     esi, [.self]
        mov     ecx, [.value]
        cmp     ecx, [esi+TMenu._selected]
        je      .finish

        get     edi, esi, TMenu:Items
        test    edi, edi
        jz      .finish

        cmp     ecx, [edi+TArray.count]
        jae     .finish

        mov     [esi+TMenu._selected], ecx
        exec    esi, TWindow:Refresh

        lea     edx, [edi+TArray.array+8*ecx]
        cmp     [edx+TMenuItem.type], mitSubmenu
        jne     .hide_old

        get     eax, [edx+TMenuItem.item], TMenu:Enabled
        test    eax, eax
        jz      .finish

        get     ebx, esi, TMenu:LineHeight
        mov     ebx, [.obj]
; First check item count and set proper size of the menu window.
        imul    ebx, ecx

        mov     eax, [esi+TMenu._width]
        sub     eax, [GUI.menuIconMargin]

        exec    [edx+TMenuItem.item], TMenu:Show, esi, eax, ebx

        jmp     .finish

.hide_old:
        cmp     [__ActiveMenu], esi
        je      .finish

        set     [__ActiveMenu], TWindow:Visible, FALSE
        mov     [__ActiveMenu], esi

.finish:
        popad
        return
endp



method TMenu.EventMouseMove
begin
        pushad

        mov     esi, [.self]

        mov     ecx, [.x]
        mov     edx, [.y]
        sub     ecx, [esi+TMenu._x]
        js      .check_caller
        sub     edx, [esi+TMenu._y]
        js      .check_caller

        cmp     ecx, [esi+TMenu._width]
        jge     .check_caller

        cmp     edx, [esi+TMenu._height]
        jge      .check_caller

        sub     edx, [GUI.boxBorderWidth]
        js      .exit

        sub     edx, [GUI.menuIconMargin]
        js      .exit

        get     ecx, esi, TMenu:LineHeight

        mov     eax, edx
        cdq
        idiv    ecx

        set     esi, TMenu:Selected, eax

.exit:
        popad
        return

.check_caller:
        mov     esi, [esi+TMenu.__caller]
        test    esi, esi
        jz      .exit

        istype  esi, TMenu
        jne     .exit

        exec    esi, TMenu:EventMouseMove, [.x], [.y], [.kbdState]
        jmp     .exit
endp


proc TMenu.SysEventHandler, .obj, .event



method TMenu.EventButtonPress
begin
        pushad
        mov     esi, [.self]

        mov     ecx, [.x]
        mov     edx, [.y]

        sub     ecx, [esi+TMenu._x]
        js      .check_caller
        sub     edx, [esi+TMenu._y]
        js      .check_caller
        cmp     ecx, [esi+TMenu._width]
        jge     .check_caller
        cmp     edx, [esi+TMenu._height]
        jge     .check_caller

        mov     ecx, [esi+TMenu._selected]
        mov     edx, [esi+TMenu._p_items]

        cmp     ecx, [edx+TArray.count]
        jae     .finish

        lea     edi, [edx+TArray.array+8*ecx]

        cmp     [edi+TMenuItem.type], mitSeparator
        je      .finish

        cmp     [edi+TMenuItem.type], mitString
        je      .finish                                 ; temporary, until I decide what to do with the string items.

        cmp     [edi+TMenuItem.type], mitSubmenu
        je      .finish

        cmp     [edi+TMenuItem.type], mitAction
        jne     .finish

        get     eax, [edi+TMenuItem.item], TAction:Enabled
        test    eax, eax
        jz      .finish

        call    .hideall
        exec    [edi+TMenuItem.item], TAction:Execute, [.self]   ; execute the action.

.finish:
        popad
        return


.check_caller:
        set     esi, TMenu:Visible, FALSE       ; hide the menu

        mov     esi, [esi+TMenu.__caller]
        test    esi, esi
        jz      .finish

        istype  esi, TMenu
        jne     .finish

        mov     [esi+TMenu._selected], -1
        exec    esi, TMenu:EventMouseMove, [.x], [.y], [.kbdState]
        exec    esi, TMenu:EventButtonPress, [.button], [.kbdState], [.x], [.y]
        jmp     .finish


.hideall:
        cmp     [__ActiveMenu], 0
        jne     @f

        retn

@@:
        set     [__ActiveMenu], TMenu:Visible, FALSE       ; hide the menu
        jmp     .hideall




endp




endmodule


Deleted freshlib/gui/TMenuItem.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40








































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: TMenuItem object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: TMenuItems are the items of the GUI menu objects.
;_________________________________________________________________________________________
module "TMenuItem library"

;ObjectClass MenuItem,         \
;            Object,           \
;            TMenuItem.Create, \
;            TMenuItem.Destroy,\
;            TMenuItem.Get,    \
;            TMenuItem.Set,    \
;            TMenuItem.ExecCmd,\
;            0

mikCommand   = 0
mikSubmenu   = 1
mikSeparator = 2


object TMenuItem, TObject
  .parent   dd ?        ; pointer to TMenu object.
  .kind     dd ?        ; mikCommand, mikSubmenu or mikSeparator
  .pAction  dd ?        ; depending on the kind. Pointer to TAction or handle of string with the text.
  .child    dd ?        ; pointer to the child TMenu object

  method Paint, .context, .x, .y, .width, .height
endobj


endmodule
Changes to freshlib/gui/TObject.asm.
22
23
24
25
26
27
28


29

30



31
32
33
34
35
36
37
38

39
40

41



42
43
44
45
46
47
48
49

50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82
83
84





























































































































































85
86
87
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47

48
49
50
51
52
53



54

55


56

57



58

59









60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236







+
+

+

+
+
+







-
+


+
-
+
+
+



-
-
-

-
+
-
-
+
-

-
-
-

-

-
-
-
-
-
-
-
-
-












+




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



    ._mxAccess  TMutex  ; access mutex. Procedures from objects.asm will use it to ensure thread safety.
  end if

  ._OnCreate  dd ?
  ._OnDestroy dd ?
  ._ptrVar    dd ?

  .__Parent       dd ?
  .__pChildren    dd ?   ; pointer to TArray of pointers to children windows.


; parameters

  param .Parent, .__Parent, .SetParent
  param .Children, .__pChildren, NONE

  param  .OnCreate, ._OnCreate, ._OnCreate
  param  .OnDestroy, ._OnDestroy, ._OnDestroy
  param  .ptrVar, ._ptrVar, ._ptrVar

; methods

  method .Create
  method .Create, .parent
  method .Destroy

  method .SetParent, .value
  abstract .AddChild, .objchild    ; this method is not implemented in TObject, but every descendent can implement it's own parent/child system.

  method .AddChild, .objchild
  method .RemoveChild, .objchild
endobj


method TObject.Destroy
begin
        push    ecx

        get     ecx, [.self], TObject:OnDestroy
interface TObject.OnCreate, .self
        jecxz   .event_ok

interface TObject.OnDestroy, .self
        stdcall dword ecx, [.self]

.event_ok:
        get     ecx, [.self], TObject:ptrVar
        jecxz   .varok

        mov     dword [ecx], 0

.varok:
if defined options.Threads & options.Threads
        mov     ecx, [.self]
        lea     ecx, [eax+TObject._mxAccess]
        stdcall MutexDestroy, eax
end if
        pop     ecx
        return
endp


method TObject.Create
begin
if defined options.Threads & options.Threads
        push    eax
        mov     eax, [.self]
        lea     eax, [eax+TObject._mxAccess]
        stdcall MutexCreate, 0, eax
        stdcall MutexRelease, eax
        pop     eax
end if
        set     [.self], TWindow:Parent, [.parent]
        return
endp




method TObject.Destroy
begin
        pushad

        mov     esi, [.self]

        get     ecx, esi, TObject:OnDestroy
        jecxz   .event_ok

        push    esi
        stdcall dword ecx, [.self]
        pop     esi

.event_ok:
        get     ecx, esi, TObject:ptrVar
        jecxz   .varok
        mov     dword [ecx], 0
.varok:

; destroy all children
        get     ebx, esi, TWindow:Children
        test    ebx, ebx
        jz      .end_children

        mov     ecx, [ebx+TArray.count]

.loop:
        dec     ecx
        js      .end_children

        destroy [ebx+TArray.array+4*ecx]
        jmp     .loop

.end_children:

if defined options.Threads & options.Threads
        lea     ecx, [esi+TObject._mxAccess]
        stdcall MutexDestroy, ecx
end if
        popad
        return
endp





;_________________________________________________________________________________________



method TObject.AddChild
begin
        pushad

        mov     esi, [.self]
        mov     ebx, [.objchild]

        istype  ebx, TObject
        jne     .not_window

        mov     edx, [esi+TObject.__pChildren]
        test    edx, edx
        jnz     .array_ok

        stdcall CreateArray, 4
        mov     edx, eax

.array_ok:

        stdcall AddArrayItems, edx, 1
        mov     [eax], ebx
        mov     [esi+TObject.__pChildren], edx

        clc
        popad
        return


.not_window:
        stc
        popad
        return
endp


;_________________________________________________________________________________________


;----------------------------------------------------------------------
; Returns:
;   CF = 1 - if the object specified was not found as a window child.
;   CF = 0 - the child was removed from the list of childrens.
;----------------------------------------------------------------------

method TObject.RemoveChild
begin
        push    edx esi

        mov     esi, [.self]
        mov     edx, [esi+TObject.__pChildren]

        stdcall ListIndexOf, edx, [.objchild]
        jc      .finish

        stdcall DeleteArrayItems, edx, eax, 1

        cmp     [edx+TArray.count], 0
        jne     .store

        stdcall FreeMem, edx
        xor     edx, edx

.store:
        mov     [esi+TObject.__pChildren], edx
        clc

.finish:
        pop     esi edx
        return
endp



;_________________________________________________________________________________________



method TObject.SetParent
begin
        pushad

        mov     esi, [.self]
        mov     edi, [.value]
        cmp     edi, [esi+TObject.__Parent]             ; if the parent is already set to the same value, ignore.
        je      .finish

        cmp     [esi+TWindow.__Parent], 0
        je      .parent_ok

        exec    [esi+TObject.__Parent], TObject:RemoveChild, esi        ; remove the window from the old parent.
        mov     [esi+TObject.__Parent], edi                             ; store the new parent.

.parent_ok:
        test    edi, edi
        jz      .finish

        exec    edi, TObject:AddChild, esi

.finish:
        mov     [esi+TObject.__Parent], edi
        popad
        return
endp



endmodule
Changes to freshlib/gui/TProgressbar.asm.
17
18
19
20
21
22
23
24
25
26
27
28
29


30
31

32
33











34
35
36
37
38
39
40
17
18
19
20
21
22
23

24
25
26
27

28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51







-




-
+
+

-
+


+
+
+
+
+
+
+
+
+
+
+







object TProgress, TWindow
  ._Pos   dd ?
  ._Max   dd ?
  ._Color dd ?

  param .Pos, ._Pos, .SetPos
  param .Max, ._Max, .SetMax
  param .Color, ._Color, .SetColor

  method .Step
  method .SetPos, .value
  method .SetMax, .value
  method .SetColor, .value

  method .Create, .pParent

  method .SysEventHandler, .pEvent
  method .Paint
endobj



method TProgress.Create
begin
        mov     eax, [.self]
        mov     [eax+TProgress.__want_focus], FALSE

        inherited [.pParent]
        return
endp


method TProgress.Step
begin
        push    eax ecx

        mov     eax, [.self]
        mov     ecx, [eax+TProgress._Pos]
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109


110
111

112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165



166
167
168
169
170
94
95
96
97
98
99
100





101



102










103
104
105

106
107
108



109



110

111





112
113
114
115
116
117
118
119


120






121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136




137

138
139
140
141
142
143
144
145







-
-
-
-
-

-
-
-

-
-
-
-
-
-
-
-
-
-
+
+

-
+


-
-
-

-
-
-
+
-

-
-
-
-
-








-
-
+
-
-
-
-
-
-















-
+
-
-
-
-

-
+
+
+






.finish:
        pop     ecx eax
        return
endp


method TProgress.SetColor
begin
        push    eax ecx
        mov     ecx, [.self]
        mov     eax, [.value]

        xchg    eax, [ecx+TProgress._Color]
        cmp     eax, [ecx+TProgress._Color]
        je      .finish

        exec    ecx, TWindow:Refresh

.finish:
        pop     ecx eax
        return
endp



method TProgress.SysEventHandler
method TProgress.Paint
 .bounds TBounds
begin
        push    eax ebx ecx esi
        pushad

        mov     esi, [.self]
        mov     ebx, [.pEvent]
        cmp     [ebx+TSysEvent.event], sePaint
        je      .paint

.finish:
        stc
        pop     esi ecx ebx eax
        exec    esi, TWindow:__UpdateCanvas
        return

.paint:
locals
  .bounds TBounds
  .style TLineStyle
endl
        mov     [.bounds.x], 0
        mov     [.bounds.y], 0
        mov     eax, [esi+TProgress._width]
        mov     ecx, [esi+TProgress._height]
        mov     [.bounds.width], eax
        mov     [.bounds.height], ecx

        lea     eax, [.bounds]
        stdcall [DrawBox], [ebx+TPaintEvent.context], eax, 0, bxSunken or bxNoFill

        stdcall [DrawBox], [esi+TProgress._canvas], eax, [GUI.clProgressBk], [GUI.progressBorder], [GUI.boxBorderWidth]
        stdcall DrawRectangle, [ebx+TPaintEvent.context], eax, [clDialogBk]

        inc     [.bounds.x]
        inc     [.bounds.y]
        sub     [.bounds.width], 2
        sub     [.bounds.height], 2

        mov     eax, [esi+TProgress._Pos]
        mov     ecx, [esi+TProgress._Max]
        test    ecx, ecx
        jnz     @f
        inc     ecx
@@:
        cmp     eax, ecx
        jle     @f
        mov     eax, ecx
@@:
        imul    eax, [.bounds.width]
        cdq
        idiv    ecx

        stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], eax, [.bounds.height], [esi+TProgress._Color]
        stdcall DrawSolidRect, [esi+TProgress._canvas], [.bounds.x], [.bounds.y], eax, [.bounds.height], [GUI.clProgressBar]
        sub     [.bounds.width], eax
        inc     eax
        inc     [.bounds.width]
        stdcall DrawFillRect, [ebx+TPaintEvent.context], eax, [.bounds.y], [.bounds.width], [.bounds.height], [clDialogBk]

        jmp     .finish
        inherited
        popad
        return
endp



endmodule
Changes to freshlib/gui/TScrollWindow.asm.
20
21
22
23
24
25
26
27

28
29
30



31
32




33
34
35



36
37


38
39
40
41
42
43
44
45
46

47
48





49


















































50



























































51






52


53


54
55



56



57
58




59




60
61



62




63
64
65
66

67


68

69
70
71



72

73
74


75
76
77


78
79
80


81
82
83
84
85
86
87
88
89
90
91
92
93

94
95








96
97
98



99

100
101




102

103
104


105
106
107
108
109
110
111





112
113

114
115
116
117



118
119
120
121
122
123
124
125











126
127
128
129





130
131
132
133
134



135


136
137
138
139
140
141
142
143








144
145


146
147
148

149
150
151
152
153
154
155
156









157
158
159
160

161


162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180


181
182
183
184
185
186
187
188

189
190
191
192
193
194

195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

230
231
232
233

234
235

236
237
238
239
240

241
242

243
244
245

246
247
248
249
250
251

252
253
254
255
256

257
258
259
260
261
262

263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
20
21
22
23
24
25
26

27
28
29
30
31
32
33


34
35
36
37
38


39
40
41
42

43
44
45
46
47


48
49
50
51
52


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179


180
181
182
183
184
185
186


187
188
189
190
191
192
193
194
195


196
197
198
199
200
201
202
203
204

205
206
207

208
209
210
211
212
213

214
215
216
217
218


219
220
221


222
223
224


225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240


241
242
243
244
245
246
247
248
249
250
251
252
253
254

255
256

257
258
259
260
261
262


263
264
265
266
267
268
269


270
271
272
273
274
275

276
277



278
279
280
281







282
283
284
285
286
287
288
289
290
291
292
293



294
295
296
297
298





299
300
301
302
303
304
305







306
307
308
309
310
311
312
313


314
315
316


317
318







319
320
321
322
323
324
325
326
327
328



329
330
331
332
333
334
335

336
337





338

339
340

341



342
343


344





345






346



























347







348




349


350





351


352



353






354





355

356




357


358


359
360
361
362
363




















364
365
366
367
368
369
370







-
+



+
+
+
-
-
+
+
+
+

-
-
+
+
+

-
+
+



-
-




+
-
-
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
-
+
+

+
+
-
-
+
+
+

+
+
+
-
-
+
+
+
+

+
+
+
+
-
-
+
+
+

+
+
+
+

-


+
-
+
+

+


-
+
+
+

+
-
-
+
+

-
-
+
+

-
-
+
+













+
-
-
+
+
+
+
+
+
+
+



+
+
+
-
+

-
+
+
+
+

+
-
-
+
+





-
-
+
+
+
+
+

-
+

-
-
-
+
+
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+

+
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+

-
-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
-
-
+

+
+



-


-
-
-
-
-
+
-


-

-
-
-
+
+
-
-

-
-
-
-
-
+
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
+
-
-
-
-
+
-
-
+
-
-
-
-
-
+
-
-
+
-
-
-
+
-
-
-
-
-
-
+
-
-
-
-
-
+
-

-
-
-
-
+
-
-

-
-





-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  .Pos  dd  ?

  ._Drag dd ?
ends



object TScrollWindow, TBackWindow
object TScrollbar, TWindow
  ._HScroller TScrollbar
  ._VScroller TScrollbar

  param .HMax, ._HScroller.Max, ._HScroller.Max
  param .HPos, ._HScroller.Pos, ._HScroller.Pos
  param .HPage, ._HScroller.Page, ._HScroller.Page
  method .HScrollSet, .Pos, .Max, .Page   ; only params >=0 are set. If<0 ignored.
  method .VScrollSet, .Pos, .Max, .Page

  param .VMax, ._VScroller.Max, ._VScroller.Max
  param .VPos, ._VScroller.Pos, ._VScroller.Pos
  param .VPage, ._VScroller.Page, ._VScroller.Page

  method ._RedrawShadow
  method .GetFreeArea
  method .Paint

  method .EventMouseMove, .x, .y, .kbdState

  method .SysEventHandler, .pEvent
  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventButtonRelease, .button, .kbdState, .x, .y
endobj


ScrollBarWidth = 12
MinScrollBarWidth = 12

;_________________________________________________________________________________________



method TScrollWindow.SysEventHandler
  .event TScrollEvent
method TScrollWindow.Paint
.canvas dd ?
.recth  TBounds
.rectv  TBounds
.rectx  TBounds
begin
        pushad
        mov     esi, [.self]

        exec    esi, TWindow:__UpdateCanvas

        mov     eax, [esi+TWindow._canvas]
        mov     [.canvas], eax

        xor     eax, eax
        mov     [.recth.x], eax
        mov     [.rectv.y], eax

        mov     eax, [esi+TWindow._width]
        mov     edx, [esi+TWindow._height]
        sub     eax, [scrollWidth]
        sub     edx, [scrollWidth]
        mov     [.rectv.x], eax
        mov     [.recth.y], edx

        inc     edx
        inc     eax
        mov     [.rectx.y], edx
        mov     [.rectx.x], eax

        mov     eax, [scrollWidth]
        mov     [.recth.height], eax
        mov     [.rectv.width], eax
        dec     eax
        mov     [.rectx.width], eax
        mov     [.rectx.height], eax

        mov     eax, [esi+TWindow._width]
        mov     edx, [esi+TWindow._height]
        sub     eax, [scrollWidth]
        sub     edx, [scrollWidth]
        mov     [.recth.width], eax
        mov     [.rectv.height], edx

        lea     eax, [.rectx]
        stdcall DrawBoxDefault, [.canvas], eax, [clDialogBk], bxNone, 0

        lea     eax, [.recth]
        stdcall DrawBoxDefault, [.canvas], eax, [clScrollBk], bxSunken or bxNoFill, 0

        lea     eax, [.rectv]
        stdcall DrawBoxDefault, [.canvas], eax, [clScrollBk], bxSunken or bxNoFill, 0

        lea     eax, [esi+TScrollWindow._HScroller]
        stdcall _SliderPixels, eax, [.recth.width]

        push    eax ebx edx esi edi
        push    esi
        stdcall DrawSolidRect, [.canvas], [.recth.x], [.recth.y], eax, [.recth.height], [clScrollBk]
        mov     esi, [.recth.width]
        sub     esi, eax
        sub     esi, edx

        add     eax, [.recth.x]
        lea     edi, [eax+edx]
        stdcall DrawSolidRect, [.canvas], edi, [.recth.y], esi, [.recth.height], [clScrollBk]
        pop     esi

        mov     [.rectx.x], eax

        mov     [.rectx.width], edx
        push    [.recth.y] [.recth.height]
        pop     [.rectx.height] [.rectx.y]

        lea     eax, [.rectx]
        stdcall [DrawSlider], [.canvas], eax, [clScrollSlider], sliderHorizontal

        lea     eax, [esi+TScrollWindow._VScroller]
        stdcall _SliderPixels, eax, [.rectv.height]

        push    esi
        stdcall DrawSolidRect, [.canvas], [.rectv.x], [.rectv.y], [.rectv.width], eax, [clScrollBk]
        mov     esi, [.rectv.height]
        sub     esi, eax
        sub     esi, edx

        add     eax, [.rectv.y]
        lea     edi, [eax+edx]
        stdcall DrawSolidRect, [.canvas], [.rectv.x], edi, [.rectv.width], esi, [clScrollBk]
        pop     esi

        mov     [.rectx.y], eax

        mov     [.rectx.height], edx
        push    [.rectv.x] [.rectv.width]
        pop     [.rectx.width] [.rectx.x]

        lea     eax, [.rectx]
        stdcall [DrawSlider], [.canvas], eax, [clScrollSlider], sliderVertical

        inherited

        popad
        return

endp






method TScrollWindow.EventMouseMove
begin
        pushad

        mov     esi, [.self]

        stdcall __ScrollSetCursor, esi, [.x], [.y]

        lea     edi, [esi+TScrollWindow._HScroller]

        mov     eax, [.x]
        mov     ecx, [.pEvent]
        mov     ecx, [esi+TScrollWindow._width]
        mov     edx, scrollX

        cmp     [edi+TScrollbar._Drag], 0
        jne     .found
        cmp     [ecx+TSysEvent.event], seMouseBtnPress
        je      .btnpress


        lea     edi, [esi+TScrollWindow._VScroller]

        mov     eax, [.y]
        mov     ecx, [esi+TScrollWindow._height]
        mov     edx, scrollY
        cmp     [ecx+TSysEvent.event], seMouseBtnRelease
        je      .btnrelease

        cmp     [edi+TScrollbar._Drag], 0

        je      .continue

.found:
        sub     ecx, [scrollWidth]
        sub     eax, 2
        sub     eax, [edi+TScrollbar._Drag]
        cmp     [ecx+TSysEvent.event], seMouseMove
        je      .mousemove

        stdcall _SetSliderPos, edi, eax, ecx
        jc      .finish

        exec    [.self], TWindow:EventScroll, edx, scTrack, [edi+TScrollbar.Pos]               ;method .EventScroll, .direction, .command, .value

        exec    [.self], TWindow:Refresh

.continue:
        inherited [.pEvent]

.finish:
        inherited  [.x], [.y], [.kbdState]
        pop     edi esi edx ebx eax

        popad
        return
endp


;.........................................................................................
method TScrollWindow.EventButtonPress
begin
        pushad

        mov     esi, [.self]
.btnpress:
        stdcall __ScrollSetCursor, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]

        stdcall __ScrollSetCursor, esi, [.x], [.y]

        cmp     [ecx+TMouseButtonEvent.Button], mbLeft
        jne     .continue
        cmp     [.button], mbLeft
        jne     .finish

        stdcall _WhatScrollbar, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
        jc      .continue         ; not found
        stdcall _WhatScrollbar, esi, [.x], [.y]
        jc      .finish         ; not found

; here ecx=height of the scrollbar
;      edi= ptr to TScrollbar structure
;      ebx= coordinate of the mouse in the scrollbar

        stdcall _SliderPixels, edi, ecx
        sub     ebx, eax
        jl      .before
        cmp     ebx, edx
        jg      .after

; inside the slider - capture the mouse.
        mov     [edi+TScrollbar._Drag], ebx

        stdcall MouseCapture, [esi+TWindow.handle]
        jmp     .continue
        stdcall SetMouseCapture, esi

.finish:

        inherited [.button], [.kbdState], [.x], [.y]

        popad
        return

.before:
.after:
        popad
        return
endp
        jmp     .continue


;.........................................................................................

method TScrollWindow.EventButtonRelease
begin
        pushad

        mov     esi, [.self]
.btnrelease:
        stdcall __ScrollSetCursor, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]

        stdcall __ScrollSetCursor, esi, [.x], [.y]

        xor     eax, eax
        mov     [esi+TScrollWindow._HScroller._Drag], eax
        mov     [esi+TScrollWindow._VScroller._Drag], eax

        stdcall MouseCapture, eax
        jmp     .continue
        stdcall SetMouseCapture, eax

        popad
        return
endp

;.........................................................................................


.mousemove:
        mov     ecx, [.pEvent]
        stdcall __ScrollSetCursor, esi, [ecx+TMouseMoveEvent.x], [ecx+TMouseMoveEvent.y]




        mov     ecx, [.pEvent]
        lea     edi, [esi+TScrollWindow._HScroller]
        mov     eax, [ecx+TMouseMoveEvent.x]
        mov     ecx, [esi+TScrollWindow._width]
        mov     [.event.ScrollBar], scrollX
        cmp     [edi+TScrollbar._Drag], 0
        jne     .found



; returns:
;   eax - position in pixels
;   edx - size in pixels


proc _SliderPixels, .pScrollbar, .length
begin
        push    ecx esi

        mov     ecx, [.pEvent]
        lea     edi, [esi+TScrollWindow._VScroller]
        mov     eax, [ecx+TMouseMoveEvent.y]
        mov     ecx, [.pScrollbar]

; page size in pixels.
        mov     esi, [ecx+TScrollbar.Max]
        mov     eax, [.length]
        mov     ecx, [esi+TScrollWindow._height]
        mov     [.event.ScrollBar], scrollY
        cmp     [edi+TScrollbar._Drag], 0

        je      .continue
        add     esi, [ecx+TScrollbar.Page]
        test    esi, esi
        jz      .lengthok

        imul     [ecx+TScrollbar.Page]
        idiv     esi

.found:
        mov     [.event.event], seScroll
        mov     [.event.ScrollCmd], scTrack

        sub     ecx, ScrollBarWidth
        sub     eax, 2
        sub     eax, [edi+TScrollbar._Drag]
.lengthok:
        cmp     eax, [minSliderHeight]
        jge     @f
        mov     eax, [minSliderHeight]
@@:
        cmp     eax, [.length]
        jle     @f
        mov     eax, [.length]
        stdcall _SetSliderPos, edi, eax, ecx
        jc      .endmove
@@:
        push    eax

        mov     eax, [edi+TScrollbar.Pos]
        mov     [.event.Value], eax
; position in pixels

        lea     eax, [.event]

        exec    esi, TWindow:SysEventHandler, eax
        jnc     .finish

; ?????? Do we need this?
;        execute esi, TScrollWindow.Refresh
        sub     eax, [.length]
        mov     esi, [ecx+TScrollbar.Max]
        test    esi, esi
        jnz     @f
        inc     esi
@@:
        neg     eax
        mul     [ecx+TScrollbar.Pos]
        div     esi

.endmove:
        clc
        jmp     .finish
        pop     edx   ; width

        pop     esi ecx
        return
endp


;_________________________________________________________________________________________


method TScrollWindow._RedrawShadow
  .recth TBounds
  .rectv TBounds
  .rectx TBounds

proc __ScrollSetCursor, .window, .x, .y
  .context dd ?
begin
        pushad
        mov     esi, [.self]

        get     ebx, esi, TScrollWindow:FreeArea

        mov     eax, [esi+TScrollWindow._pShadow]
        mov     esi, [.window]
        mov     eax, [esi+TWindow._cursor]
        stdcall AllocateContext, [eax+TBackBuffer.raster]
        mov     [.context], eax

        mov     eax, [ebx+TBounds.x]
        mov     edx, [ebx+TBounds.y]
        mov     [.recth.x], eax
        mov     [.rectv.y], edx

        stdcall _WhatScrollbar, esi, [.x], [.y]
        add     eax, [ebx+TBounds.width]
        add     edx, [ebx+TBounds.height]
        mov     [.rectv.x], eax
        mov     [.recth.y], edx

        inc     edx
        jc      @f
        inc     eax
        mov     [.rectx.y], edx
        mov     [.rectx.x], eax

        mov     [.recth.height], ScrollBarWidth
        mov     [.rectv.width], ScrollBarWidth
        mov     [.rectx.width], ScrollBarWidth-1
        mov     [.rectx.height], ScrollBarWidth-1

        mov     eax, [ebx+TBounds.width]
        mov     edx, [ebx+TBounds.height]
        inc     eax
        inc     edx
        mov     [.recth.width], eax
        mov     [.rectv.height], edx

        lea     eax, [.rectx]
        stdcall [DrawBox], [.context], eax, [clDialogBk], bxNone

        lea     eax, [.recth]
        stdcall [DrawBox], [.context], eax, [clScrollBk], bxSunken or bxNoFill

        lea     eax, [.rectv]
        stdcall [DrawBox], [.context], eax, [clScrollBk], bxSunken or bxNoFill

        lea     eax, [esi+TScrollWindow._HScroller]
        stdcall _SliderPixels, eax, [.recth.width]

        push    esi
        stdcall DrawFillRect, [.context], [.recth.x], [.recth.y], eax, [.recth.height], [clScrollBk]
        mov     esi, [.recth.width]
        sub     esi, eax
        sub     esi, edx

        add     eax, [.recth.x]
        mov     eax, mcArrow
        lea     edi, [eax+edx]
        stdcall DrawFillRect, [.context], edi, [.recth.y], esi, [.recth.height], [clScrollBk]
        pop     esi

@@:
        mov     [.rectx.x], eax

        mov     [esi+TWindow._cursor], eax
        mov     [.rectx.width], edx
        push    [.recth.y] [.recth.height]
        pop     [.rectx.height] [.rectx.y]

        lea     eax, [.rectx]
        test    eax, $ffffff00
        stdcall [DrawSlider], [.context], eax, [clScrollSlider], sliderHorizontal

        jnz     @f
        lea     eax, [esi+TScrollWindow._VScroller]
        stdcall _SliderPixels, eax, [.rectv.height]

        stdcall GetStockCursor, eax
        push    esi
        stdcall DrawFillRect, [.context], [.rectv.x], [.rectv.y], [.rectv.width], eax, [clScrollBk]
        mov     esi, [.rectv.height]
        sub     esi, eax
        sub     esi, edx

@@:
        add     eax, [.rectv.y]
        lea     edi, [eax+edx]
        stdcall DrawFillRect, [.context], [.rectv.x], edi, [.rectv.width], esi, [clScrollBk]
        pop     esi

        get     edx, esi, TWindow:OSWindow
        mov     [.rectx.y], eax

        mov     [.rectx.height], edx
        push    [.rectv.x] [.rectv.width]
        pop     [.rectx.width] [.rectx.x]

        stdcall SetMouseCursor, edx, eax
        lea     eax, [.rectx]
        stdcall [DrawSlider], [.context], eax, [clScrollSlider], sliderVertical

        stdcall ReleaseContext, [.context]
        stc
        popad
        return
endp




method TScrollWindow.GetFreeArea
begin
        inherited

        sub     [eax+TBounds.width], ScrollBarWidth
        jns     @f
        mov     [eax+TBounds.width], 0
@@:
        sub     [eax+TBounds.height], ScrollBarWidth
        jns     @f
        mov     [eax+TBounds.height], 0
@@:
        return
endp


;_________________________________________________________________________________________



proc _SetSliderPos, .pScrollbar, .x, .lengthpx
begin
        push    eax ecx edx

        mov     ecx, [.pScrollbar]
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428


429
430
431
432
433
434
435
396
397
398
399
400
401
402









































































403
404
405
406
407
408
409
410
411
412
413
414
415
416
417




418
419
420


421
422
423
424
425
426
427
428
429







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-















-
-
-
-



-
-
+
+








.zero:
        xor     eax, eax
        jmp     .ok2
endp



; returns:
;   eax - position in pixels
;   edx - size in pixels

proc _SliderPixels, .pScrollbar, .length
begin
        push    ecx esi

        mov     ecx, [.pScrollbar]

; page size in pixels.
        mov     esi, [ecx+TScrollbar.Max]
        mov     eax, [.length]
        add     esi, [ecx+TScrollbar.Page]
        test    esi, esi
        jz      .lengthok

        imul     [ecx+TScrollbar.Page]
        idiv     esi

.lengthok:
        cmp     eax, MinScrollBarWidth
        jge     @f
        mov     eax, MinScrollBarWidth
@@:
        cmp     eax, [.length]
        jle     @f
        mov     eax, [.length]
@@:
        push    eax

; position in pixels

        sub     eax, [.length]
        mov     esi, [ecx+TScrollbar.Max]
        test    esi, esi
        jnz     @f
        inc     esi
@@:
        neg     eax
        mul     [ecx+TScrollbar.Pos]
        div     esi

        pop     edx   ; width

        pop     esi ecx
        return
endp


proc __ScrollSetCursor, .window, .x, .y
begin
        pushad

        mov     esi, [.window]
        mov     eax, [esi+TWindow._cursor]
        stdcall _WhatScrollbar, esi, [.x], [.y]
        jc      @f

        mov     eax, mcArrow
@@:
        mov     [esi+TWindow._cursor], eax
        test    eax, $ffffff00
        jnz     @f
        stdcall GetStockCursor, eax
@@:
        stdcall SetMouseCursor, eax

        popad
        return
endp



; returns:
;      ecx = height of the scrollbar
;      edi = ptr to TScrollbar structure
;      ebx = coordinate of the mouse in the scrollbar
;
; CF=1 if the cursor is not in scrollbar

proc _WhatScrollbar, .window, .x, .y
begin
        push    eax edx esi

        mov     esi, [.window]


        mov     eax, [.x]
        mov     edx, [.y]

        mov     eax, [esi+TWindow._width]
        mov     edx, [esi+TWindow._height]

        sub     eax, ScrollBarWidth
        sub     edx, ScrollBarWidth
        sub     eax, [scrollWidth]
        sub     edx, [scrollWidth]

        cmp     [.x], eax
        jl      .checkh

        cmp     [.y], edx
        jg      .notfound     ; we are in the dead square.

455
456
457
458
459
460
461



































































































































































































































































































































































































































462
463
464
465
466
467
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







.notfound:
        stc
        pop     esi edx eax
        return
endp


;;_________________________________________________________________________________________
;
;
;method TScrollWindow.SysEventHandler
;  .event TScrollEvent
;begin
;        push    eax ebx edx esi edi
;        mov     esi, [.self]
;        mov     ecx, [.pEvent]
;
;        cmp     [ecx+TSysEvent.event], seMouseBtnPress
;        je      .btnpress
;
;        cmp     [ecx+TSysEvent.event], seMouseBtnRelease
;        je      .btnrelease
;
;        cmp     [ecx+TSysEvent.event], seMouseMove
;        je      .mousemove
;
;.continue:
;        inherited [.pEvent]
;
;.finish:
;        pop     edi esi edx ebx eax
;        return
;
;
;;.........................................................................................
;
;.btnpress:
;        stdcall __ScrollSetCursor, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
;
;        cmp     [ecx+TMouseButtonEvent.Button], mbLeft
;        jne     .continue
;
;        stdcall _WhatScrollbar, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
;        jc      .continue         ; not found
;
;; here ecx=height of the scrollbar
;;      edi= ptr to TScrollbar structure
;;      ebx= coordinate of the mouse in the scrollbar
;
;        stdcall _SliderPixels, edi, ecx
;        sub     ebx, eax
;        jl      .before
;        cmp     ebx, edx
;        jg      .after
;
;; inside the slider - capture the mouse.
;        mov     [edi+TScrollbar._Drag], ebx
;        stdcall MouseCapture, [esi+TWindow.handle]
;        jmp     .continue
;
;.before:
;.after:
;        jmp     .continue
;
;;.........................................................................................
;
;.btnrelease:
;        stdcall __ScrollSetCursor, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
;
;        xor     eax, eax
;        mov     [esi+TScrollWindow._HScroller._Drag], eax
;        mov     [esi+TScrollWindow._VScroller._Drag], eax
;
;        stdcall MouseCapture, eax
;        jmp     .continue
;
;;.........................................................................................
;
;.mousemove:
;        mov     ecx, [.pEvent]
;        stdcall __ScrollSetCursor, esi, [ecx+TMouseMoveEvent.x], [ecx+TMouseMoveEvent.y]
;
;        mov     ecx, [.pEvent]
;        lea     edi, [esi+TScrollWindow._HScroller]
;        mov     eax, [ecx+TMouseMoveEvent.x]
;        mov     ecx, [esi+TScrollWindow._width]
;        mov     [.event.ScrollBar], scrollX
;        cmp     [edi+TScrollbar._Drag], 0
;        jne     .found
;
;        mov     ecx, [.pEvent]
;        lea     edi, [esi+TScrollWindow._VScroller]
;        mov     eax, [ecx+TMouseMoveEvent.y]
;        mov     ecx, [esi+TScrollWindow._height]
;        mov     [.event.ScrollBar], scrollY
;        cmp     [edi+TScrollbar._Drag], 0
;
;        je      .continue
;
;
;.found:
;        mov     [.event.event], seScroll
;        mov     [.event.ScrollCmd], scTrack
;
;        sub     ecx, ScrollBarWidth
;        sub     eax, 2
;        sub     eax, [edi+TScrollbar._Drag]
;        stdcall _SetSliderPos, edi, eax, ecx
;        jc      .endmove
;
;        mov     eax, [edi+TScrollbar.Pos]
;        mov     [.event.Value], eax
;
;        lea     eax, [.event]
;
;        exec    esi, TWindow:SysEventHandler, eax
;        jnc     .finish
;
;; ?????? Do we need this?
;;        execute esi, TScrollWindow.Refresh
;
;.endmove:
;        clc
;        jmp     .finish
;
;endp
;
;
;;_________________________________________________________________________________________
;
;
;method TScrollWindow._RedrawShadow
;  .recth TBounds
;  .rectv TBounds
;  .rectx TBounds
;
;  .context dd ?
;begin
;        pushad
;        mov     esi, [.self]
;
;        get     ebx, esi, TScrollWindow:FreeArea
;
;        mov     eax, [esi+TScrollWindow._pShadow]
;        stdcall AllocateContext, [eax+TBackBuffer.raster]
;        mov     [.context], eax
;
;        mov     eax, [ebx+TBounds.x]
;        mov     edx, [ebx+TBounds.y]
;        mov     [.recth.x], eax
;        mov     [.rectv.y], edx
;
;        add     eax, [ebx+TBounds.width]
;        add     edx, [ebx+TBounds.height]
;        mov     [.rectv.x], eax
;        mov     [.recth.y], edx
;
;        inc     edx
;        inc     eax
;        mov     [.rectx.y], edx
;        mov     [.rectx.x], eax
;
;        mov     [.recth.height], ScrollBarWidth
;        mov     [.rectv.width], ScrollBarWidth
;        mov     [.rectx.width], ScrollBarWidth-1
;        mov     [.rectx.height], ScrollBarWidth-1
;
;        mov     eax, [ebx+TBounds.width]
;        mov     edx, [ebx+TBounds.height]
;        inc     eax
;        inc     edx
;        mov     [.recth.width], eax
;        mov     [.rectv.height], edx
;
;        lea     eax, [.rectx]
;        stdcall DrawBoxDefault, [.context], eax, [clDialogBk], bxNone
;
;        lea     eax, [.recth]
;        stdcall [DrawBox], [.context], eax, [clScrollBk], bxSunken or bxNoFill
;
;        lea     eax, [.rectv]
;        stdcall [DrawBox], [.context], eax, [clScrollBk], bxSunken or bxNoFill
;
;        lea     eax, [esi+TScrollWindow._HScroller]
;        stdcall _SliderPixels, eax, [.recth.width]
;
;        push    esi
;        stdcall DrawFillRect, [.context], [.recth.x], [.recth.y], eax, [.recth.height], [clScrollBk]
;        mov     esi, [.recth.width]
;        sub     esi, eax
;        sub     esi, edx
;
;        add     eax, [.recth.x]
;        lea     edi, [eax+edx]
;        stdcall DrawFillRect, [.context], edi, [.recth.y], esi, [.recth.height], [clScrollBk]
;        pop     esi
;
;        mov     [.rectx.x], eax
;
;        mov     [.rectx.width], edx
;        push    [.recth.y] [.recth.height]
;        pop     [.rectx.height] [.rectx.y]
;
;        lea     eax, [.rectx]
;        stdcall [DrawSlider], [.context], eax, [clScrollSlider], sliderHorizontal
;
;        lea     eax, [esi+TScrollWindow._VScroller]
;        stdcall _SliderPixels, eax, [.rectv.height]
;
;        push    esi
;        stdcall DrawFillRect, [.context], [.rectv.x], [.rectv.y], [.rectv.width], eax, [clScrollBk]
;        mov     esi, [.rectv.height]
;        sub     esi, eax
;        sub     esi, edx
;
;        add     eax, [.rectv.y]
;        lea     edi, [eax+edx]
;        stdcall DrawFillRect, [.context], [.rectv.x], edi, [.rectv.width], esi, [clScrollBk]
;        pop     esi
;
;        mov     [.rectx.y], eax
;
;        mov     [.rectx.height], edx
;        push    [.rectv.x] [.rectv.width]
;        pop     [.rectx.width] [.rectx.x]
;
;        lea     eax, [.rectx]
;        stdcall [DrawSlider], [.context], eax, [clScrollSlider], sliderVertical
;
;        stdcall ReleaseContext, [.context]
;        stc
;        popad
;        return
;endp
;
;
;
;
;method TScrollWindow.GetFreeArea
;begin
;        inherited
;
;        sub     [eax+TBounds.width], ScrollBarWidth
;        jns     @f
;        mov     [eax+TBounds.width], 0
;@@:
;        sub     [eax+TBounds.height], ScrollBarWidth
;        jns     @f
;        mov     [eax+TBounds.height], 0
;@@:
;        return
;endp
;
;
;;_________________________________________________________________________________________
;
;
;
;proc _SetSliderPos, .pScrollbar, .x, .lengthpx
;begin
;        push    eax ecx edx
;
;        mov     ecx, [.pScrollbar]
;        stdcall _SliderPixels, [.pScrollbar], [.lengthpx]
;
;        sub     [.lengthpx], edx
;        jz      .zero
;
;        mov     eax, [ecx+TScrollbar.Max]
;        imul    [.x]
;        idiv    [.lengthpx]
;
;        cmp     eax, 0
;        jge     .ok
;        mov     eax, 0
;.ok:
;        cmp     eax, [ecx+TScrollbar.Max]
;        jle     .ok2
;        mov     eax, [ecx+TScrollbar.Max]
;.ok2:
;        cmp     [ecx+TScrollbar.Pos], eax
;        stc
;        je      @f
;        clc
;@@:
;        mov     [ecx+TScrollbar.Pos], eax
;        pop     edx ecx eax
;        return
;
;.zero:
;        xor     eax, eax
;        jmp     .ok2
;endp
;
;
;
;; returns:
;;   eax - position in pixels
;;   edx - size in pixels
;
;proc _SliderPixels, .pScrollbar, .length
;begin
;        push    ecx esi
;
;        mov     ecx, [.pScrollbar]
;
;; page size in pixels.
;        mov     esi, [ecx+TScrollbar.Max]
;        mov     eax, [.length]
;        add     esi, [ecx+TScrollbar.Page]
;        test    esi, esi
;        jz      .lengthok
;
;        imul     [ecx+TScrollbar.Page]
;        idiv     esi
;
;.lengthok:
;        cmp     eax, MinScrollBarWidth
;        jge     @f
;        mov     eax, MinScrollBarWidth
;@@:
;        cmp     eax, [.length]
;        jle     @f
;        mov     eax, [.length]
;@@:
;        push    eax
;
;; position in pixels
;
;        sub     eax, [.length]
;        mov     esi, [ecx+TScrollbar.Max]
;        test    esi, esi
;        jnz     @f
;        inc     esi
;@@:
;        neg     eax
;        mul     [ecx+TScrollbar.Pos]
;        div     esi
;
;        pop     edx   ; width
;
;        pop     esi ecx
;        return
;endp
;
;
;proc __ScrollSetCursor, .window, .x, .y
;begin
;        pushad
;
;        mov     esi, [.window]
;        mov     eax, [esi+TWindow._cursor]
;        stdcall _WhatScrollbar, esi, [.x], [.y]
;        jc      @f
;
;        mov     eax, mcArrow
;@@:
;        mov     [esi+TWindow._cursor], eax
;        test    eax, $ffffff00
;        jnz     @f
;        stdcall GetStockCursor, eax
;@@:
;        stdcall SetMouseCursor, eax
;
;        popad
;        return
;endp
;
;
;
;; returns:
;;      ecx = height of the scrollbar
;;      edi = ptr to TScrollbar structure
;;      ebx = coordinate of the mouse in the scrollbar
;;
;; CF=1 if the cursor is not in scrollbar
;
;proc _WhatScrollbar, .window, .x, .y
;begin
;        push    eax edx esi
;
;        mov     esi, [.window]
;
;
;        mov     eax, [.x]
;        mov     edx, [.y]
;
;        mov     eax, [esi+TWindow._width]
;        mov     edx, [esi+TWindow._height]
;
;        sub     eax, ScrollBarWidth
;        sub     edx, ScrollBarWidth
;
;        cmp     [.x], eax
;        jl      .checkh
;
;        cmp     [.y], edx
;        jg      .notfound     ; we are in the dead square.
;
;; mouse in vscrollbar
;        mov     ebx, [.y]
;        mov     ecx, edx
;        lea     edi, [esi+TScrollWindow._VScroller]
;        jmp     .found
;
;.checkh:
;        cmp     [.y], edx
;        jl      .notfound     ; in the client area
;
;; mouse in hscrollbar
;        mov     ebx, [.x]
;        mov     ecx, eax
;        lea     edi, [esi+TScrollWindow._HScroller]
;
;.found:
;        clc
;        pop     esi edx eax
;        return
;
;.notfound:
;        stc
;        pop     esi edx eax
;        return
;endp



endmodule



Added freshlib/gui/TScrollbar.asm.


















































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: TScrollWindow object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: TScrollWindow is window that may have scrollers to scroll the client area.
;_________________________________________________________________________________________
module "TScrollWindow library"


sbkHorizontal = 0
sbkVertical = 1


object TScrollbar, TWindow

  ._pos  dd ?
  ._page dd ?
  ._max  dd ?

  ._kind dd ?

  ._drag_ofs dd ?

  ._state  dd ?

  param .Kind, ._kind, .SetKind

  param .Pos, ._pos, .SetPos
  param .Page, ._page, .SetPage
  param .Max, ._max, .SetMax

  method .SetKind, .value

  method .SetPos, .value
  method .SetPage, .value
  method .SetMax, .value

  method .Paint

  method .EventMouseMove, .x, .y, .kbdState

  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventButtonRelease, .button, .kbdState, .x, .y

  method .EventMouseEnter
  method .EventMouseLeave
endobj



;_________________________________________________________________________________________


method TScrollbar.SetKind         ;, .value
begin
        mov     eax, [.self]
        push    [.value]
        pop     [eax+TScrollbar._kind]

        exec    eax, TScrollbar:Refresh
        return
endp

;_________________________________________________________________________________________

method TScrollbar.SetPos          ;, .value
begin
        push    eax ecx

        mov     ecx, [.self]

        mov     eax, [.value]
        cmp     eax, [ecx+TScrollbar._pos]
        je      .finish

        mov     [ecx+TScrollbar._pos], eax
        exec    ecx, TScrollbar:Refresh

.finish:
        pop     ecx eax
        return
endp

;_________________________________________________________________________________________


method TScrollbar.SetPage         ;, .value
begin
        push    eax ecx

        mov     ecx, [.self]

        mov     eax, [.value]
        cmp     eax, [ecx+TScrollbar._page]
        je      .finish

        mov     [ecx+TScrollbar._page], eax
        exec    ecx, TScrollbar:Refresh

.finish:
        pop     ecx eax
        return
endp


;_________________________________________________________________________________________


method TScrollbar.SetMax          ;, .value
begin
        push    eax ecx

        mov     ecx, [.self]

        mov     eax, [.value]
        cmp     eax, [ecx+TScrollbar._max]
        je      .finish

        mov     [ecx+TScrollbar._max], eax
        exec    ecx, TScrollbar:Refresh

.finish:
        pop     ecx eax
        return
endp



;_________________________________________________________________________________________


method TScrollbar.Paint
.canvas dd ?
.rect  TBounds
begin
        pushad
        mov     esi, [.self]

        get     ebx, esi, TScrollbar:Canvas

        xor     eax, eax
        mov     ecx, [ebx+TImage.width]
        mov     edx, [ebx+TImage.height]

        mov     [.rect.x], eax
        mov     [.rect.y], eax
        mov     [.rect.width], ecx
        mov     [.rect.height], edx

        mov     edi, [esi+TScrollbar._state]

        stdcall DrawSolidRect, ebx, eax, eax, [ebx+TImage.width], [ebx+TImage.height], [GUI.clScrollBk+4*edi]

        mov     ecx, [esi+TScrollbar._kind]
        mov     edx, [esi+TScrollbar._width + 4*ecx]    ; sbkHorizontal = 0; sbkVertical = 1

        stdcall _SliderPixels, esi, edx

        mov     [.rect.x + 4*ecx], eax
        mov     [.rect.width + 4*ecx], edx

        lea     eax, [.rect]
        stdcall DrawBoxDefault, ebx, eax, [GUI.clScrollSlider+4*edi], [GUI.borderScroll], [GUI.boxBorderWidth]

        inherited

        popad
        return

endp






method TScrollbar.EventMouseMove
begin
        pushad

        mov     esi, [.self]
        mov     edx, [esi+TScrollbar._kind]

        cmp     [esi+TScrollbar._drag_ofs], 0
        je      .finish

        mov     eax, [.x + 4*edx]
        mov     ecx, [esi+TScrollbar._width + 4*edx]

        sub     eax, [edi+TScrollbar._drag_ofs]

        stdcall _SetSliderPos, edi, eax, ecx
        jc      .finish

        get     eax, esi, TWindow:Parent
        exec    eax, TWindow:EventScroll, edx, scTrack, [edi+TScrollbar._pos]               ;method .EventScroll, .direction, .command, .value

        exec    esi, TWindow:Refresh

.finish:
        inherited  [.x], [.y], [.kbdState]
        popad
        return
endp


method TScrollbar.EventButtonPress
begin
        pushad

        cmp     [.button], mbLeft
        jne     .finish

        mov     esi, [.self]
        mov     ebx, [esi+TScrollbar._kind]

        stdcall _SliderPixels, esi, [esi+TScrollbar._width + 4*ebx]

        mov     edi, [.x+ 4*ebx]

        sub     edi, eax
        jl      .before

        cmp     edi, edx
        jg      .after

; inside the slider - capture the mouse.

        mov     [esi+TScrollbar._drag_ofs], edi

        stdcall SetMouseCapture, esi

.finish:
        inherited [.button], [.kbdState], [.x], [.y]

        popad
        return

.before:
.after:
        jmp     .finish
endp




method TScrollbar.EventButtonRelease
begin
        pushad

        mov     esi, [.self]

        xor     eax, eax
        mov     [esi+TScrollbar._drag_ofs], eax
        stdcall SetMouseCapture, eax

        popad
        return
endp









; returns:
;   eax - position in pixels
;   edx - size in pixels


proc _SliderPixels, .pScrollbar, .length
begin
        push    ecx esi

        mov     ecx, [.pScrollbar]

; page size in pixels.
        mov     esi, [ecx+TScrollbar._max]
        mov     eax, [.length]
        add     esi, [ecx+TScrollbar._page]
        test    esi, esi
        jz      .lengthok

        imul     [ecx+TScrollbar._page]
        idiv     esi

.lengthok:
        cmp     eax, [GUI.minSliderHeight]
        jge     @f
        mov     eax, [GUI.minSliderHeight]
@@:
        cmp     eax, [.length]
        jle     @f
        mov     eax, [.length]
@@:
        push    eax

; position in pixels

        sub     eax, [.length]
        mov     esi, [ecx+TScrollbar._max]
        test    esi, esi
        jnz     @f
        inc     esi
@@:
        neg     eax
        mul     [ecx+TScrollbar._pos]
        div     esi

        pop     edx   ; width

        pop     esi ecx
        return
endp





proc _SetSliderPos, .pScrollbar, .x, .lengthpx
begin
        push    eax ecx edx

        mov     ecx, [.pScrollbar]
        stdcall _SliderPixels, [.pScrollbar], [.lengthpx]

        sub     [.lengthpx], edx
        jz      .zero

        mov     eax, [ecx+TScrollbar._max]
        imul    [.x]
        idiv    [.lengthpx]

        cmp     eax, 0
        jge     .ok
        mov     eax, 0
.ok:
        cmp     eax, [ecx+TScrollbar._max]
        jle     .ok2
        mov     eax, [ecx+TScrollbar._max]
.ok2:
        cmp     [ecx+TScrollbar._pos], eax
        stc
        je      @f
        clc
@@:
        mov     [ecx+TScrollbar._pos], eax
        pop     edx ecx eax
        return

.zero:
        xor     eax, eax
        jmp     .ok2
endp






method TScrollbar.EventMouseEnter
begin
        mov     eax, [.self]
        mov     [eax+TScrollbar._state], 1
        exec    eax, TWindow:Refresh

        inherited
        return
endp




method TScrollbar.EventMouseLeave
begin
        mov     eax, [.self]
        mov     [eax+TScrollbar._state], 0

        exec    eax, TWindow:Refresh

        inherited
        return
endp





endmodule



Changes to freshlib/gui/TTreeView.asm.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27














28
29
30

31
32
33
34

35
36
37
38


39
40

41













































42
43
44
45
46





47
48















































49




50

51
52
53
54
55

















































56



57











58

59


60

61






62
63



























64
65
66
67
68
69


70



71




















72




73









74
75


































































76




77











































































78
79
80
81
82



83

84










85
86








87




88

89
90
91










92
93




94



95
96
97
98
99

























100
101


102
103
104
105
106
107











































108




109

110
111










































































































112
113
114























115


116



117



118



119


120



121


































































122


































123
124
125
126





127












128



129



130











131




132

























133
134


135
136
137
8
9
10
11
12
13
14








15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97



98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157




158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

223
224
225
226

227
228
229
230
231
232
233
234


235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304
305
306
307


308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

458
459
460
461
462

463
464
465
466
467
468
469
470
471
472
473

474
475
476
477
478
479
480
481
482
483
484
485
486
487
488



489
490
491
492
493
494
495
496
497
498
499

500
501
502
503
504
505
506
507
508




509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534

535
536
537
538




539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696



697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722

723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740

741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842

843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870

871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886

887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918







-
-
-
-
-
-
-
-




-
+
+
+
+
+
+
+
+
+
+
+
+
+
+



+




+



-
+
+


+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
+
+
+
+
+

-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
-
+

-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+

+
+
+
+
+
+
+
+
+
+
+
-
+

+
+
-
+

+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






+
+
-
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+

+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+
+
+

+
-
+
+
+
+
+
+
+
+
+
+

-
+
+
+
+
+
+
+
+

+
+
+
+

+
-
-
-
+
+
+
+
+
+
+
+
+
+

-
+
+
+
+

+
+
+

-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+
+


-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+

+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
-
+
+
+

+
+
+

+
+
+

+
+

+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-


+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+

+
+
+

+
+
+
-
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+



;  Target OS: Any
;
;  Dependencies:
;  Notes:
;_________________________________________________________________________________________
module "TreeView library"

;ObjectClass TreeView,                    \
;            ScrollWindow,                \
;            TTreeView.Create,           \
;            TTreeView.Destroy,          \
;            TTreeView.Get,              \
;            TTreeView.Set,              \
;            TTreeView.ExecCmd,          \
;            TTreeView.SysEventHandler

; tree-view item state flags.
tvisExpanded = 1
tvisSelected = 2
tvisFocused  = 4

; iterate visible items flags

iifViewport = 1         ; iterate only items that are in the viewport of the control.
                        ; if not set, the items that are "visible" because of the expanded parent items
                        ; will cause callback call as well.


; TTreeView:HitTest return flags

tvhtNone = 0
tvhtExpandIcon = 1
tvhtItemIcon = 2
tvhtItemText = 3


struct TTreeViewItem

  .level      dd ?        ; the level of the element in the tree.

  .caption    dd ?        ; hString of the name.
  .state      dd ?        ; one or more state flags.

  .imgNormal  dd ?        ; index to the icon for normal state
  .iSelected  dd ?        ; index to the icon for selected state

  .pObject    dd ?        ; the object attached to the item
  .UserData   dd ?        ; the user data attached to the item.

  align 32
  .shift = 5

ends




object TTreeView, TWindow

  ._items dd ?    ; TArray with TTreeViewItem elements.
  ._index dd ?    ; TArray with dword index to the displayable items of ._items array.

  ._start_view dd ?     ; in the index array.
  ._focused    dd ?

  ._line_height dd ?
  ._text_offset dd ?
  ._margin_top  dd ?
  ._margin_left dd ?

  .YScroller    dd ?

  ._on_focused_change dd ?

  param  .StartView,   ._start_view, .SetStartView
  param  .OnFocusItem, ._on_focused_change, ._on_focused_change
  param  .FocusedItem, ._focused, .SetFocused

  method .SetStartView, .value
  method .SetFocused, .value

  method .Create, .parent
  method .Destroy

  method .ClearSelection, .mask
  method .IterateVisibleItems, .start_item, .flags, .callback, .user
  method .HitTest, .x, .y

  method .__UpdateCanvas
  method .__RebuildIndex

  method .Paint

  method .EventKeyPress, .utf8, .scancode, .kbdState
  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventScroll, .direction, .command, .value

endobj


object TTreeView, TScrollWindow
  ._items dd ?    ; TArray with TTreeViewItem elements.
  ._first dd ?    ; index of the first visible item.

interface TTreeView.IterateCallback, .pTreeView, .pItem, .yItem, .user

interface TTreeView.OnFocusItem, .pTreeView, .pItem


  .OnItemDelete  dd ? ; procedure to be call when the item is deleted. It should free the objects attached to the item.


method TTreeView.Create ; .parent
begin
        pushad
        mov     esi, [.self]

        stdcall CreateArray, sizeof.TTreeViewItem
        mov     [esi+TTreeView._items], eax

        stdcall CreateArray, 4
        mov     [esi+TTreeView._index], eax

        mov     [esi+TTreeView._margin_top], 4
        mov     [esi+TTreeView._margin_left], 4

        stdcall GetFontMetrics, [GUI.DefaultFont]
        add     eax, 4
        add     ebx, 2
        mov     [esi+TTreeView._line_height], eax
        mov     [esi+TTreeView._text_offset], ebx

        create  edi, TScrollbar, [.self]
        set     edi, TScrollbar:Kind, sbkVertical
        set     edi, TScrollbar:width, [GUI.scrollWidth]

        mov     [esi+TTreeView.YScroller], edi

        mov     [esi+TTreeView.__want_focus], 1

        inherited [.parent]
        popad
        return
endp



method TTreeView.Destroy
begin
        push    ebx

        mov     ebx, [.self]

        set     ebx, TTreeView:Visible, FALSE   ; in order to not try to update the view.

        stdcall FreeMem, [ebx+TTreeView._index]
        stdcall FreeMem, [ebx+TTreeView._items]

        pop     ebx
        inherited
        return
endp
  param .Focused


  method .AddItem, .iParent
  method .DelItem, .iItem  ;deletes the item and all children.
  method .GetItem, .index
endobj


method TTreeView.__UpdateCanvas
.count dd ?
begin
        inherited

        pushad

; now update the scroller size and position.

        mov     esi, [.self]
        mov     ecx, [esi+TTreeView._width]
        mov     edx, [esi+TTreeView._height]

        mov     eax, ecx
        sub     eax, [GUI.scrollWidth]
        sub     eax, [GUI.boxBorderWidth]

        sub     edx, [GUI.boxBorderWidth]
        sub     edx, [GUI.boxBorderWidth]
        js      .finish

        set     [esi+TTreeView.YScroller], TScrollbar:x, eax
        set     [esi+TTreeView.YScroller], TScrollbar:y, [GUI.boxBorderWidth]
        set     [esi+TTreeView.YScroller], TScrollbar:height, edx


        mov     eax, [esi+TTreeView._height]
        mov     ecx, [esi+TTreeView._line_height]

        cdq

        div     ecx
        test    eax, eax
        jz      @f

        inc     eax
@@:
        mov     ebx, [esi+TTreeView._index]
        test    ebx, ebx
        jz      .finish

        mov     ebx, [ebx+TArray.count]
        sub     ebx, eax
        inc     ebx

        set     [esi+TTreeView.YScroller], TScrollbar:Page, eax
        set     [esi+TTreeView.YScroller], TScrollbar:Max, ebx

        cmp     eax, ebx
        setl    al
        movzx   eax, al

        set     [esi+TTreeView.YScroller], TScrollbar:Visible, eax

.finish:
        popad
        return
endp





proc TTreeView.Create, .pobj
method TTreeView.__RebuildIndex
begin
        pushad

        mov     ebx, [.pobj]
        mov     esi, [.self]

        mov     ecx, [esi+TTreeView._index]
        jecxz   @f

        stdcall FreeMem, ecx

@@:
        stdcall CreateArray, sizeof.TTreeViewItem
        mov     [ebx+TTreeView._items], eax
        stdcall CreateArray, 4
        mov     [esi+TTreeView._index], eax

        xor     eax, eax
        lea     edx, [esi+TTreeView._index]
        exec    esi, TTreeView:IterateVisibleItems, eax, eax, TTreeView.__AddIndex, edx

        popad
        return
endp



proc TTreeView.__AddIndex as TTreeView.IterateCallback
begin
        mov     esi, [.pTreeView]
        mov     esi, [esi+TTreeView._items]
        lea     esi, [esi+TArray.array]

        mov     edi, [.user]
        mov     ebx, [.pItem]
        sub     ebx, esi
        shr     ebx, TTreeViewItem.shift

        stdcall AddArrayItems, [edi], 1
        mov     [edi], edx
        mov     [eax], ebx

        clc
        return
endp




proc TTreeView.Destroy, .pobj
method TTreeView.Paint
.bounds TBounds
.end_item dd ?
begin
        pushad

        mov     esi, [.self]
        get     ebx, esi, TWindow:Canvas

        xor     eax, eax

        mov     [.bounds.x], eax
        mov     [.bounds.y], eax

        mov     ecx, [esi+TTreeView._width]
        mov     edx, [esi+TTreeView._height]

        mov     [.bounds.width], ecx
        mov     [.bounds.height], edx

        lea     eax, [.bounds]
        stdcall [DrawBox], [esi+TTreeView._canvas], eax, [GUI.clTreeViewBack], bxNone, 0

        mov     eax, [esi+TTreeView._items]
        mov     ebx, [.pobj]
        mov     ebx, [eax+TArray.count]
        shl     ebx, TTreeViewItem.shift
        lea     ebx, [eax+TArray.array+ebx]
        mov     [.end_item], ebx

        mov     edi, [esi+TTreeView._index]
        mov     ecx, [esi+TTreeView._start_view]
        mov     edx, [esi+TTreeView._margin_top]

.loop:
        cmp     ecx, [edi+TArray.count]
        jae     .end_paint

        mov     eax, [edi+TArray.array + 4*ecx]
        execute ebx, TTreeView.DelItem, -1
        stdcall FreeMem, [ebx+TTreeView._items]
        shl     eax, TTreeViewItem.shift
        add     eax, [esi+TTreeView._items]
        add     eax, TArray.array

        xor     ebx, ebx
        cmp     ecx, [esi+TTreeView._focused]
        sete    bl
        push    ebx     ; .focused argument

        lea     ebx, [eax+sizeof.TTreeViewItem]
        cmp     ebx, [.end_item]
        jb      @f

        xor     ebx, ebx

@@:
        stdcall TTreeView.__PaintOneItem, esi, eax, ebx, [esi+TTreeView._line_height], [esi+TTreeView._line_height], edx     ; the last argument from the stack.

        inc     ecx
        add     edx, [esi+TTreeView._line_height]
        cmp     edx, [esi+TTreeView._height]
        jb      .loop

.end_paint:
        lea     eax, [.bounds]
        mov     ecx, [GUI.tvBorder]
        or      ecx, bxNoFill
        stdcall [DrawBox], [esi+TTreeView._canvas], eax, [GUI.clTreeViewBack], ecx, [GUI.boxBorderWidth]

        inherited

        popad
        return
endp


proc TTreeView.__PaintOneItem, .pTreeView, .pItem, .pNextItem, .hsize, .vsize, .y, .focused
.back dd ?
.text dd ?
begin
        pushad

        mov     edx, [.y]
        mov     esi, [.pItem]
        mov     edi, [.pTreeView]

        mov     ecx, [esi+TTreeViewItem.level]
        imul    ecx, [.hsize]

        add     ecx, [edi+TTreeView._margin_left] ; left margin.

        mov     eax, [GUI.clTreeViewText]
        mov     ebx, [GUI.clTreeViewBack]

        test    [esi+TTreeViewItem.state], tvisSelected
        jz      @f
        mov     eax, [GUI.clTreeSelectedTxt]
        mov     ebx, [GUI.clTreeSelected]
@@:
        cmp     [.focused], 0
        je      @f
        mov     eax, [GUI.clTreeFocusedTxt]
        mov     ebx, [GUI.clTreeFocused]
@@:
        mov     [.text], eax
        mov     [.back], ebx

; draw state icon
        mov     eax, [.pNextItem]
        test    eax, eax
        jz      .state_icon_ok
        clc

        mov     eax, [eax+TTreeViewItem.level]
        cmp     eax, [esi+TTreeViewItem.level]
        jle     .state_icon_ok

        mov     ebx, [esi+TTreeViewItem.state]
        and     ebx, tvisExpanded
        mov     ebx, [GUI.tvIcons+8*ebx]                    ; TImage with the expand/collapse icon

        push    ecx edx

; center the icon
        mov     eax, [edi+TTreeView._line_height]
        sub     eax, [ebx+TImage.width]
        sar     eax, 1

        add     ecx, eax

        mov     eax, [edi+TTreeView._line_height]
        sub     eax, [ebx+TImage.height]
        sar     eax, 1

        add     edx, eax

;.draw_state:
        stdcall BlendImage, [edi+TTreeView._canvas], ecx, edx, ebx, 0, 0, [ebx+TImage.width], [ebx+TImage.height]
        pop     edx ecx

.state_icon_ok:
        add     ecx, [.hsize]

; draw item icon
        mov     ebx, [esi+TTreeViewItem.imgNormal]
        test    ebx, ebx
        jz      .icon_ok

        push    ecx edx

; center the icon
        mov     eax, [edi+TTreeView._line_height]
        sub     eax, [ebx+TImage.width]
        sar     eax, 1

        add     ecx, eax

        mov     eax, [edi+TTreeView._line_height]
        sub     eax, [ebx+TImage.height]
        sar     eax, 1

        add     edx, eax

        stdcall BlendImage, [edi+TTreeView._canvas], ecx, edx, ebx, 0, 0, [ebx+TImage.width], [ebx+TImage.height]

        pop     edx ecx

        add     ecx, [edi+TTreeView._line_height]

.icon_ok:
        push    edx

        stdcall StrPtr, [esi+TTreeViewItem.caption]
        stdcall GetTextBounds, eax, [eax+string.len], [GUI.DefaultFont]

        pop     edx
        add     eax, 4

        stdcall DrawSolidRect, [edi+TTreeView._canvas], ecx, edx, eax, [.vsize], [.back]

        add     edx, [edi+TTreeView._text_offset]
        add     ecx, 2

        stdcall StrPtr, [esi+TTreeViewItem.caption]
        stdcall DrawString, [edi+TTreeView._canvas], eax, [eax+string.len], ecx, edx, [GUI.DefaultFont], [.text]

        popad
        return
endp


proc TTreeView.Get, .pobj, .paramID


method TTreeView.EventKeyPress  ;, .utf8, .scancode, .kbdState
begin
        pushad
        stc

        mov     esi, [.self]

        mov     eax, [.utf8]
        test    eax, eax
        jz      .no_char

; search the treeview???

        popad
        return
endp

.no_char:
        mov     eax, [.scancode]

        cmp     eax, keyUpNumpad
        je      .up
        cmp     eax, keyUp
        je      .up

        cmp     eax, keyDownNumpad
        je      .down
        cmp     eax, keyDown
        je      .down

        cmp     eax, keyPgUpNumpad
proc TTreeView.Set, .pobj, .paramID, .value
begin
        stc
        je      .pgup
        cmp     eax, keyPgUp
        je      .pgup

        cmp     eax, keyPgDnNumpad
        je      .pgdn
        cmp     eax, keyPgDown
        je      .pgdn

        popad
        return
endp

.up:
        mov     edx, 1
        jmp     .moveup

.pgup:
        get     edx, [esi+TTreeView.YScroller], TScrollbar:Page
        dec     edx

proc TTreeView.ExecCmd, .self, .method
begin
        cmp     [.method], TTreeView._RedrawShadow
        je      .redraw

.moveup:
        mov     ebx, [esi+TTreeView._focused]

        test    [.kbdState], maskShift
        jnz     .sel_up_ok

        exec    esi, TTreeView:ClearSelection, not tvisSelected

.sel_up_ok:
        sub     ebx, edx
        jns     @f

        xor     ebx, ebx
@@:
        set     esi, TTreeView:FocusedItem, ebx

        cmp     ebx, [esi+TTreeView._start_view]
        jae     .refresh

        set     esi, TTreeView:StartView, ebx
        jmp     .finish

.refresh:
        exec    esi, TTreeView:Refresh

        stc
.finish:
        popad
        return

.redraw:
locals
  .context dd ?
endl

.down:
        mov     edx, 1
        jmp     .move_down

.pgdn:
        get     edx, [esi+TTreeView.YScroller], TScrollbar:Page
        dec     edx


.move_down:
        mov     edi, [esi+TTreeView._index]
        mov     ebx, [esi+TTreeView._focused]

        add     ebx, edx

        cmp     ebx, [edi+TArray.count]
        jb      .posok

        mov     ebx, [edi+TArray.count]
        dec     ebx

.posok:
        test    [.kbdState], maskShift
        jnz     .sel_dn_ok

        exec    esi, TTreeView:ClearSelection, not tvisSelected

.sel_dn_ok:
        set     esi, TTreeView:FocusedItem, ebx

        get     ecx, [esi+TTreeView.YScroller], TScrollbar:Page

        sub     ecx, 2
        sub     ebx, ecx

        cmp     ebx, [esi+TTreeView._start_view]
        jle     .refresh

        set     esi, TTreeView:StartView, ebx
        jmp     .finish

endp



method TTreeView.EventButtonPress        ;, .button, .kbdState, .x, .y
begin
        pushad

        mov     esi, [.self]

        exec    esi, TTreeView:HitTest, [.x], [.y]

        cmp     eax, tvhtNone
        je      .finish2

        cmp     eax, tvhtExpandIcon
        je      .expand_collapse

        test    [.kbdState], maskCtrl
        jnz     @f
        exec    esi, TTreeView:ClearSelection, not tvisSelected
@@:
        set     esi, TTreeView:FocusedItem, ecx
        jmp     .finish

.expand_collapse:

        xor     [edx+TTreeViewItem.state], tvisExpanded
        exec    esi, TTreeView:__RebuildIndex

.finish:
        exec    [.self], TWindow:Refresh

.finish2:
        popad
        return
endp



method TTreeView.EventScroll
begin
        pushad

        mov     esi, [.self]

        cmp     [.command], scWheelUp
        je      .scrollup

        cmp     [.command], scWheelDn
        je      .scrolldn

        cmp     [.command], scTrack
        jne     .finish

        set     esi, TTreeView:StartView, [.value]

.finish:
        popad
        return

.scrollup:
        get     eax, esi, TTreeView:StartView
        dec     eax
        jns     @f
        xor     eax, eax
@@:
        set     esi, TTreeView:StartView, eax
        jmp     .finish


.scrolldn:
        get     ecx, [esi+TTreeView.YScroller], TScrollbar:Max
        get     eax, esi, TTreeView:StartView
        inc     eax
        cmp     eax, ecx
        jbe     @f
        dec     eax
@@:
        set     [.self], TTreeView:StartView, eax
        jmp     .finish

        return
endp




method TTreeView.SetStartView    ;, .value
begin
        pushad

        mov     esi, [.self]
        mov     ebx, [.value]
        mov     [esi+TTreeView._start_view], ebx

        set     [esi+TTreeView.YScroller], TScrollbar:Pos, ebx
        exec    [.self], TWindow:Refresh

        popad
        return

endp



method TTreeView.IterateVisibleItems
.end dd ?

.min_item dd ?
.maxy dd ?
begin
        pushad

        mov     esi, [.self]

        mov     edi, [esi+TTreeView._pShadow]
        stdcall AllocateContext, [edi+TBackBuffer.raster]
        mov     [.context], eax
        mov     eax, [esi+TTreeView._height]
        mov     [.maxy], eax

        mov     eax, [esi+TTreeView._items]
        mov     eax, [eax+TArray.count]

        mov     ecx, [.start_item]
        mov     edx, [esi+TTreeView._start_view]

        shl     eax, TTreeViewItem.shift
        shl     ecx, TTreeViewItem.shift
        shl     edx, TTreeViewItem.shift

        add     eax, [esi+TTreeView._items]
        add     ecx, [esi+TTreeView._items]
        add     edx, [esi+TTreeView._items]

        lea     eax, [eax+TArray.array]
        lea     ecx, [ecx+TArray.array]
        lea     edx, [edx+TArray.array]

        mov     [.end], eax
        mov     [.min_item], edx

        xor     edx, edx
        dec     edx        ; current level = $ffffffff - unsigned cmp
        stdcall DrawFillRect, [.context], 0, 0, [esi+TWindow._width], [esi+TWindow._height], [clEditBk]

        xor     edi, edi   ; current Y coordinate.
        add     edi, [esi+TTreeView._margin_top]   ; top margin.

.item_loop:
        cmp     ecx, [.end]
        jae     .end_items

        cmp     [ecx+TTreeViewItem.level], edx
        ja      .next_item
        je      .equal

; below
        mov     edx, [ecx+TTreeViewItem.level]

.equal:
        test    [ecx+TTreeViewItem.state], tvisExpanded
        jz      .visible
        stdcall ReleaseContext, [.context]

        inc     edx

.visible:
        test    [.flags], iifViewport
        jz      .yes

        cmp     ecx, [.min_item]
        jb      .next_item

        cmp     edi, [.maxy]
        ja      .end_items

.yes:
        pushad
        stdcall [.callback], esi, ecx, edi, [.user]
        popad
        jc      .found

        add     edi, [esi+TTreeView._line_height]

.next_item:
        add     ecx, sizeof.TTreeViewItem
        jmp     .item_loop

.end_items:
        clc
        popad
        return

.found:
        mov     [esp+regEAX*4], ecx
        popad
        return
endp




method TTreeView.HitTest
.index dd ?
begin
        pushad

        mov     esi, [.self]

        mov     eax, [.y]
        sub     eax, [esi+TTreeView._margin_top]
        xor     edx, edx
        mov     ecx, [esi+TTreeView._line_height]

        mov     [.index], edx

        div     ecx

        add     eax, [esi+TTreeView._start_view]
        mov     ebx, [esi+TTreeView._index]

        cmp     eax, [ebx+TArray.count]
        jae     .not_found

        mov     [.index], eax

        mov     edi, [ebx+4*eax+TArray.array]   ; index

        mov     ebx, [esi+TTreeView._items]

        cmp     edi, [ebx+TArray.count]
        jae     .not_found

        shl     edi, TTreeViewItem.shift
        lea     edi, [ebx+TArray.array + edi]   ; edi - pointer to the pointed item.

        mov     edx, [edi+TTreeViewItem.level]
        imul    edx, [esi+TTreeView._line_height]
        add     edx, [esi+TTreeView._margin_left]

        cmp     [.x], edx
        jb      .finish

        add     edx, [esi+TTreeView._line_height]

        mov     eax, tvhtExpandIcon

        cmp     [.x], edx
        jb      .finish

        add     edx, [esi+TTreeView._line_height]

        mov     eax, tvhtItemIcon

        cmp     [.x], edx
        jb      .finish

        mov     eax, tvhtItemText

.finish:
        mov     [esp+regEDX*4], edi
        mov     [esp+regEAX*4], eax
        mov     eax, [.index]
        mov     [esp+regECX*4], eax
        popad
        stc
        return

.not_found:
        xor     edi, edi
        mov     eax, tvhtNone
        jmp     .finish

endp



method TTreeView.ClearSelection
begin
        pushad

        mov     esi, [.self]
        mov     esi, [esi+TTreeView._items]
        lea     edi, [esi+TArray.array]
        mov     ecx, [esi+TArray.count]
        mov     ebx, [.mask]

.loop:
        dec     ecx
        js      .finish

        and     [edi+TTreeViewItem.state], ebx
        add     edi, sizeof.TTreeViewItem
        jmp     .loop
proc TTreeView.SysEventHandler, .pobj, .pEvent


.finish:
        popad
        return
endp




method TTreeView.SetFocused     ;, .value
begin
        pushad
        mov     esi, [.self]
        mov     edi, [esi+TTreeView._items]
        mov     ecx, [.value]
        stc

        cmp     [esi+TTreeView._focused], ecx
        je      .finish

        mov     [esi+TTreeView._focused], ecx

        xor     ebx, ebx

        cmp     ecx, [edi+TArray.count]
        jae     .no_selection

        shl     ecx, TTreeViewItem.shift
        lea     ebx, [edi+TArray.array+ecx]

        or      [ebx+TTreeViewItem.state], tvisSelected

.no_selection:
        mov     eax, [esi+TTreeView._on_focused_change]
        test    eax, eax
        jz      .finish

        stdcall eax, esi, ebx           ; interface TTreeView.OnFocusItem, .pTreeView, .pItem

.finish:
        popad
        return
endp




endmodule
Changes to freshlib/gui/TWindow.asm.
11
12
13
14
15
16
17

18

19
20
21
22
23
24





















































25
26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41




42


43

44




45

46

47
48




49

50



51

52
53





54
55



56
57
58




59
60
61
62


63
64

65

66
67


68
69

70
71
72
73








74


75
76




77








78
79









80
81





82
83
84
85



86
87
88
89
90
91
92
93
94








95
96
97
98

99
100

















101
102
103



104


105
106


107


108



109

110



111

112
113
114
115
116
117
118














119
120
121
122
123
124
125
126

127
128
129
130
131
132

133
134
135
136


137
138

139
140
141
142
143
144
145
146
147
148
149
150

151

152





153

154
155
156








157

158

159






















160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186


187

188


189
190
191
192






193
194

195
196
197


198

199
200
201




202
203

204

205
206



207
208
209

210
211
212

213
214
215
216
217
218

219

220
221
222



223
224
225
226
227
228
229
230
231


























232

233

234
235
236
237
238
239
240
11
12
13
14
15
16
17
18
19
20






21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86




87
88
89
90
91
92
93

94
95
96
97
98
99

100
101
102


103
104
105
106
107
108

109
110
111
112
113


114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131


132
133
134

135
136
137


138
139
140

141
142



143
144
145
146
147
148
149
150
151
152
153


154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177


178
179
180
181
182
183



184
185
186
187








188
189
190
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219


220
221
222
223
224
225


226
227
228
229
230

231
232
233
234
235

236
237
238
239
240







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256


257
258

259
260
261
262
263
264


265

266


267
268


269

270
271
272
273
274
275
276
277
278
279

280
281
282

283
284
285
286
287
288
289



290
291
292
293
294
295
296
297
298
299

300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324




















325
326
327
328
329
330
331
332

333
334
335
336




337
338
339
340
341
342
343

344
345


346
347
348
349



350
351
352
353
354

355
356
357


358
359
360
361


362
363
364

365
366
367
368
369
370
371
372

373
374


375
376
377
378








379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414







+

+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+











-
+

-
-
-
-
+
+
+
+

+
+
-
+

+
+
+
+
-
+

+
-
-
+
+
+
+

+
-
+
+
+

+
-
-
+
+
+
+
+

-
+
+
+



+
+
+
+


-
-
+
+

-
+

+
-
-
+
+

-
+

-
-
-
+
+
+
+
+
+
+
+

+
+
-
-
+
+
+
+

+
+
+
+
+
+
+
+


+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+

-
-
-
+
+
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+



-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
+
+
+

+
+
-
-
+
+

+
+
-
+
+
+

+
-
+
+
+

+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-


-

+




-
-
+
-

-
-
+
+
-
-
+
-










-
+

+
-
+
+
+
+
+

+
-
-
-
+
+
+
+
+
+
+
+

+
-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






+
+
-
+

+
+
-
-
-
-
+
+
+
+
+
+

-
+

-
-
+
+

+
-
-
-
+
+
+
+

-
+

+
-
-
+
+
+

-
-
+


-
+






+
-
+

-
-
+
+
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
-
+







;
;  Notes: TWindow is the common ancestor of all visible on the screen controls.
;         This file contains only OS independent part of the library and includes
;         the OS dependent files.
;_________________________________________________________________________________________
module "TWindow library"

; Interfaces for the OS dependent procedures

; NOTICE: Some of them are not needed, so can be removed.
; The elements of the array returned by .Children param
; if handle<>0 and pWindow=0 - it is a native window, not added by FreshLib
struct TWinArrayItem
  .handle   dd ?      ; The native OS handle of the window.
  .pWindow  dd ?      ; pointer to TWindow descendent structure.
ends


;-----------------------------------------------------------------------------------------
; Creates OS window, according to the content of TWindow structure [.pWindow]
;
; Notice, that this OS windows are created ONLY for the visible top level windows.
;
;-----------------------------------------------------------------------------------------
interface _CreateWindow, .pWindow

;-----------------------------------------------------------------------------------------
; Destroy the OS window. The OS windows are actually destroyed when invisible and then
; recreated when needed.
;-----------------------------------------------------------------------------------------
interface _DestroyWindow, .hwnd

;-----------------------------------------------------------------------------------------
; Converts the client coordinates to screen coordinates.
;-----------------------------------------------------------------------------------------
interface _ClientToScreen, .hwnd, .x, .y

;-----------------------------------------------------------------------------------------
; Changes the visibility of the window.
;-----------------------------------------------------------------------------------------
interface _ShowWindow, .hwnd, .flag


interface _RefreshWindowRect, .hwnd, .x, .y, .width, .height
interface _SetWindowTextUtf8, .hwnd, .ptrUtf8
interface _SetModalTowards, .hwnd, .hwndParent
interface _FinalizeModal, .hwnd, .hwndParent
interface _GetWindowStruct, .hwin
interface _SetWindowStruct, .hwin, .value


; probably not needed, but will keep them for some time.

;interface _SetWindowBorder, .hwnd, .brdType
;interface _GetWindowBounds, .hwnd, .pBounds
;interface _SetWindowBounds, .hwnd, .pBounds
;interface _CreateNullWindow
;interface _GetParent, .hwnd
;interface _GetChildren, .hwnd
;interface _GetVisible, .hwnd
;interface _SetFocus, .hwnd
;interface _AddChild, .hwnd, .child
;interface _GetWindowTextUtf8, .hwnd, .ptrUtf8
;interface _EnableWindow, .hwnd, .flag
;interface _SetTransientTowards, .hwnd, .hwndParent


include '%TargetOS%/windows.asm'



; Border kind of window.
borderNone    = 0
borderFull    = 1
borderModal   = 2
borderToolbox = 3


object TWindow, TObject

  .handle       dd ?   ; it is handle to the system provided window.
  .handle         dd ?   ; it is handle to the system provided window.

  ._x           dd ?
  ._y           dd ?
  ._width       dd ?
  ._height      dd ?
  ._x             dd ?
  ._y             dd ?
  ._width         dd ?
  ._height        dd ?

  ._border        dd ?    ; has meaning only for the top level windows!

  ._visible     dd ?
  ._visible       dd ?

  ._cursor        dd ?    ; mouse cursor.

  ._caption       dd ?    ; string handle with window caption.

  ._border      dd ?
  ._enabled       dd ?

  .__want_focus   dd ?
  ._pSplitGrid   dd ?         ; pointer to array of TSplitRect that devide the window on a layout grid.
  ._dragSplitter dd ?

  .__action       dd ?

  .__main         dd ?    ; this is the window that is main for this window. has meaning only for top level windows.

; window canvas
  ._FreeArea    TBounds      ; the window area that remains free after all children aligned. [1]

  ._screen        dd ?    ; TImage containing the image of the window with all children composited.
  ._invalid_rect  RECT    ; the rectangle that need to be repainted.

  ._canvas      dd ?    ; TImage containing the image of the window only.
  ._caption     dd ?    ; string handle with window caption.
  ._cursor      dd ?    ; it is a handle to the mouse cursor.

  ._screen_invalid dd ?
  ._canvas_invalid dd ?

; window user event handlers

  .___counter   dd ?
  ._OnPaint        dd ?
  ._OnScroll       dd ?
  ._OnKeyPressed   dd ?

; parameters

  param .OSWindow, .GetOSWindow, NONE           ; the first window down the tree, that has window handle.

  param .Action, .__action, .SetAction

  param .x,      ._x,      ._x
  param .y,      ._y,      ._y
  param .width,  ._width,  ._width
  param .height, ._height, ._height
  param .width,  ._width,  .SetWidth
  param .height, ._height, .SetHeight

  param .FreeArea, .GetFreeArea, NONE     ; read only.
  param .border, ._border, ._border

  param ._MainWindow, .__main, .__main
  param .borderKind, ._border, .SetBorder
  param .ZOrder,     .GetZ, .SetZ

  param .Cursor, ._cursor, ._cursor

  param .Visible, ._visible, .SetVisible
  param .Visible, ._visible,     .SetVisible
  param .Caption, .GetCaption,   .SetCaption
  param .Parent,  .GetParent,  .SetParent
  param .Cursor,  ._cursor,    .SetCursor
  param .Children, .GetChildren, NONE

  param .Enabled, .GetEnabled, .SetEnabled
  param .GlobalEnabled, .GetGlobalEnabled, NONE

  param .WantFocus, .__want_focus, NONE

  param .ImgScreen, .GetImgScreen, NONE
  param .Canvas,    .GetCanvas,    NONE

  param .OnPaint, ._OnPaint, .SetOnPaint
  param .OnScroll, ._OnScroll, ._OnScroll
  param .SplitGrid, ._pSplitGrid, .SetSplitGrid
  param .SplitCell, .GetSplitCell, .SetSplitCell

  param .OnKeyPressed, ._OnKeyPressed, ._OnKeyPressed

  param .SplitCell, NONE, .SetSplitCell

; private methods

  method .__UpdateHandle
  method .__UpdateFocus
  method .__UpdateCanvas
  method .__UpdateScreen


; parameter methods

  method .SetParent, .value

  method .SetAction, .value

  method .UpdateAction, .action    ; to be defined only for controls that can be attached to TAction

  method .SetWidth, .value
  method .SetHeight, .value

  method .GetFreeArea
  method .GetZ
  method .GetEnabled
  method .SetEnabled, .value

  method .GetGlobalEnabled

  method .GetCaption
  method .GetParent
  method .GetChildren
  method .GetSplitCell
  method .SetCaption, .value

  method .SetVisible, .value

  method .SetBorder, .value
  method .SetZ,      .value
  method .SetVisible, .value
  method .SetCaption, .value
  method .SetParent, .value
  method .SetCursor, .value
  method .SetSplitGrid, .value
  method .SetSplitCell, .value
  method .SetOnPaint, .value

  method .SetSplitCell, .value

  method .GetImgScreen
  method .GetCanvas

  method .GetOSWindow

; other methods

  method .Create
  method .Create, .parent
  method .Destroy


; Parent/child methods definitions of abstract methods, inherited from TObject

  method .ChildByXY, .x, .y, .onlyenabled

  method .RectChanged, .pRect      ; invalidates the rectangle, so all children windows in this rectangle are
                                   ; to be redrawn. Called from the children window on any visual changes.
                                   ; notice, that if the child changed the size ot position, it needs special
                                   ; processing of the rectangle. Actually the changed rectangle is the
                                   ; bounding rectangle of the new and old rectangles.

  method  .ClientToScreenXY, .x, .y


; Painting methods

  method .Paint        ; Paints itself on the .Canvas TImage
  method .Refresh
  method .Focus
  method .UpdateBounds
  method .Update

  method .RefreshAll

; System event methods

  method .AddChild, .child
  method .AlignChildren
  method .EventFocusIn
  method .EventFocusOut

  method .EventResize, .newWidth, .newHeight
  method .EventMove, .newX, .newY
  method .SysEventHandler, .pEvent

  method .EventMouseEnter
  method .EventMouseLeave

  method .EventMouseMove, .x, .y, .kbdState
endobj

  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventButtonRelease, .button, .kbdState, .x, .y

  method .EventScroll, .direction, .command, .value
; NOTES:
; [1]  FreeArea field
;
; [2] The param .children returns an array of TWinArrayItem filled with information about
;     all children of the given window.
;     This array is allocated with CreateArray and needs to be free with FreeMem after use.
;     TArray.lparam of the array contains a pointer to the element containing current window

  method .EventKeyPress, .utf8, .scancode, .kbdState
  method .EventKeyRelease, .scancode, .kbdState

  method .CloseRequest, .reason

endobj


interface TWindow.OnPaint, .self, .canvas

interface TWindow.OnScroll, .self, .direction, .command, .value

interface TWindow.OnKeyPressed, .self, .utf8, .scancode, .kbdState


; OS dependend code
include '%TargetOS%/windows.asm'

; OS independent code.

;_________________________________________________________________________________________



method TWindow.Create
begin
        push    ebx

        inherited [.parent]
        stdcall _CreateNullWindow

        mov     ebx, [.self]
        mov     [ebx+TWindow.handle], eax
        set     [.self], TWindow:Enabled, TRUE
        set     [.self], TWindow:Cursor, mcArrow
        stdcall _SetWindowStruct, eax, ebx

        set     [.self], TWindow:border, borderFull
        pop     ebx
        return
endp


;_________________________________________________________________________________________



method TWindow.Destroy
begin
        push    eax
        pushad

        mov     esi, [.self]
        set     [.self], TWindow:SplitGrid, 0

; hide the window, destroy the handle and remove the focus.
        mov     [esi+TWindow._visible], 0
        exec    esi, TWindow:__UpdateHandle
        exec    esi, TWindow:__UpdateFocus

        cmp     esi, [__LastPointedWindow]
        mov     eax, [.self]
        cmp     [eax+TWindow.handle], 0
        je      @f
        jne     @f
        mov     [__LastPointedWindow], 0
@@:

; detach from action if any

        mov     ecx, [esi+TWindow.__action]
        jecxz   @f

        exec    ecx, TAction:Detach, esi
        stdcall _DestroyWindow, [eax+TWindow.handle]

@@:
; destroy the canvas and screen images if any.

        mov     ecx, [esi+TWindow._canvas]
        jecxz   .canvas_ok

        stdcall DestroyImage, ecx

.canvas_ok:

        mov     ecx, [esi+TWindow._screen]
        jecxz   .screen_ok

        stdcall DestroyImage, ecx

.screen_ok:

; free the string handles

        stdcall StrDel, [esi+TWindow._caption]

        popad

        inherited
        pop     eax
        return
endp



;_________________________________________________________________________________________


method  TWindow.GetParent
begin
        mov     eax, [.self]

        stdcall _GetParent, [eax+TWindow.handle]
        test    eax, eax
        jz      .finish

        stdcall _GetWindowStruct, eax

.finish:
        return
endp


;_________________________________________________________________________________________



method TWindow.GetChildren
method TWindow.SetAction
begin
        pushad

        mov     eax, [.self]
        stdcall _GetChildren, [eax+TWindow.handle]
        test    eax, eax
        jz      .finish
        mov     esi, [.self]
        mov     ecx, [.value]
        mov     edx, [esi+TWindow.__action]

        cmp     ecx, edx
        je      .finish

        push    ecx ebx edi
        mov     [esi+TWindow.__action], ecx

        mov     ebx, eax
        mov     ecx, [ebx+TArray.count]
        test    edx, edx
        jz      .old_ok

        exec    edx, TAction:Detach, esi
.loop:
        jecxz   .endloop
        dec     ecx

.old_ok:
        test    ecx, ecx
        jz      .new_ok

        stdcall _GetWindowStruct, [ebx+TArray.array+8*ecx+TWinArrayItem.handle]
        exec    ecx, TAction:Attach, esi

.new_ok:
        mov     [ebx+TArray.array+8*ecx+TWinArrayItem.pWindow], eax
        jmp     .loop
        getm    eax, esi, TWindow:UpdateAction
        test    eax, eax
        jz      .finish

.endloop:
        mov     eax, ebx
        stdcall eax, esi, ecx

.finish:
        pop     edi ebx ecx
        popad
        return
endp


;_________________________________________________________________________________________


method TWindow.GetFreeArea
method TWindow.SetWidth
begin
        push    ecx esi
        mov     esi, [.self]
        push    ecx eax

        mov     ecx, [.self]

        xor     eax, eax
        mov     [esi+TWindow._FreeArea.x], eax
        mov     [esi+TWindow._FreeArea.y], eax
        mov     eax, [esi+TWindow._width]
        mov     ecx, [esi+TWindow._height]
        mov     [esi+TWindow._FreeArea.width], eax
        mov     [esi+TWindow._FreeArea.height], ecx
        lea     eax, [esi+TWindow._FreeArea]
        mov     eax, [.value]
        xchg    eax, [ecx+TWindow._width]
        cmp     eax, [ecx+TWindow._width]
        je      .finish

        exec    ecx, TWindow:Paint

.finish:
        pop     eax ecx
        return
endp



method TWindow.SetHeight
begin
        push    ecx eax

        mov     ecx, [.self]

        mov     eax, [.value]
        xchg    eax, [ecx+TWindow._height]
        cmp     eax, [ecx+TWindow._height]
        je      .finish

        exec    ecx, TWindow:Paint

.finish:
        pop     esi ecx
        pop     eax ecx
        return
endp


;_________________________________________________________________________________________


249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284



285
286
287



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305


306

307
308
309
310
311
312
313
314
315
316

317
318
319
320
321

322
323
324

325
326
327

328
329
330
331
332
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348

349
350
351
352

353
354
355
356
357
358











359





360
361



362

363
364
365








366










367
368
369





370

371
372
373






374

375
376
377






378
379
380
381


382




383




















































































































































































































































































































































































































384
385
386

387

388
389



390
391
392
393







394
395










396
397
398





















399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454


455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504

505

506
507
508
509






















510
511



512


513
514





515
516
517


518



519
520



521


522
523






524








525
526


527

528
529


530

531
532


533



534
535
536







537













538


539
540

















541
542

543
544
545
546
547
548














549


550






551

552
553







554

555
556
557
558
559
560
561













562
563
564
565
566

























567
568
569
570
571






572
573

574
575
576
577
578
579
580




581
582
583


584
585
586
587
588


589
590

591
592
593
594
595
596
597
598
599
600
601
602



603
604
605


606
607

608

609
610
611



612
613

614
615
616
617
618

619

620
621
622

623
624


625
626
627
628
629
630
631


632
633
634
635
636
637






638
639
640
641
642
643
644







645


646
647



648
649
650


651
652
653
654
655
656



657
658
659
660

661
662

663
664
665
666
667



668
669

670
671


672
673
674


675
676
677
678


679
680
681
682
683



684
685
686
687
688
689
690
691


692
693


694
695



696
697




698
699
700
701







702
703

























704
705
706
707
708
709
710
711
712














713




714
715
716
717
718








719






720
721
722
723
724
725
423
424
425
426
427
428
429




















430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467

468
469
470
471
472
473
474
475
476
477

478
479
480
481
482

483



484



485



486
487








488
489
490
491
492
493
494

495
496
497
498
499

500
501





502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518


519
520
521
522
523



524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542



543
544
545
546
547
548
549



550
551
552
553
554
555
556
557



558
559
560
561
562
563
564
565


566
567
568
569
570
571
572

573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978

979
980
981
982
983
984
985
986
987



988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006



1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035









































1036
1037





1038
1039











































1040
1041
1042
1043
1044
1045
1046
1047

1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074


1075
1076
1077
1078
1079
1080


1081
1082
1083
1084
1085
1086


1087
1088
1089
1090
1091
1092


1093
1094
1095
1096
1097
1098


1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113


1114
1115
1116
1117


1118
1119
1120
1121


1122
1123
1124
1125
1126
1127



1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151


1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172





1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189

1190
1191
1192
1193
1194
1195
1196
1197


1198
1199
1200
1201
1202
1203
1204
1205
1206







1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220




1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248


1249
1250
1251
1252
1253
1254
1255

1256
1257


1258



1259
1260
1261
1262
1263


1264
1265
1266




1267
1268


1269
1270

1271


1272




1273

1274
1275
1276
1277


1278
1279

1280
1281

1282
1283


1284
1285
1286
1287

1288


1289

1290
1291

1292


1293
1294


1295
1296

1297


1298

1299
1300
1301






1302
1303
1304
1305
1306
1307

1308





1309
1310
1311
1312
1313
1314
1315
1316
1317
1318


1319
1320
1321
1322


1323
1324

1325




1326
1327
1328




1329


1330


1331


1332
1333
1334
1335

1336


1337
1338
1339


1340
1341

1342


1343
1344
1345




1346
1347
1348
1349




1350

1351
1352
1353


1354
1355
1356
1357
1358
1359
1360


1361
1362
1363
1364
1365



1366
1367
1368
1369
1370
1371
1372
1373

1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399








1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418





1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-









+
+
+



+
+
+


















+
+
-
+









-
+




-
+
-
-
-
+
-
-
-
+
-
-
-


-
-
-
-
-
-
-
-
+






-

+



-
+

-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
-
-
+
+
+

+
-
-
-
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+

+
-
-
-
+
+
+
+
+
+

+
-
-
-
+
+
+
+
+
+


-
-
+
+

+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
+

+


+
+
+

-
-
-
+
+
+
+
+
+
+


+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







+
-
+




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+

+
+
-
-
+
+
+
+
+

-
-
+
+

+
+
+
-
-
+
+
+

+
+
-
-
+
+
+
+
+
+

+
+
+
+
+
+
+
+
-
-
+
+

+
-
-
+
+

+
-
-
+
+

+
+
+
-
-
-
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+

-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
-
+
+
+
+
+
+

+
-
-
+
+
+
+
+
+
+

+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
-
+
+
+
+
+
+

-
+

-
-

-
-
-
+
+
+
+

-
-
+
+

-
-
-
-
+
+
-
-
+

-

-
-

-
-
-
-

-
+
+
+

-
-
+
+
-

+
-
+

-
-
+
+
+

-
+
-
-

-

+
-
+
-
-

+
-
-
+
+
-

-
-

-

+
+
-
-
-
-
-
-
+
+
+
+
+
+
-

-
-
-
-
-
+
+
+
+
+
+
+

+
+
-
-
+
+
+

-
-
+
+
-

-
-
-
-
+
+
+
-
-
-
-
+
-
-
+
-
-

-
-
+
+
+

-
+
-
-
+
+

-
-
+
+
-

-
-
+
+

-
-
-
-
+
+
+

-
-
-
-

-

+
+
-
-
+
+


+
+
+
-
-
+
+
+
+

-
-
-
+
+
+
+
+
+
+

-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+

+
+
+
+
+
+






        return
endp


;_________________________________________________________________________________________


method TWindow.SetBorder
begin
        push    eax esi

        mov     esi, [.self]
        mov     eax, [.value]
        xchg    eax, [esi+TWindow._border]
        cmp     eax, [esi+TWindow._border]
        je      .finish ; not changed

        stdcall _SetWindowBorder, [esi+TWindow.handle], [esi+TWindow._border]

.finish:
        pop     esi eax
        return
endp


;_________________________________________________________________________________________

method TWindow.SetCaption
begin
        push    eax esi

        mov     esi, [.self]

        lea     eax, [esi+TWindow._caption]
        stdcall SetString, eax, [.value]
        stdcall StrPtr, [eax]

        cmp     [esi+TWindow.handle], 0
        je      @f

        stdcall _SetWindowTextUtf8, [esi+TWindow.handle], eax

@@:
        exec    esi, TWindow:Refresh

        pop     esi eax
        return
endp


;_________________________________________________________________________________________


method TWindow.SetVisible
begin
        push    eax esi

        mov     esi, [.self]
        mov     eax, [.value]
        xchg    [esi+TWindow._visible], eax
        cmp     [esi+TWindow._visible], eax
        je      .finish

        exec    esi, TWindow:__UpdateFocus
        exec    esi, TWindow:__UpdateHandle
        stdcall _ShowWindow, [esi+TWindow.handle], [esi+TWindow._visible]
        exec    esi, TWindow:Refresh

.finish:
        pop     esi eax
        return
endp


;_________________________________________________________________________________________

method TWindow.SetSplitGrid
method TWindow.SetOnPaint
begin
        push    eax esi

        mov     esi, [.self]
        mov     eax, [esi+TWindow._pSplitGrid]
        mov     eax, [.value]
        test    eax, eax
        jz      @f

        xchg    [esi+TWindow._OnPaint], eax
        sub     eax, TArray.array
        stdcall FreeMem, eax
        mov     [esi+TWindow._pSplitGrid], 0
        cmp     [esi+TWindow._OnPaint], eax

@@:
        cmp     [.value], 0
        je      .finish

        stdcall ReadSplitGridTemplate, [.value]
        test    eax, eax
        jz      .finish

        add     eax, TArray.array
        mov     [esi+TWindow._pSplitGrid], eax

        exec    esi, TWindow:AlignChildren
        exec    esi, TWindow:Refresh

.finish:
        pop     esi eax
        return
endp


;_________________________________________________________________________________________


method TWindow.SetSplitCell
begin
        pushad
        push    eax

        mov     esi, [.self]
        get     edi, esi, TWindow:Parent
        get     edx, edi, TWindow:SplitGrid
        test    edx, edx
        jz      .finish         ; there is no splitgrid set on the parent
        get     eax, [.self], TWindow:Parent
        istype  eax, TForm
        jne     .finish

        exec    eax, TForm:AttachControlToCell, [.self], [.value]

.finish:
        pop     eax
        return
endp


;_________________________________________________________________________________________


method TWindow.GetGlobalEnabled
begin
        mov     ecx, 1
        mov     ebx, [.value]
        push    ecx

        mov     ecx, [.self]

        get     eax, ecx, TWindow:Action
.search_loop:
        test    [edx+TSplitRect.type], stNone
        jnz     .check
        test    eax, eax
        jz      .action_ok

        get     eax, eax, TAction:Enabled
        jmp     .check_parent

.action_ok:
        mov     eax, [ecx+TWindow._enabled]

.check_parent:
        test    eax, eax
        jz      .finish

        get     ecx, [.self], TWindow:Parent
        jecxz   .finish

        get     eax, ecx, TWindow:GlobalEnabled

.finish:
        inc     ecx
        add     edx, sizeof.TSplitRect
        jmp     .search_loop
        pop     ecx
        return
endp



;_________________________________________________________________________________________
.check:
        cmp     [edx+TSplitRect.id], ebx
        je      .found



method TWindow.GetEnabled
begin
        push    ecx

        mov     ecx, [.self]
        add     edx, sizeof.TSplitRect
        dec     ecx
        jnz     .search_loop

        get     eax, ecx, TWindow:Action
        test    eax, eax
        jz      .action_ok

        get     eax, eax, TAction:Enabled
        jmp     .finish

.found:
        mov     [edx+TSplitRect.pWindow], esi
.action_ok:
        mov     eax, [ecx+TWindow._enabled]

.finish:
        pop     ecx
        return
endp
        exec    edi, TWindow:AlignChildren




method TWindow.SetEnabled
begin
        push    ecx
        mov     ecx, [.self]
        push    [.value]
        pop     [ecx+TWindow._enabled]

        exec    ecx, TWindow:__UpdateFocus
        exec    ecx, TWindow:Refresh

        pop     ecx
        return
endp




;_________________________________________________________________________________________
;
; returns the pointer of the image TWindow.ImgScreen but only after ensuring that the
; contained image is valid.

method TWindow.GetImgScreen
.dest RECT
.xSrc dd ?
.ySrc dd ?
begin
        pushad

        mov     esi, [.self]

        exec    esi, TWindow:__UpdateScreen
        mov     edx, [esi+TWindow._screen]
        test    edx, edx
        jnz     .process_screen

        mov     edx, [esi+TWindow._canvas]
        jmp     .end_loop

.process_screen:
        mov     eax, [esi+TWindow._invalid_rect.right]
        mov     ecx, [esi+TWindow._invalid_rect.bottom]

        sub     eax, [esi+TWindow._invalid_rect.left]
        jz      .finish

        sub     ecx, [esi+TWindow._invalid_rect.top]
        jz      .finish

        get     ebx, esi, TWindow:Canvas

; start with the background.

        stdcall CopyImageRect, edx, [esi+TWindow._invalid_rect.left], [esi+TWindow._invalid_rect.top], ebx, [esi+TWindow._invalid_rect.left], [esi+TWindow._invalid_rect.top], eax, ecx

; then blend the children windows

        lea     edi, [esi+TWindow._invalid_rect]                ; EDI = invalid rect.

        get     ebx, esi, TObject:Children
        test    ebx, ebx
        jz      .end_loop

        xor     ecx, ecx
        cmp     ecx, [ebx+TArray.count]
        je      .end_loop

.children_loop:
        mov     esi, [ebx+4*ecx+TArray.array]

        istype  esi, TWindow
        jne     .next_child

        get     eax, esi, TWindow:Visible
        test    eax, eax
        jz      .next_child

        push    [esi+TWindow._x] [esi+TWindow._y] [esi+TWindow._width] [esi+TWindow._height]
        pop     [.dest.bottom] [.dest.right] [.dest.top] [.dest.left]

        mov     eax, [.dest.left]
        add     [.dest.right], eax

        mov     eax, [.dest.top]
        add     [.dest.bottom], eax

        lea     eax, [.dest]
        stdcall RectIntersect, eax, eax, edi
        jc      .next_child                  ; the rectangles does not intersect, so the child should not to be painted.

        mov     eax, [.dest.left]
        sub     [.dest.right], eax

        sub     eax, [esi+TWindow._x]
        mov     [.xSrc], eax

        mov     eax, [.dest.top]
        sub     [.dest.bottom], eax
        sub     eax, [esi+TWindow._y]
        mov     [.ySrc], eax

        get     eax, esi, TWindow:ImgScreen


        stdcall BlendImage, edx, [.dest.left], [.dest.top], eax, [.xSrc], [.ySrc], [.dest.right], [.dest.bottom]

.next_child:
        inc     ecx
        cmp     ecx, [ebx+TArray.count]
        jne     .children_loop

.end_loop:
        mov     esi, [.self]

        get     eax, esi, TWindow:Enabled
        test    eax, eax
        jnz     .dis_ok

;        stdcall FilterDisabled, edx, [esi+TWindow.handle]

.dis_ok:
        xor     eax, eax
        mov     [esi+TWindow._invalid_rect.left], eax
        mov     [esi+TWindow._invalid_rect.top], eax
        mov     [esi+TWindow._invalid_rect.right], eax
        mov     [esi+TWindow._invalid_rect.bottom], eax

.finish:
        mov     [esp+4*regEAX], edx
        popad
        return
endp



;_________________________________________________________________________________________


method TWindow.GetCanvas
begin

        exec    [.self], TWindow:__UpdateCanvas

        mov     eax, [.self]
        mov     eax, [eax+TWindow._canvas]
        return
endp



;_________________________________________________________________________________________


method TWindow.GetOSWindow
begin
        push    esi

        mov     esi, [.self]

.loop:
        cmp     [esi+TWindow.handle], 0
        jne     .finish

        get     esi, esi, TWindow:Parent
        test    esi, esi
        jnz     .loop

.finish:
        mov     eax, esi
        pop     esi
        return
endp


;_________________________________________________________________________________________


method TWindow.Paint
.rect RECT
begin
        pushad

        mov     esi, [.self]

        get     eax, esi, TWindow:OnPaint
        test    eax, eax
        jz      .user_paint_ok

        get     ecx, esi, TWindow:Canvas
        stdcall eax, esi, ecx                   ; user OnPaint handler.

.user_paint_ok:

        xor     ecx, ecx
        mov     eax, [esi+TWindow._width]
        mov     edx, [esi+TWindow._height]

        mov     [.rect.left], ecx
        mov     [.rect.top], ecx
        mov     [.rect.right], eax
        mov     [.rect.bottom], edx
        lea     eax, [.rect]
        exec    esi, TWindow:RectChanged, eax

        popad
        return
endp


;_________________________________________________________________________________________

method TWindow.Refresh
.rect RECT
begin
        exec    [.self], TWindow:Paint
        exec    [.self], TWindow:Update
        return
endp



method TWindow.RefreshAll
begin
        pushad
        get     esi, [.self], TObject:Children
        test    esi, esi
        jz      .end_loop

        mov     ecx, [esi+TArray.count]

.loop:
        dec     ecx
        js      .end_loop

        istype  [esi+TArray.array+4*ecx], TWindow
        jne     .loop

        exec    [esi+TArray.array+4*ecx], TWindow:RefreshAll
        jmp     .loop

.end_loop:
        exec    [.self], TWindow:Refresh

        popad
        return
endp




method TWindow.Update
.rect RECT
begin
        pushad

        mov     esi, [.self]

        xor     ecx, ecx
        mov     eax, [esi+TWindow._width]
        mov     edx, [esi+TWindow._height]

        mov     [.rect.left], ecx
        mov     [.rect.top], ecx

        mov     [.rect.right], eax
        mov     [.rect.bottom], edx


.loop:
        lea     eax, [.rect]
        exec    esi, TWindow:RectChanged, eax

        mov     eax, [esi+TWindow._x]
        mov     edx, [esi+TWindow._y]

        add     [.rect.left], eax
        add     [.rect.top], edx
        add     [.rect.right], eax
        add     [.rect.bottom], edx

        get     ecx, esi, TWindow:Parent

        jecxz   .refresh

        mov     esi, ecx
        jmp     .loop


.refresh:
        cmp     [esi+TWindow.handle], 0
        je      .finish

        mov     eax, [esi+TWindow._invalid_rect.right]
        mov     edx, [esi+TWindow._invalid_rect.bottom]

        sub     eax, [esi+TWindow._invalid_rect.left]
        sub     edx, [esi+TWindow._invalid_rect.top]

        stdcall _RefreshWindowRect, [esi+TWindow.handle], [esi+TWindow._invalid_rect.left], [esi+TWindow._invalid_rect.top], eax, edx

.finish:
        popad
        return
endp



;_________________________________________________________________________________________


;---------------------------------------------------------------------------------
; Arguments:
;   .self
;   .x
;   .y
;
; Returns:
;   eax - pointer to TWindow
;   ecx - X coordinates, translated to the client coordinates of the child.
;   edx - Y coordinates, translated to the client coordinates of the child.
;
; If children window was not found, the method returns:
; eax = [.self]
; ecx = [.x]
; edx = [.y]
;---------------------------------------------------------------------------------

method TWindow.ChildByXY
begin
        push    ebx esi edi

        mov     eax, [.self]
        mov     ecx, [.x]
        mov     edx, [.y]

        mov     esi, [eax+TObject.__pChildren]
        test    esi, esi
        jz      .finish

        mov     edi, [esi+TArray.count]
        lea     esi, [esi+TArray.array]


.loop:
        dec     edi
        js      .finish

        mov     ebx, [esi+4*edi]

        istype  ebx, TWindow
        jne     .loop

        sub     ecx, [ebx+TWindow._x]
        jl      .no2

        sub     edx, [ebx+TWindow._y]
        jl      .no

        cmp     ecx, [ebx+TWindow._width]
        jge     .no

        cmp     edx, [ebx+TWindow._height]
        jge      .no

        cmp     [.onlyenabled], FALSE
        je      .enabled_ok

        push    eax
        get     eax, ebx, TWindow:GlobalEnabled
        test    eax, eax
        pop     eax
        jz      .no


.enabled_ok:
        pushad

        get     esi, ebx, TWindow:Canvas

        mov     eax, edx
        imul    eax, [esi+TImage.width]
        shl     eax, 2
        add     eax, [esi+TImage.pPixels]

        cmp     byte [eax+4*ecx+3], 0   ; the alpha value under the pointer
        popad
        jne     .yes


.no:
        add     edx, [ebx+TWindow._y]

.no2:
        add     ecx, [ebx+TWindow._x]
        jmp     .loop


.yes:
        mov     eax, ebx
        exec    eax, TWindow:ChildByXY, ecx, edx, [.onlyenabled]

.finish:
        popad
        pop     edi esi ebx
        return

endp




;_________________________________________________________________________________________


method TWindow.UpdateBounds
;
; Includes the passed rectangle in the invalid rectangle. Later this rectangle will need
; to be repainted, but only when the screen image is required.
;

method TWindow.RectChanged      ;, .pRect
.client RECT
begin
        push    eax ecx

        xor     eax, eax
        mov     [.client.left], eax
        mov     [.client.top], eax

        mov     eax, [.self]

        push    [eax+TWindow._height] [eax+TWindow._width]
        pop     [.client.right] [.client.bottom]

        mov     ecx, [.self]
        lea     eax, [ecx+TWindow._x]
        stdcall _SetWindowBounds, [ecx+TWindow.handle], eax
        mov     ecx, [eax+TWindow._invalid_rect.right]
        sub     ecx, [eax+TWindow._invalid_rect.left]
        jz      .copy

        mov     ecx, [eax+TWindow._invalid_rect.bottom]
        sub     ecx, [eax+TWindow._invalid_rect.top]
        jnz     .add

.copy:
        lea     eax, [eax+TWindow._invalid_rect]
        stdcall RectCopy, eax, [.pRect]
        jmp     .intersect

.add:
        lea     eax, [eax+TWindow._invalid_rect]
        stdcall RectBounding, eax, eax, [.pRect]

.intersect:
        lea     ecx, [.client]
        stdcall RectIntersect, eax, eax, ecx

        pop     ecx eax
        return
endp


;_________________________________________________________________________________________


method TWindow.Refresh
begin
        push    eax

        mov     eax, [.self]
        cmp     [eax+TWindow._visible], 0
        je      .finish

        stdcall _RefreshWindow, [eax+TWindow.handle]

.finish:
        pop     eax
        return
endp

;_________________________________________________________________________________________

method TWindow.AddChild
begin
        push    eax ebx

        istype  [.child], TWindow
        jne     .add_not_window

        mov     ebx, [.child]
        mov     eax, [.self]

        stdcall _AddChild, [eax+TWindow.handle], [ebx+TWindow.handle]

        clc
        pop     ebx eax
        return


.add_not_window:        ; this is possible, but not implemented for now.
        stc
        pop     ebx eax
        return
endp


method TWindow.SetParent
begin
        exec    [.value], TWindow:AddChild, [.self]
        return
endp


        inherited [.value]
        exec    [.self], TWindow:__UpdateHandle      ; create/destroy handle of the OS window, according to the  window state.
;_________________________________________________________________________________________

method TWindow.AlignChildren
  .winrect RECT
begin
        pushad

        mov     esi, [.self]

        cmp     [esi+TWindow._pSplitGrid], 0
        je      .endalign

        xor     eax, eax
        mov     [.winrect.left], eax
        mov     [.winrect.top], eax

        get     eax, esi, TWindow:width
        get     edx, esi, TWindow:height

        mov     [.winrect.right], eax
        mov     [.winrect.bottom], edx

        lea     eax, [.winrect]
        get     edx, esi, TWindow:SplitGrid

        stdcall RealignGrid, edx, eax

        exec    esi, TWindow:Refresh

.endalign:
        pop     edi esi
        return
endp


;_________________________________________________________________________________________

method  TWindow.Focus
begin
        push    eax
        mov     eax, [.self]
        stdcall _SetFocus, [eax+TWindow.handle]
        pop     eax
        return
endp


;_________________________________________________________________________________________



method TWindow.SysEventHandler
method TWindow.__UpdateHandle
begin
        pushad

        mov     esi, [.self]
        xor     ecx, ecx

        cmp     [esi+TWindow._visible], ecx
        je      .no_handle

        get     eax, esi, TWindow:Parent

        test    eax, eax
        jnz     .no_handle

; need handle

        cmp     [esi+TWindow.handle], ecx
        jne     .finish                         ; the window needs OS handle and has one.

; The window has no handle, but needs it.

        stdcall _CreateWindow, esi
        mov     [esi+TWindow.handle], eax

;        stdcall _CreateNullWindow
;        mov     [esi+TWindow.handle], eax
        mov     ebx, [.pEvent]
        mov     eax, [ebx+TSysEvent.event]
;        mov     ebx, eax

;        stdcall _SetWindowStruct, ebx, esi

;        stdcall StrPtr, [esi+TWindow._caption]
;        stdcall _SetWindowTextUtf8, ebx, eax
        cmp     eax, seMouseEnter
        je      .mouseenter

;        lea     eax, [esi+TWindow._x]
;        stdcall _SetWindowBounds, ebx, eax

;        stdcall _SetWindowBorder, ebx, [esi+TWindow._border]

        cmp     eax, seMouseLeave
        je      .mouseleave
        stdcall _ShowWindow, eax, TRUE


.finish:
        popad
        return
        cmp     eax, seMouseBtnPress
        je      .mouse_btnpress


.no_handle:

        cmp     [esi+TWindow.handle], ecx
        je      .finish                         ; no need for handle and there is no such.
        cmp     eax, seMouseBtnRelease
        je      .mouse_btnrelease

   ;     stdcall _ShowWindow, [esi+TWindow.handle], 0
        stdcall _DestroyWindow, [esi+TWindow.handle]    ; destroy not needed window handle.

        mov     [esi+TWindow.handle], ecx
        jmp     .finish

endp




method TWindow.__UpdateFocus
begin
        mov     eax, [.self]
        cmp     eax, seResize
        je      .resize
        cmp     eax, [__FocusedWindow]
        jne     .finish

        get     eax, [.self], TWindow:Visible
        cmp     eax, seMouseMove
        je      .mousemove
        test    eax, eax
        jz      .clear

        get     eax, [.self], TWindow:Enabled
        cmp     eax, sePaint
        je      .paint
        test    eax, eax
        jz      .clear

        get     eax, [.self], TWindow:WantFocus
        test    eax, eax
        jz      .clear
.no_action:
        stc
        popad

.finish:
        return

.clear:
        mov     [__FocusedWindow], 0
        exec    [.self], TWindow:EventFocusOut
        return
endp





method TWindow.__UpdateCanvas
begin
        pushad
        mov     esi, [.self]
        mov     edi, [esi+TWindow._canvas]
        mov     ecx, [esi+TWindow._width]
        mov     edx, [esi+TWindow._height]

        test    edi, edi
        jz      .create_new
.finish:
        clc

        cmp     [edi+TImage.width], ecx
        jne     .destroy_img

        cmp     [edi+TImage.height], edx
        je      .imageok


.destroy_img:

        stdcall DestroyImage, edi

.create_new:
        stdcall CreateImage, ecx, edx
        mov     [esi+TWindow._canvas], eax

.imageok:
        popad
        return
endp

;.........................................................................................
.paint:
        get     eax, esi, TWindow:SplitGrid
        test    eax, eax
        jz      .no_action




method TWindow.__UpdateScreen
begin
        pushad
        mov     esi, [.self]
        mov     edi, [esi+TWindow._screen]
        mov     ecx, [esi+TWindow._width]
        mov     edx, [esi+TWindow._height]

        test    edi, edi
        jz      .create_new

        cmp     [edi+TImage.width], ecx
        jne     .destroy_img
        stdcall DrawSplitters, [ebx+TPaintEvent.context], eax

        cmp     [edi+TImage.height], edx
        je      .imageok


.destroy_img:

        stdcall DestroyImage, edi
        clc
        jmp     .finish

.create_new:
        mov     eax, [esi+TWindow.__pChildren]
        test    eax, eax
        jz      .imageok
        cmp     [eax+TArray.count], 0
        je      .imageok

        stdcall CreateImage, ecx, edx
;.........................................................................................
.move:
        mov     eax, [ebx+TMoveEvent.newX]
        mov     ecx, [ebx+TMoveEvent.newY]
        mov     [esi+TWindow._x], eax
        mov     [esi+TWindow._y], ecx
        jmp     .finish

        mov     [esi+TWindow._screen], eax

        xor     eax, eax
        mov     [esi+TWindow._invalid_rect.left], eax
        mov     [esi+TWindow._invalid_rect.top], eax
        mov     [esi+TWindow._invalid_rect.right], ecx
        mov     [esi+TWindow._invalid_rect.bottom], edx

.imageok:
        popad
        return
endp

;.........................................................................................
.resize:
        mov     eax, [ebx+TResizeEvent.newWidth]
        mov     ecx, [ebx+TResizeEvent.newHeight]





; System events methods




method TWindow.EventResize     ;, .newWidth, .newHeight
begin
        pushad
        mov     esi, [.self]

        mov     eax, [.newWidth]
        mov     ecx, [.newHeight]

        cmp     eax, [esi+TWindow._width]
        jne     .update

        cmp     ecx, [esi+TWindow._height]
        je      .finish

.update:
        mov     [esi+TWindow._width], eax
        mov     [esi+TWindow._height], ecx

        exec    esi, TWindow:AlignChildren
        jmp     .finish
        exec    esi, TWindow:Paint

.finish:
        popad
        return
endp

;.........................................................................................


.mouse_btnpress:
        exec    esi, TWindow:Focus

        get     ecx, esi, TWindow:SplitGrid
        test    ecx, ecx
        jz      .finish
method TWindow.EventMove       ;, .newX, .newY
begin
        push    esi
        mov     esi, [.self]

        cmp     [ebx+TMouseButtonEvent.Button], mbLeft
        jne     .finish
        push    [.newX] [.newY]
        pop     [esi+TWindow._y] [esi+TWindow._x]

        lea     eax, [ebx+TMouseButtonEvent.x]
        stdcall FindSplitter, ecx, eax
        jnc     .finish

        pop     esi
        return
        test    [eax+TSplitRect.type], stJustGap
        jnz     .finish
endp

        mov     [esi+TWindow._dragSplitter], eax

        stdcall MouseCapture, [esi+TWindow.handle]
        jmp     .finish

;.........................................................................................
.mousemove:
        cmp     [esi+TWindow._dragSplitter], 0
        je      .set_mouse_cursor

        mov     edi, [esi+TWindow._dragSplitter] ; splitter to resize
method TWindow.EventMouseEnter
begin
        push    esi edx

        mov     ecx, [edi+TSplitRect.type]
        and     ecx, stVert
        mov     esi, [.self]
        get     edx, esi, TWindow:OSWindow
        mov     eax, [ebx+TMouseMoveEvent.x+ecx] ; the respective coordinate.

        stdcall GetStockCursor, [esi+TWindow._cursor]
        sub     eax, [edi+TSplitRect.rect.left+ecx]
        stdcall SetMouseCursor, [edx+TWindow.handle], eax

        test    [edi+TSplitRect.type], stOriginBR
        jz      .sizeok
        pop     edx esi
        return
endp

        mov     edx, [edi+TSplitRect.rect.right+ecx]

        sub     eax, edx
        neg     eax

        sub     eax, [edi+TSplitRect.spWidth]

method TWindow.EventMouseLeave
.sizeok:
begin
        test    [edi+TSplitRect.type], stRelative
        jz      .posok

        return
        cdq
        mov     ebx, $8000
endp

        imul    ebx

        mov     ebx, [edi+TSplitRect.rect.right+ecx]
        sub     ebx, [edi+TSplitRect.rect.left+ecx]     ; size of rect (x or y depending on type)

        idiv    ebx

method TWindow.EventMouseMove   ;, .x, .y, .kbdState
begin
.posok:
        cmp     eax, [edi+TSplitRect.min]
        jge     @f
        mov     eax, [edi+TSplitRect.min]
@@:
        cmp     [edi+TSplitRect.max], 0

        return
endp



        je      @f

        cmp     eax, [edi+TSplitRect.max]
        jle     @f
        mov     eax, [edi+TSplitRect.max]
@@:
        mov     edx, $8000 ;==100%
method TWindow.EventButtonPress        ;, .button, .kbdState, .x, .y
begin

        return
endp



method TWindow.EventButtonRelease      ;, .button, .kbdState, .x, .y
begin
        test    [edi+TSplitRect.type], stRelative
        jnz     @f

        return
endp

        mov     edx, [edi+TSplitRect.rect.right+ecx]
        sub     edx, [edi+TSplitRect.rect.left+ecx]


        sub     edx, [edi+TSplitRect.spWidth]

@@:
        cmp     eax, edx
        jle     @f
        mov     eax, edx
method TWindow.EventScroll     ;, .direction, .command, .value
begin
        mov     eax, [.self]
@@:
        mov     [edi+TSplitRect.pos], eax
        stdcall RealignGrid, edi, edi

        cmp     [eax+TWindow._OnScroll], 0
; In order to avoid flicker, [.hwnd] must have WS_CLIPCHILDREN set.

        je      .finish
        exec    esi, TWindow:Refresh
        jmp     .finish

.set_mouse_cursor:
        mov     ecx, [esi+TWindow._cursor]
        pushad
        stdcall [eax+TWindow._OnScroll], [.self], [.direction], [.command], [.value]
        popad

        get     edx, esi, TWindow:SplitGrid
.finish:
        test    edx, edx
        jz      .cursor_ok
        return
endp

        lea     eax, [ebx+TMouseMoveEvent.x]
        stdcall FindSplitter, edx, eax


        jnc     .cursor_ok

        test    [eax+TSplitRect.type], stJustGap
        jnz     .finish
method TWindow.CloseRequest     ;, .reason
begin

        mov     ecx, mcSizeH
        test    [eax+TSplitRect.type], stVert
        jz      .cursor_ok
        mov     ecx, mcSizeV
        return
endp


.cursor_ok:
        stdcall GetStockCursor, ecx
        stdcall SetMouseCursor, eax
        jmp     .finish

;.........................................................................................

method TWindow.EventKeyPress    ;, .utf8, .scancode, .kbdState
begin
.mouse_btnrelease:
        cmp     [esi+TWindow._dragSplitter], 0
        mov     eax, [.self]
        cmp     [eax+TWindow._OnKeyPressed], 0
        je      .finish

        pushad
        stdcall [eax+TWindow._OnKeyPressed], [.self], [.utf8], [.scancode], [.kbdState]
        popad
        cmp     [ebx+TMouseButtonEvent.Button], mbLeft
        jne     .finish

.finish:
        return
endp

        stdcall MouseCapture, NULL
        mov     [esi+TWindow._dragSplitter], 0
        jmp     .finish


method TWindow.EventKeyRelease  ;, .kbdState
begin

        return
endp

;.........................................................................................


method TWindow.EventFocusIn
begin
        exec    [.self], TWindow:Refresh
        return
endp



method TWindow.EventFocusOut
begin
        exec    [.self], TWindow:Refresh
        return
endp




; Utility procedures.


method  TWindow.ClientToScreenXY; , .window, .x, .y
begin
        push    eax esi

.mouseenter:
        mov     eax, [esi+TWindow._cursor]
        test    eax, $ffffff00
        jnz     @f
        stdcall GetStockCursor, eax
@@:
        stdcall SetMouseCursor, eax
        jmp     .finish
        mov     ecx, [.x]
        mov     edx, [.y]
        mov     esi, [.self]

.loop:
        get     eax, esi, TWindow:Parent
        test    eax, eax
        jz      .os_win

        add     ecx, [esi+TWindow._x]
        add     edx, [esi+TWindow._y]

        mov     esi, eax
        jmp     .loop

.os_win:
        mov     eax, [esi+TWindow.handle]
        test    eax, eax
        jz      .finish
;.........................................................................................
.mouseleave:
        stdcall GetStockCursor, mcArrow
        stdcall SetMouseCursor, eax
        jmp     .finish


        stdcall _ClientToScreen, eax, ecx, edx

.finish:
        pop     esi eax
        return
endp



method TWindow.UpdateAction
begin
        exec    [.self], TWindow:Refresh
        return
endp



endmodule

Deleted freshlib/gui/ThemeGUI.asm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200








































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: This file contains procedures and data, that form the appearance of the
;               FreshLib GUI application. Colors, control borders, backgrownd drawing etc.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: The user should be able to change these settings and if he uses external
;         procedures, then the code from this library should not be compiled.
;_________________________________________________________________________________________
module "GUI theme data and code library"

; Box border type
bxNone   = 0
bxRaised = 1
bxSunken = 2
bxFlat   = 3
bxNoFill = $80000000

; Default colors
iglobal
  var clBorderLight   = $ffffffff
  var clBorderDark    = $ff606060 ; soft shadow
  var clBorderNeutral = $ffa0a0a8

; edit colors
  var clEditBk        = $fffffff0
  var clEditTxt       = $ff000000
  var clEditSel       = $ff0000a0
  var clEditSelTxt    = $ffffffff

; button colors
  var clButtonBk      = $ffd0d0d8
  var clButtonTxt     = $ff000000

  var clButtonHotBk   = $ffe0e0e8
  var clButtonHotTxt  = $ff0000ff

; dialog box colors.
  var clDialogBk      = $ffd0d0d8
  var clDialogTxt     = $ff000000

; scrollbar colors
  var clScrollBk      = $ffa0a0a0
  var clScrollSlider  = $ffd0d0d8

; splitter colors
  var clSplitter      = $ff80a0a0

; grid colors.
  var clGridCellBk    = $ffffffff         ; normal data cell background
  var clGridCellText  = $ff000000         ; normal cell text color

  var clGridSelBk     = $ff000080         ; selected cell background
  var clGridSelText   = $ffffffff         ; selected cell text color

  var clGridFixedBk   = $ffd0d0d8         ; fixed cell background
  var clGridFixedText = $ff000000         ; fixed cell text color

  var clGridLines     = $ff000000

  var clGridMarked    = $ff0000a0         ; background for the cells that are selected in the moment.

; drawing functions.

  if ~defined DrawBox | defined ___DrawBox
    var DrawBox = DrawBoxDefault
    ___DrawBox = 1
  end if

  if ~defined DrawSlider | defined ___DrawSlider
    var DrawSlider = DrawSliderDefault
    ___DrawSlider = 1
  end if

  if ~defined DrawSplitter | defined ___DrawSplitter
    var DrawSplitter = DrawSplitterDefault2
    ___DrawSplitter = 1
  end if


endg





; Midnight colors
;iglobal
;  var clBorderLight   = $0000ff
;  var clBorderDark    = $000000
;  var clBorderNeutral = $808080
;
;  var clEditBk        = $0000c0
;  var clEditTxt       = $ffffff
;  var clEditSel       = $0000ff
;  var clEditSelTxt    = $000000
;
;  var clButtonBk      = $000080
;  var clButtonTxt     = $ffffff
;
;  var clButtonHotBk   = $0000a0
;  var clButtonHotTxt  = $ffffff
;
;  var clDialogBk      = $000080
;  var clDialogTxt     = $ffffff
;endg




proc DrawBoxDefault, .context, .pBounds, .bkground, .border
  .brd RECT
begin
        push    eax ecx edx esi


        stdcall SetDrawMode, [.context], cmCopy

        mov     esi, [.pBounds]

        mov     edx, [.border]
        and     edx, $ff
        jz      .borderok

        mov     eax, [esi+TBounds.x]
        mov     ecx, [esi+TBounds.y]
        mov     [.brd.left], eax
        mov     [.brd.top], ecx

        add     eax, [esi+TBounds.width]
        add     ecx, [esi+TBounds.height]
        dec     eax
        dec     ecx
        mov     [.brd.right], eax
        mov     [.brd.bottom], ecx

        sub     [esi+TBounds.width], 2
        sub     [esi+TBounds.height], 2
        inc     [esi+TBounds.x]
        inc     [esi+TBounds.y]

        mov     eax, [clBorderLight]
        mov     ecx, [clBorderDark]

        cmp     edx, bxRaised
        je      .colorok

        xchg    eax, ecx

        cmp     edx, bxSunken
        je      .colorok

        mov     eax, [clBorderNeutral]
        mov     ecx, eax

.colorok:
        stdcall SetSimpleLine, [.context], eax
        stdcall DrawLine, [.context], [.brd.left],  [.brd.top], [.brd.left], [.brd.bottom]
        stdcall DrawLine, [.context], [.brd.left],  [.brd.top], [.brd.right], [.brd.top]

        stdcall SetSimpleLine, [.context], ecx
        stdcall DrawLine, [.context], [.brd.left], [.brd.bottom], [.brd.right], [.brd.bottom]
        inc      [.brd.bottom]
        stdcall DrawLine, [.context], [.brd.right], [.brd.top], [.brd.right], [.brd.bottom]

.borderok:
        bt      [.border], 31
        jc      .fillok
        stdcall DrawFillRect, [.context], [esi+TBounds.x], [esi+TBounds.y], [esi+TBounds.width], [esi+TBounds.height], [.bkground]

; additional 1px margin
        sub     [esi+TBounds.width], 2
        sub     [esi+TBounds.height], 2
        inc     [esi+TBounds.x]
        inc     [esi+TBounds.y]

.fillok:
        pop     esi edx ecx eax
        return
endp


sliderHorizontal = 0
sliderVertical   = 1

proc DrawSliderDefault, .context, .pBounds, .bkground, .type
begin
        stdcall [DrawBox], [.context], [.pBounds], [.bkground], bxRaised
        return
endp



endmodule
Changes to freshlib/gui/Win32/Main.asm.
8
9
10
11
12
13
14




15

16

17
18

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33













































34
35


36

37

38
39
40


41
42
43
44
45
46

47
48
49
50
51
52
53

54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92


93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122



123

124


125


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141











142

143
144
145
146
147







148













149
150
151
152
153
154
155







156
157
158
159
160


161
162
163

164
165

166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

188
189
190
191

192
193
194

195
196
197
198
199
200
201
202


203
204
205
206
207
208
209
210

211
212
213
214



215

216
217

218
219
220
221
222
223




224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240
241
242
243
244
245

246
247
248
249


250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276












277

278
279



280

281
282



283











284
285
286
287
288
289
290










291
292
293
294
295
296
297
298
299
300

301
302

303
304
305
306
307
308
309
310
311
312


313
314
315

316
317
318

319
320
321
322
323
324
325
326






327

328
329
330
331




332
333


334

335

336
337
338
339

340
341
342


343
344
345
346
347




348


349
350
351
352

353

354
355

356
357

358
359
360
361

362
363
364
365
366
367
368
369
370

371
372
373
374
375

376
377
378

379
380
381
382
383
384
385


386
387
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411
412
413
414
415
416
417


418
419
420
421

422
423
424
425
426
427
428
429

430
431

432

433
434
435
436

437
438
439
440
441
442
443
444
445









446
447
448
449
450
451












452



453
454
455








456

457



458



459
460
461
462











463


464










465









466
467
468
469
470
471




472
473
474
475
476
477








478
479

480
481
482
483
484
485
486
487



488
489
490
491
492
493
494
495

496
497
498
499
500
501
502
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22

23
24
25
26
27
28
29
30
31
32



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80


81
82
83
84

85
86


87
88
89
90
91
92
93

94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118


















119
120
121


122
123
124
125
126
127
128


129
130





131

132

133
134
135
136
137

138
139
140

141
142
143
144
145
146
147

148
149
150
151

152
153
154
155
156
157
158





159
160




161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199







200
201
202
203
204
205
206
207




208
209



210

211
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226








227
228
229
230

231
232
233

234
235







236
237
238
239
240
241
242
243
244
245
246
247
248


249
250
251
252
253
254
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279



280


281

282
283



284
285





286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320


321
322
323
324
325


326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345


346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361


362

363


364










365
366
367


368



369

370
371
372
373
374


375
376
377
378
379
380
381
382




383
384
385
386
387

388
389
390
391

392


393

394
395


396
397





398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

413


414

415
416

417



418
419
420



421


422


423



424







425
426

427








428

429
430
431
432


433









434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453

454


455
456
457
458



459

460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476






477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492



493
494
495
496
497
498
499
500
501
502

503
504
505
506
507
508
509




510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534

535
536
537
538
539
540
541
542
543
544
545
546

547
548
549
550
551
552
553





554
555
556
557
558
559
560
561


562

563
564





565
566
567








568
569
570
571
572
573
574
575







+
+
+
+
-
+

+

-
+









-
-
-



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+

+
-
+

-
-
+
+





-
+






-
+


+














-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-



-
-
+
+





-
-
+

-
-
-
-
-

-

-





-
+


-




+
+
+
-
+

+
+
-
+
+





-
-
-
-
-


-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

+





+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
-
-
-
+
+
-
-
-
+
-

+
-
+













-
-
-
-
-
-
-
-
+



-
+


-
+

-
-
-
-
-
-
-
+
+








+


-
-
+
+
+

+


+





-
+
+
+
+








-
+





-
-
-

-
-

-
+

-
-
-
+
+
-
-
-
-
-

-




















+
+
+
+
+
+
+
+
+
+
+
+

+
-
-
+
+
+

+
-
-
+
+
+

+
+
+
+
+
+
+
+
+
+
+





-
-
+
+
+
+
+
+
+
+
+
+






-
-

-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
+
+

-
-
+
-
-
-
+
-





-
-
+
+
+
+
+
+

+
-
-
-
-
+
+
+
+

-
+
+

+
-
+
-
-

-
+

-
-
+
+
-
-
-
-
-
+
+
+
+

+
+




+

+

-
+
-
-
+
-


-
+
-
-
-



-
-
-
+
-
-

-
-
+
-
-
-
+
-
-
-
-
-
-
-
+
+
-

-
-
-
-
-
-
-
-
+
-




-
-
+
-
-
-
-
-
-
-
-
-






+
+




+







-
+
-
-
+

+

-
-
-
+
-








+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
-
-
-
+
+
+
+
+
+
+
+

+
-
+
+
+

+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

+
+

+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+



-


+
+
+
+

-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
-


-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+







;  Target OS: Win32
;
;  Dependencies:
;
;  Notes: Organize the main message/event loop needed by every GUI engine.
;_________________________________________________________________________________________





proc ProcessSystemEvents
body ProcessSystemEvents
.msg MSG
.msg2 MSG
begin
        push    ecx edx esi
        push    ecx edx esi edi

.msgloop:
        lea     esi, [.msg]
        xor     eax, eax

        invoke  PeekMessageW, esi, eax, eax, eax, PM_REMOVE
        test    eax, eax
        jz      .exitok

        cmp     [.msg.message], WM_TIMER
        je      .translate                      ; express dispatching of the timer messages.

        cmp     [.msg.message], WM_QUIT
        je      .terminate

        cmp     [.msg.message], WM_TIMER
        jne     .timer_ok

        xor     eax, eax
        stdcall __TimerProc, eax, eax, eax, eax
        jmp     .msgloop

.timer_ok:
        cmp     [.msg.message], WM_MOUSEMOVE
        jne     .move_ok

.loop:
        invoke  PeekMessageW, esi, [.msg.hwnd], WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE
        test    eax, eax
        jnz     .loop
        jmp     .processit


.move_ok:
        cmp     [.msg.message], WM_KEYDOWN
        jne     .processit

; cleaning the message queue from the keyboard autorepeat messages.

        lea     edi, [.msg2]

.loop2:
        invoke  PeekMessageW, edi, [.msg.hwnd], WM_KEYDOWN, WM_KEYDOWN, PM_NOREMOVE
        test    eax, eax
        jz      .processit

        mov     eax, [.msg2.wParam]
        mov     ecx, [.msg2.lParam]

        cmp     eax, [.msg.wParam]
        jne     .processit

        cmp     ecx, [.msg.lParam]
        jne     .processit

        invoke  PeekMessageW, edi, [.msg.hwnd], WM_KEYDOWN, WM_KEYDOWN, PM_REMOVE
        jmp     .loop2


.processit:
        stdcall __ProcessOneSystemEvent, [esi+MSG.hwnd], [esi+MSG.message], [esi+MSG.wParam], [esi+MSG.lParam]
        jnc     .msgloop                ; the message is translated to system event and the event is executed by the object SysEvent handler.
        stdcall __ProcessOneSystemEvent, [.msg.hwnd], [.msg.message], [.msg.wParam], [.msg.lParam]
        jnc     .msgloop

        invoke  DefWindowProcW, [.msg.hwnd], [.msg.message], [.msg.wParam], [.msg.lParam]
; the message is for window that is not an FreshLib object, so process with standard windows behaviour.

;        invoke  TranslateMessage, esi
.translate:
        invoke  DispatchMessageW, esi
;        invoke  DispatchMessageW, esi

        jmp     .msgloop


.exitok:
        clc
        pop     esi edx ecx
        pop     edi esi edx ecx
        return


.terminate:
        mov     eax, [.msg.wParam]
        stc
        pop     esi edx ecx
        pop     edi esi edx ecx
        return
endp




proc WaitForSystemEvent
begin
        push    eax ecx edx
        invoke  WaitMessage
        pop     edx ecx eax
        return
endp




;proc EventsQueued, .pWin
;.msg MSG
;begin
;        push    eax ecx edx
;        mov     eax, [.pWin]
;        mov     ecx, [eax+TWindow.handle]
;        lea     eax, [.msg]
;        invoke  PeekMessage, eax, ecx, 0, 0, PM_NOREMOVE
;        test    eax, eax
;        clc
;        jz      @f
;        stc
;@@:
;        pop     edx ecx eax
;        return
;endp
;

;----------------------------------------------------------------------------------------------------------
; This procedure makes following:
;   1. Takes as arguments one windows message
;   2. Converts this message to FreshLib system event (or not, depending on the message)
;   3. Calls SysEventHandler procedures for the given object (if any) with the created event structure.
;   2. Analizes the message and finds the target child window for it (only top level windows receive messages)
;   3. Calls the respective event handling method of the target window object.
;   4. returns CF=0 if the event was properly processed.
;   5. returns CF=1 if the event was not processed.
;
; The event can be not processed in the following cases:
;   1. The window that receives the message is not FreshLib object.
;   2. TObjectClass.procSysEventHandler = 0 for the given class and all parents.
;   3. All procSysEventHandler procedures refuse to process the event (CF=1)
;   2. The respective event handler refuse to process the event (return CF=1)
;----------------------------------------------------------------------------------------------------------
uglobal
  if used __LatestPointedObj
    __LatestPointedObj dd ?
  end if
endg


proc __ProcessOneSystemEvent, .hwnd, .wmsg, .wparam, .lparam
.event  rb 32
begin
        pushad

        stdcall _GetWindowStruct, [.hwnd]
        test    eax, eax
        jz      .not_processed
        jz      .ondefault

        mov     esi, eax
        lea     edi, [.event]

        dispatch [.wmsg]

.ondefault:
        popad
        stc
        return
        invoke  DefWindowProcW, [.hwnd], [.wmsg], [.wparam], [.lparam]


.ret_null:
        xor     eax, eax
.finish:

.processed:
        mov     [esp+4*regEAX], eax
        popad
        clc
        return

.not_processed:
        popad
        stc
        return

;.........................................................................................

.exec_event:
        exec    esi, TWindow:SysEventHandler, edi
        jc      .ondefault
        jmp     .finish

oncase WM_ACTIVATE
oncase WM_CANCELMODE

        cmp     [__ActiveMenu], 0
        je      .ondefault

.hideall:
        set     [__ActiveMenu], TWindow:Visible, FALSE
        cmp     [__ActiveMenu], 0
        jne     .hideall

        jmp     .ret_null

;.........................................................................................


oncase WM_MOUSEWHEEL
locals
 .point POINT
endl
        movsx   ecx, word [.lparam]
        movsx   edx, word [.lparam+2]
        mov     [.point.x], ecx
        mov     [.point.y], edx

        lea     eax, [.point]
        invoke  ScreenToClient, [.hwnd], eax

        mov     ecx, [.point.y]
        shl     ecx, 16
        mov     cx, word [.point.x]

        mov     [.lparam], ecx

        movsx   ecx, word [.lparam]
        movsx   edx, word [.lparam+2]
        call    .get_mouse_target

          mov   eax, [.wparam]
          sar   eax, 16
          mov   ecx, scWheelUp
          test  eax, eax
          jns   @f
          mov   ecx, scWheelDn
          neg   eax
        mov     eax, [.wparam]
        sar     eax, 16
        mov     ecx, scWheelUp
        test    eax, eax
        jns     @f
        mov     ecx, scWheelDn
        neg     eax
@@:
          mov   [edi+TScrollEvent.event], seScroll
          mov   [edi+TScrollEvent.ScrollBar], scrollY
          mov   [edi+TScrollEvent.ScrollCmd], ecx

        mov     ebx, 120
        cdq
          xor   edx, edx
          mov   ecx, 120
          idiv  ecx
        div     ebx
          mov   [edi+TScrollEvent.Value], eax

        exec    edi, TWindow:EventScroll, scrollY, ecx, eax
          jmp   .exec_event
        jmp     .ret_null

;.........................................................................................

oncase WM_WINDOWPOSCHANGED

locals
  .rect RECT
endl
        mov     ebx, [.lparam]

        test    [ebx+WINDOWPOS.flags], SWP_NOMOVE
        jnz     .move_ok

        mov     eax, [ebx+WINDOWPOS.x]
        mov     ecx, [ebx+WINDOWPOS.y]
        mov     [edi+TMoveEvent.newX], eax
        mov     [edi+TMoveEvent.newY], ecx

        mov     [edi+TMoveEvent.event], seMove

        exec    esi, TWindow:SysEventHandler, edi
        exec    esi, TWindow:EventMove, [ebx+WINDOWPOS.x], [ebx+WINDOWPOS.y]

.move_ok:
        test    [ebx+WINDOWPOS.flags], SWP_NOSIZE
        jnz     .not_processed
        jnz     .ret_null

        lea     eax, [.rect]
        invoke  GetClientRect, [.hwnd], eax
        invoke  GetClientRect, [esi+TWindow.handle], eax

        mov     eax, [.rect.right]
        mov     ecx, [.rect.bottom]
        mov     [edi+TResizeEvent.newWidth], eax
        mov     [edi+TResizeEvent.newHeight], ecx
        mov     [edi+TResizeEvent.event], seResize

        jmp     .exec_event
        exec    esi, TWindow:EventResize, [.rect.right], [.rect.bottom]
        jmp     .ret_null


;.........................................................................................

oncase WM_SYSKEYDOWN
oncase WM_SYSKEYUP
oncase WM_KEYDOWN
oncase WM_KEYUP

locals
  .keyboard rb 256
  .unicode rw 16
  .utf8    rb 16
  .unicode  rw 16
  .utf8buff rb 16
  .scancode dd ?
endl

        lea     ebx, [.keyboard]
        invoke  GetKeyboardState, ebx

        mov     eax, [.lparam]
        mov     ecx, eax
        shr     eax, 16
        and     ecx, $80000000
        and     eax, $ff
        mov     [edi+TKeyboardEvent.scancode], eax
        mov     [.scancode], eax

        mov     dword [.utf8buff], 0

        or      eax, ecx
        lea     edx, [.unicode]
        invoke  ToUnicode, [.wparam], eax, ebx, edx, 16, 0
        xor     ecx, ecx
        test    eax, eax
        jz      .key_translated    ; the key can not be translated.
        js      .key_translated    ; it is a dead key. What we have to do???

        lea     edx, [.utf8]
        lea     edx, [.utf8buff]
        xor     ecx, ecx
        mov     [edx], ecx
        mov     [edx+4], ecx
        lea     ecx, [.unicode]
        invoke  WideCharToMultiByte, CP_UTF8, 0, ecx, eax, edx, 8, 0, 0
        xor     ecx, ecx
        test    eax, eax
        jz      .key_translated

        mov     ecx, dword [.utf8]

.key_translated:
        mov     [edi+TKeyboardEvent.key], ecx
        xor     eax, eax

        mov     ecx, seKbdKeyPress
        cmp     [.wmsg], WM_KEYDOWN
        je      @f
        cmp     [__FocusedWindow], eax
        jz      .ondefault
        cmp     [.wmsg], WM_SYSKEYDOWN
        je      @f
        mov     ecx, seKbdKeyRelease
@@:
        mov     [edi+TKeyboardEvent.event], ecx

        xor     eax, eax
        test    [.keyboard+VK_CONTROL], $80
        jz      @f
        or      eax, maskCtrl
@@:
        test    [.keyboard+VK_SHIFT], $80
        jz      @f
        or      eax, maskShift
@@:
        test    [.keyboard+VK_MENU], $80
        jz      @f
        or      eax, maskAlt
@@:
        test    [.keyboard+VK_SCROLL], $01
        jz      @f
        or      eax, maskScrLk
@@:
        test    [.keyboard+VK_CAPITAL], $01
        jz      @f
        or      eax, maskCapsLock
@@:
        test    [.keyboard+VK_LBUTTON], $80
        jz      @f
        or      eax, maskBtnLeft
@@:
        test    [.keyboard+VK_RBUTTON], $80
        jz      @f
        or      eax, maskBtnRight
@@:
        test    [.keyboard+VK_MBUTTON], $80
        jz      @f
        or      eax, maskBtnMiddle
@@:

        cmp     [.wmsg], WM_KEYUP
;        or      eax, [__MouseButtonMask]
;        OutputRegister regEAX, 16
        je      .key_up
        cmp     [.wmsg], WM_SYSKEYUP
        je      .key_up

;.key_down:
        mov     [edi+TKeyboardEvent.kbdStatus], eax
        jmp     .exec_event

        exec    [__FocusedWindow], TWindow:EventKeyPress, dword [.utf8buff], [.scancode], eax
        jmp     .end_key_msg

.key_up:
        exec    [__FocusedWindow], TWindow:EventKeyRelease, [.scancode], eax

.end_key_msg:
        cmp     [.wmsg], WM_SYSKEYDOWN
        je      .ondefault

        cmp     [.wmsg], WM_SYSKEYUP
        je      .ondefault

        jmp     .ret_null

;.........................................................................................


oncase WM_SETFOCUS
        mov     [edi+TFocusInEvent.event], seFocusIn
        jmp     .exec_event

        stdcall __SearchWindowToFocus, esi

        mov     [__FocusedWindow], eax

        test    eax, eax
        jz      .ret_null

        exec    eax, TWindow:EventFocusIn
        jmp     .ret_null


;.........................................................................................


oncase WM_KILLFOCUS
        mov     [edi+TFocusOutEvent.event], seFocusOut
        jmp     .exec_event


        xor     ebx, ebx
;.........................................................................................

        xchg    [__FocusedWindow], ebx

oncase WM_SETCURSOR

        movzx   eax, word [.lparam]
        cmp     eax, HTCLIENT
        jne     .ondefault

        mov     eax, [esi+TWindow._cursor]
        test    eax, $ffffff00
        jnz     .customcursor
        test    ebx, ebx
        jz      .ret_null

        stdcall GetStockCursor, eax

        exec    ebx, TWindow:EventFocusOut
.customcursor:
        stdcall SetMouseCursor, eax
        jmp     .finish
        jmp     .ret_null


;.........................................................................................


oncase WM_MOUSEMOVE
        cmp     esi, [__LatestPointedObj]
        je      .normal_mouse_move

        movsx   ecx, word [.lparam]
        movsx   edx, word [.lparam+2]

        stdcall ServeMenuMouseMove, [.hwnd], ecx, edx, 0
        jc      .ret_null

        call    .get_mouse_target
        mov     [edi+TMouseEnterEvent.event], seMouseLeave
        xchg    esi, [__LatestPointedObj]
        test    esi, esi
        jz      .leaveok

        get     eax, edi, TWindow:Enabled
        test    eax, eax
        jz      .ret_null

        exec    esi, TWindow:SysEventHandler, edi
        cmp     edi, [__LastPointedWindow]
        je      .move_event

        cmp     [__LastPointedWindow], 0
.leaveok:
        je      .leave_ok
        mov     esi, [__LatestPointedObj]
        mov     [edi+TMouseEnterEvent.event], seMouseEnter

        exec    esi, TWindow:SysEventHandler, edi
        exec    [__LastPointedWindow], TWindow:EventMouseLeave

.normal_mouse_move:
        mov     [edi+TMouseMoveEvent.event], seMouseMove
.leave_ok:

        movsx   eax, word [.lparam]
        movsx   ecx, word [.lparam+2]
        mov     [edi+TMouseMoveEvent.x], eax
        mov     [edi+TMouseMoveEvent.y], ecx
        jmp     .exec_event
        mov     [__LastPointedWindow], edi
        exec    edi, TWindow:EventMouseEnter

.move_event:

        exec    edi, TWindow:EventMouseMove, ecx, edx, 0
        jmp     .ret_null


;.........................................................................................


oncase WM_PAINT

locals
  .ps PAINTSTRUCT
  .ps     PAINTSTRUCT
  .context TContext
  .caret   dd ?
  .hdc    dd ?
  .rect2    RECT
endl

        lea     eax, [.rect2]
        get     edi, esi, TWindow:ImgScreen
        invoke  GetUpdateRect, [.hwnd], eax, FALSE
        test    eax, eax
        jz      .endpaint

        lea     eax, [.ps]
        invoke  BeginPaint, [.hwnd], eax

if defined Caret
        mov     [.caret], -1
        mov     [.hdc], eax
        cmp     esi, [Caret.pWindow]
        jne     @f

        stdcall CaretShow, FALSE
        mov     [.caret], eax
        mov     ecx, [.ps.rcPaint.right]
@@:
end if

        mov     edx, [.ps.rcPaint.bottom]
        mov     [edi+TPaintEvent.event], sePaint
        push    [.ps.hdc]
        pop     [.context.handle]
        push    [.hwnd]
        pop     [.context.raster]

        lea     eax, [.context]
        sub     ecx, [.ps.rcPaint.left]
        sub     edx, [.ps.rcPaint.top]
        mov     [edi+TPaintEvent.context], eax

; ?????????????????????????????
;        push    [.ps.rcPaint.left] [.ps.rcPaint.top]
        push     [.rect2.left] [.rect2.top]
        pop     [edi+TPaintEvent.rect.top] [edi+TPaintEvent.rect.left]
;        push    [.ps.rcPaint.right] [.ps.rcPaint.bottom]
         push    [.rect2.right] [.rect2.bottom]
        pop     [edi+TPaintEvent.rect.bottom] [edi+TPaintEvent.rect.right]

        stdcall DrawImageRect, [.hdc], edi, [.ps.rcPaint.left], [.ps.rcPaint.top], [.ps.rcPaint.left], [.ps.rcPaint.top], ecx, edx
        exec    esi, TWindow:SysEventHandler, edi

        lea     eax, [.ps]
        invoke  EndPaint, [.hwnd], eax

if defined Caret
        cmp     [.caret], -1
        jmp     .ret_null
        je      @f
        stdcall CaretShow, [.caret]
@@:
end if

.endpaint:
        pop     edi esi edx ecx ebx eax
        clc
        return


;.........................................................................................


oncase WM_CLOSE

        DebugMsg "Close request."

        get     eax, [pApplication], TApplication:MainWindow
        test    eax, eax
        jz      @f

        cmp     [eax], esi
        jne     @f

DebugMsg "Quit message posted."
        invoke  PostQuitMessage, 0

@@:
        mov     [edi+TCloseEvent.event], seCloseRequest
        exec    esi, TWindow:CloseRequest, cerFromUser
        mov     [edi+TCloseEvent.reason], cerFromUser
        jmp     .exec_event
        jmp     .ret_null


oncase WM_DESTROY
        cmp     esi, [__LatestPointedObj]
        jne     .ondefault

        mov     [esi+TWindow.handle], 0
        mov     [__LatestPointedObj], 0
        jmp     .ondefault

;.........................................................................................


oncase WM_LBUTTONUP
oncase WM_RBUTTONUP
oncase WM_MBUTTONUP
        movsx   ecx, word [.lparam]
        movsx   edx, word [.lparam+2]
        call    .get_mouse_target

        get     eax, edi, TWindow:Enabled
        test    eax, eax
        jz      .ret_null

        mov     ebx, [.wmsg]
oncase WM_LBUTTONDOWN
oncase WM_RBUTTONDOWN
oncase WM_MBUTTONDOWN
oncase WM_LBUTTONDBLCLK
oncase WM_RBUTTONDBLCLK
oncase WM_MBUTTONDBLCLK
        sub     ebx, WM_LBUTTONDOWN
        movzx   ebx, byte [.__mouse_button_table+ebx]

        stdcall __KeyStatus, [.wparam]

        exec    edi, TWindow:EventButtonRelease, ebx, eax, ecx, edx
        jmp     .ret_null


oncase WM_LBUTTONDOWN
oncase WM_RBUTTONDOWN
oncase WM_MBUTTONDOWN

locals
  .kbdState dd ?
endl
        stdcall __MouseButton, [.wmsg]
        mov     [edi+TMouseButtonEvent.event], ecx
        mov     [edi+TMouseButtonEvent.Button], eax

        movsx   ecx, word [.lparam]
        movsx   edx, word [.lparam+2]

        mov     ebx, [.wmsg]
        sub     ebx, WM_LBUTTONDOWN
        movzx   ebx, byte [.__mouse_button_table+ebx]

        stdcall __KeyStatus, [.wparam]
        mov     [.kbdState], eax
        mov     [edi+TMouseButtonEvent.kbdStatus], eax

        stdcall ServeMenuButtonPress, [.hwnd], ebx, eax, ecx, edx
        jc      .ret_null

        call    .get_mouse_target

        get     eax, edi, TWindow:Enabled
        movsx   eax, word [.lparam]
        movsx   ecx, word [.lparam+2]
        mov     [edi+TMouseButtonEvent.x], eax
        mov     [edi+TMouseButtonEvent.y], ecx
        test    eax, eax
        jz      .ret_null

; deal with focus

        cmp     edi, [__FocusedWindow]
        je      .focusok

        get     eax, edi, TWindow:WantFocus
        test    eax, eax
        jz      .focusok

        mov     eax, [__FocusedWindow]
        mov     [__FocusedWindow], edi


        test    eax, eax
        jz      @f
        exec    eax, TWindow:EventFocusOut
@@:

        exec    edi, TWindow:EventFocusIn

.focusok:
        exec    edi, TWindow:EventButtonPress, ebx, [.kbdState], ecx, edx
        jmp     .exec_event
        jmp     .ret_null


; Double clicks are not supported for now...

;oncase WM_LBUTTONDBLCLK
;oncase WM_RBUTTONDBLCLK
;oncase WM_MBUTTONDBLCLK



        enddispatch
endp


.get_mouse_target:
        mov     edi, [__MouseTarget]
        test    edi, edi
        jz      .search_target_move

proc __MouseButton, .msg
begin
        mov     eax, [.msg]
        sub     eax, WM_LBUTTONDOWN
        movzx   ecx, byte [__mouse_event_table+eax]
        stdcall __GetRelativeXY, edi, ecx, edx
        jmp     .target_move

.search_target_move:
        exec    esi, TWindow:ChildByXY, ecx, edx, FALSE
        mov     edi, eax

.target_move:
        movzx   eax, byte [__mouse_button_table+eax]
        return
        retn
endp


iglobal
  if used __mouse_button_table
  __mouse_button_table db mbLeft,        mbLeft,       mbLeft
                       db mbRight,       mbRight,      mbRight
                       db mbMiddle,      mbMiddle,     mbMiddle
  .__mouse_button_table db mbLeft,        mbLeft,       mbLeft
                        db mbRight,       mbRight,      mbRight
                        db mbMiddle,      mbMiddle,     mbMiddle
  end if

  if used __mouse_event_table
  __mouse_event_table  db seMouseBtnPress, seMouseBtnRelease, seMouseBtnDblClick
                       db seMouseBtnPress, seMouseBtnRelease, seMouseBtnDblClick
                       db seMouseBtnPress, seMouseBtnRelease, seMouseBtnDblClick
  end if
endg
endp


;.........................................................................................



proc __KeyStatus, .status
512
513
514
515
516
517
518
519

520
521
522
523
524
525
526

585
586
587
588
589
590
591

592
593
594
595
596
597
598
599
600







-
+







+
@@:
        test    [.status], MK_MBUTTON
        jz      @f
        or      eax, maskBtnMiddle
@@:
        test    [.status], MK_SHIFT
        jz      @f
        or      eax, maskCtrl
        or      eax, maskShift
@@:
        test    [.status], MK_CONTROL
        jz      @f
        or      eax, maskCtrl
@@:
        return
endp

Changes to freshlib/gui/Win32/TApplication.asm.
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
16
17
18
19
20
21
22

23
24

25
26

27

28
29
30
31
32







-
+

-


-

-





uglobal
  if used hInstance
    hInstance dd ?
  end if
endg


method TApplication.Create
method TApplication.__create
begin
        push    eax ecx edx
        invoke  GetModuleHandleW, 0
        mov     [hInstance], eax

        clc
        pop     edx ecx eax
        return
endp



Changes to freshlib/gui/Win32/mouse.asm.
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31


32


33
34
35
36
37
38
39
40

41
42
43
44
45

46
47
48
49
50

51
52
53
54
55
56
57
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42

43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61







-
+













+
+
-
+
+







-
+




-
+





+







;
;  Notes:
;_________________________________________________________________________________________

; ToDo: Arbitrary mouse cursors, B&W for the begining.


proc SetMouseCursor, .hCursor
proc SetMouseCursor, .hWindow, .hCursor
begin
        push    ecx edx
        invoke  SetCursor, [.hCursor]
        pop     edx ecx
        return
endp



proc GetStockCursor, .index
begin
        push    ecx edx
        mov     eax, [.index]
        cmp     eax, mcCount
        jb      @f
        and     eax, 7
        xor     eax, eax
@@:
        movzx   eax, [_cursors+2*eax]
        invoke  LoadCursorW, 0, eax
        pop     edx ecx
        return
endp

if used _cursors
  _cursors dw IDC_ARROW, IDC_IBEAM, IDC_CROSS, IDC_SIZEWE, IDC_SIZENS, IDC_SIZENWSE, IDC_SIZENESW, IDC_WAIT
  _cursors dw IDC_ARROW, IDC_IBEAM, IDC_CROSS, IDC_SIZEWE, IDC_SIZENS, IDC_SIZENWSE, IDC_SIZENESW, IDC_WAIT, IDC_HAND, IDC_HAND, IDC_ARROW
end if



proc MouseCapture, .hwnd
proc __MouseCapture, .hwnd
begin
        push    eax ecx edx
        cmp     [.hwnd], 0
        je      .release

        DebugMsg "Mouse captured!"
        invoke  SetCapture, [.hwnd]

.finish:
        pop     edx ecx eax
        return

.release:
Changes to freshlib/gui/Win32/windows.asm.
23
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64










65









66
67
68
69























































70











71


72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

100
101
102
103

104
105

106
107
108


109
110
111
112

113
114
115
116
117
118



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134



135



136
137
138
139
140













141
142
143
144
145
146
147
148
149


150
151

152
153
154
155
156

157
158
159
160
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189


190
191
192
193

194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209




210
211

212
213
214
215
216

217
218

219
220
221
222
223

224
225
226

227
228
229

230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

250
251
252
253
254

255
256
257
258
259

260
261

262
263

264
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287


288
289

290
291
292
293
294
295

296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
351
352
353

354
355
356
357




358
359
360
361
362
363
364
365
366
367
368


369
370
371
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437

438




439
440
441
442
443
444
445
446
447
448
449
450
451

452
453
454
455
456
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40

41
42
43
44



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81




82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
166
167
168








169


170


171

172
173

174
175


176
177




178






179
180
181
182




183





184
185
186
187
188
189
190
191
192
193
194
195





196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215


216
217
218

219
220




221







222




223











224




225





226
227
228



229




230



231



232




233
234
235
236


237





238


239





240



241



242












243



244



245





246





247


248


249







250

251









252





253
254


255
256





257
258
259
260




















261
262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325

326



327






























328




329








330
331
332
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

359
360
361
362
363
364







-
+










-
+



-
-
-
















+
-
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+

+
+





-
+











-
-
-
-
-
-
-
-

-
-
+
-
-

-
+

-
+

-
-
+
+
-
-
-
-
+
-
-
-
-
-
-
+
+
+

-
-
-
-

-
-
-
-
-





+
+
+

+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+







-
-
+
+

-
+

-
-
-
-
+
-
-
-
-
-
-
-

-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-

-
-
-
-
-
+
+

-
-
-
+
-
-
-
-

-
-
-
+
-
-
-

-
-
-
-
+
+
+
+
-
-
+
-
-
-
-
-
+
-
-
+
-
-
-
-
-
+
-
-
-
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-

-
-
-
+
-
-
-
-
-
+
-
-
-
-
-
+
-
-
+
-
-
+
-
-
-
-
-
-
-

-
+
-
-
-
-
-
-
-
-
-

-
-
-
-
-
+
+
-
-
+

-
-
-
-
-
+



-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







-
+













-
+












-
+




+
+
+
+











+
+









-
+
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-

-
-
-
-
-
-
-
-

+









-
+

+
+
+
+












-
+






;_________________________________________________________________________________________
;
; Registers common window class
; Call only once
;_________________________________________________________________________________________

if used _CreateNullWindow
if used _CreateWindow
initialize __RegisterWindowClass

.wc WNDCLASS

begin
        xor     eax, eax
        lea     edi, [.wc]
        mov     ecx, sizeof.WNDCLASS / 4
        rep stosd

        mov     [.wc.style], CS_OWNDC or CS_DBLCLKS or CS_VREDRAW or CS_HREDRAW
        mov     [.wc.style], CS_PARENTDC; or CS_DBLCLKS ;or CS_VREDRAW or CS_HREDRAW
        mov     [.wc.lpfnWndProc], __CommonWindowProc
        mov     [.wc.cbWndExtra], nWindowExtraBytes

;        invoke  CreateSolidBrush, $0000ff
;        mov     [.wc.hbrBackground], eax

        mov     eax,[hInstance]
        mov     [.wc.hInstance],eax
        mov     [.wc.lpszClassName], cWindowClassName

        lea     eax, [.wc]
        invoke  RegisterClassW, eax

        return
endp
end if



;_________________________________________________________________________________________



proc _CreateNullWindow
body _CreateWindow

.pwc     dd ?
.charlen dd ?

.style dd ?
.exstyle dd ?

.rect RECT

begin
        pushad
        mov     esi, [.pWindow]

        mov     [.pwc], 0

        cmp     [esi+TWindow._caption], 0
        je      .caption_ok

        stdcall StrLen, [esi+TWindow._caption]
        push    ecx edx
        xor     ecx, ecx
        invoke  CreateWindowExW, ecx, cWindowClassName, ecx, WS_CLIPSIBLINGS or WS_CLIPCHILDREN, ecx, ecx, ecx, ecx, ecx, ecx, ecx, ecx
        pop     edx ecx
        lea     ecx, [eax*4]

        stdcall GetMem, ecx
        mov     [.pwc], eax

        stdcall StrPtr, [esi+TWindow._caption]

        invoke  MultiByteToWideChar, CP_UTF8, 0, eax, -1, [.pwc], ecx
        mov     [.charlen], eax

.caption_ok:

; now styles
        mov     eax, [esi+TWindow._border]
        and     eax, $3

        mov     ecx, [.styles+4*eax]
        mov     edx, [.exstyles+4*eax]

        mov     [.style], ecx
        mov     [.exstyle], edx

; the coordinates and size

        xor     eax, eax
        mov     [.rect.left], eax
        mov     [.rect.top],  eax
        mov     ecx, [esi+TWindow._width]
        mov     edx, [esi+TWindow._height]
        mov     [.rect.right], ecx
        mov     [.rect.bottom], edx

        lea     eax, [.rect]
        invoke  AdjustWindowRectEx, eax, [.style], 0, [.exstyle]

        mov     ecx, [.rect.right]
        mov     edx, [.rect.bottom]
        sub     ecx, [.rect.left]
        sub     edx, [.rect.top]

; the owner
        mov     eax, [esi+TWindow.__main]
        test    eax, eax
        jz      .owner_ok

        mov     eax, [eax+TWindow.handle]
.owner_ok:
        invoke  CreateWindowExW, [.exstyle], cWindowClassName, [.pwc], [.style], [esi+TWindow._x], [esi+TWindow._y], ecx, edx, eax, 0, [hInstance], 0
        mov     [esp+4*regEAX], eax

        invoke  SetWindowLongW, eax, ofsWindowStruct, esi

        stdcall FreeMem, [.pwc]

        popad
        return


.styles dd WS_POPUP
        dd WS_BORDER  or WS_CAPTION or WS_SYSMENU or WS_SIZEBOX or WS_MINIMIZEBOX or WS_MAXIMIZEBOX
        dd WS_CAPTION or WS_SYSMENU
        dd WS_BORDER  or WS_CAPTION or WS_SYSMENU or WS_SIZEBOX

.exstyles dd WS_EX_TOPMOST or WS_EX_TOOLWINDOW or WS_EX_NOACTIVATE
          dd WS_EX_APPWINDOW
          dd WS_EX_DLGMODALFRAME
          dd WS_EX_TOOLWINDOW
endp



;_________________________________________________________________________________________



proc _DestroyWindow, .hwnd
body _DestroyWindow
begin
        push    eax ecx edx
        invoke  DestroyWindow, [.hwnd]
        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _GetParent, .hwnd
begin
        push    ecx edx
;        invoke  GetParent, [.hwnd]
        invoke  GetWindowLongW, [.hwnd], GWL_HWNDPARENT
        pop     edx ecx
        return
endp

;_________________________________________________________________________________________

body _ClientToScreen

proc _GetChildren, .hwnd
begin
        push    ebx ecx edx
        push    eax

        xor     ebx, ebx
        lea     eax, [.x]

        invoke  GetWindow, [.hwnd], GW_CHILD
        mov     ecx, eax
        invoke  ClientToScreen, [.hwnd], eax
        mov     ecx, [.x]
        jecxz   .endchildren

        stdcall CreateArray, sizeof.TWinArrayItem
        mov     ebx, eax
        mov     edx, [.y]

.loophwnd:
        stdcall AddArrayItems, ebx, 1
        mov     ebx, edx

        mov     [eax+TWinArrayItem.handle], ecx
        pop     eax
        return
endp

        invoke  GetWindow, ecx, GW_HWNDNEXT
        mov     ecx, eax
        jecxz   .endchildren
        jmp     .loophwnd

.endchildren:
        mov     eax, ebx
        pop     edx ecx ebx
        return
endp


;_________________________________________________________________________________________


body _ShowWindow
begin
        pushad

        mov     ebx, SW_HIDE
        cmp     [.flag], 0
        je      .com_ok
proc _GetVisible, .hwnd
begin
        push    ecx edx
        invoke  IsWindowVisible, [.hwnd]
        pop     edx ecx

        mov     ebx, SW_SHOWNOACTIVATE

        invoke  GetWindowLongW, [.hwnd], GWL_STYLE
        test    eax, WS_POPUP
        jnz     .com_ok

        mov     ebx, SW_SHOWNORMAL

.com_ok:
        invoke  ShowWindow, [.hwnd], ebx

        popad
        return
endp


;_________________________________________________________________________________________



proc _GetWindowBounds, .hwnd, .pBounds
body _RefreshWindowRect
;.rect RECT
begin
        push    eax ecx edx
        push    eax ecx edx ebx

        invoke  GetClientRect, [.hwnd], [.pBounds]
        invoke  GetParent, [.hwnd]
        invoke  MapWindowPoints, [.hwnd], eax, [.pBounds], 2

; WAY 1 - direct paint on the window surface, without sending any messages.
        mov     edx, [.pBounds]
        mov     eax, [edx+TBounds.width]
        mov     ecx, [edx+TBounds.height]
        sub     eax, [edx+TBounds.x]
        sub     ecx, [edx+TBounds.y]
        mov     [edx+TBounds.width], eax
        mov     [edx+TBounds.height], ecx

        pop     edx ecx eax
        return
endp

        invoke  GetDC, [.hwnd]


;_________________________________________________________________________________________


proc _SetWindowBounds, .hwnd, .pBounds
.rect RECT
begin
        push    eax ecx edx

        mov     eax, [.pBounds]
        mov     ebx, eax
        push    [eax+TBounds.width] [eax+TBounds.height]
        pop     [.rect.bottom] [.rect.right]
        mov     [.rect.left], 0
        mov     [.rect.top], 0

        invoke  GetWindowLongW, [.hwnd], GWL_EXSTYLE
        push    eax
        push    FALSE
        invoke  GetWindowLongW, [.hwnd], GWL_STYLE
        push    eax
        stdcall _GetWindowStruct, [.hwnd]
        get     eax, eax, TWindow:ImgScreen

        lea     eax, [.rect]
        invoke  AdjustWindowRectEx, eax ; and from the stack

        stdcall DrawImageRect, ebx, eax, [.x], [.y], [.x], [.y], [.width], [.height]
        mov     eax, [.rect.right]
        mov     ecx, [.rect.bottom]
        sub     eax, [.rect.left]
        sub     ecx, [.rect.top]

        mov     edx, [.pBounds]
        invoke  SetWindowPos, [.hwnd], 0, [edx+TBounds.x], [edx+TBounds.y], eax, ecx, SWP_NOZORDER; or SWP_NOREDRAW

        invoke  ReleaseDC, [.hwnd], ebx
        pop     edx ecx eax
        return
endp





;; Needed for WAY2 and WAY3
;
;        mov     eax, [.x]
;        mov     ecx, [.y]
;_________________________________________________________________________________________

;        mov     [.rect.left], eax
wsNoneWindowBorder = WS_POPUP
wsFullWindowBorder = WS_BORDER or WS_CAPTION or WS_SYSMENU or WS_SIZEBOX or WS_MINIMIZEBOX or WS_MAXIMIZEBOX
wsModalWindowBorder  = WS_CAPTION or WS_SYSMENU
wsToolboxWindowBorder = WS_BORDER or WS_CAPTION or WS_SYSMENU or WS_SIZEBOX

;        mov     [.rect.top], ecx
wsAllWindowBorder = wsNoneWindowBorder or wsFullWindowBorder or wsModalWindowBorder or wsToolboxWindowBorder

;        add     eax, [.width]
proc _SetWindowBorder, .hwnd, .brdType
.bounds TBounds
begin
        push    eax ebx ecx edx esi

;        add     ecx, [.height]
        invoke  GetWindowLongW, [.hwnd], GWL_STYLE
        mov     ebx, eax

;        mov     [.rect.right], eax
        mov     esi, [.brdType]
        and     esi, 3

;        mov     [.rect.bottom], ecx
        mov     ecx, [.styles+4*esi]
        mov     edx, [.exstyles+4*esi]

        and     ebx, not wsAllWindowBorder
        test    ebx, WS_CHILD
        jz      @f
        and     ecx, not (WS_CAPTION or WS_SYSMENU or WS_SIZEBOX)
        and     edx, not (WS_EX_APPWINDOW or WS_EX_DLGMODALFRAME or WS_EX_TOOLWINDOW)
@@:
        or      ebx, ecx
        invoke  SetWindowLongW, [.hwnd], GWL_EXSTYLE, edx
        invoke  SetWindowLongW, [.hwnd], GWL_STYLE, ebx

        lea     esi, [.bounds]
        stdcall _GetWindowBounds, [.hwnd], esi
        stdcall _SetWindowBounds, [.hwnd], esi

        pop     esi edx ecx ebx eax
        return

;; WAY2 - generates messages before returning.
.styles dd wsNoneWindowBorder
        dd wsFullWindowBorder
        dd wsModalWindowBorder
        dd wsToolboxWindowBorder

;
.exstyles dd 0
          dd WS_EX_APPWINDOW
          dd WS_EX_DLGMODALFRAME
          dd WS_EX_TOOLWINDOW

;        lea     eax, [.rect]
endp

;        xor     ecx, ecx
;_________________________________________________________________________________________

;        invoke  RedrawWindow, [.hwnd], eax, ecx, RDW_UPDATENOW or RDW_INVALIDATE or RDW_NOERASE
proc _ShowWindow, .hwnd, .flag
begin
        push    eax ecx edx
        invoke  ShowWindow, [.hwnd], [.flag]
        pop     edx ecx eax
        return
endp


;; WAY3 - returns immediately and posts messages to the queue
;_________________________________________________________________________________________


proc _RefreshWindow, .hwnd
begin
        push    eax ecx edx
        xor     eax, eax
        invoke  InvalidateRect, [.hwnd], eax, eax
;        invoke  RedrawWindow, [.hwnd], eax, eax, RDW_INVALIDATE or RDW_UPDATENOW or RDW_ERASENOW

        pop     edx ecx eax
        return
endp


;        lea     eax, [.rect]
;        xor     ecx, ecx
;_________________________________________________________________________________________

;        invoke  InvalidateRect, [.hwnd], eax, ecx

proc _SetFocus, .hwnd
begin
        push    eax ecx edx
        invoke  SetFocus, [.hwnd]
        pop     edx ecx eax
        pop     ebx edx ecx eax
        return
endp

;_________________________________________________________________________________________

proc _AddChild, .hwnd, .child
begin
        push    eax ecx edx

        invoke  GetWindowLongW, [.child], GWL_STYLE
        or      eax, WS_CHILD
        and     eax, not (WS_DLGFRAME or WS_BORDER)
        invoke  SetWindowLongW, [.child], GWL_STYLE, eax
        invoke  SetParent, [.child], [.hwnd]

        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________


; Common utility procedures.


;_________________________________________________________________________________________
;
; Returns the window TObject structure, from the window handle.
;_________________________________________________________________________________________

proc _GetWindowStruct, .hwin
body _GetWindowStruct
begin
        push    ecx edx
        invoke  GetWindowLongW, [.hwin], ofsWindowStruct
        pop     edx ecx
        return
endp



;_________________________________________________________________________________________



proc _SetWindowStruct, .hwin, .value
body _SetWindowStruct
begin
        push    eax ecx edx
        invoke  SetWindowLongW, [.hwin], ofsWindowStruct, [.value]
        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________



proc _SetWindowTextUtf8, .hwnd, .ptrUtf8
body _SetWindowTextUtf8
.pwc dd ?
.charlen dd ?
begin
        push    eax ecx edx

        cmp     [.ptrUtf8], 0
        je      .finish

        stdcall StrLen, [.ptrUtf8]
        lea     ecx, [eax*4]

        stdcall GetMem, ecx
        mov     [.pwc], eax

        invoke  MultiByteToWideChar, CP_UTF8, 0, [.ptrUtf8], -1, [.pwc], ecx
        mov     [.charlen], eax

        invoke  SendMessageW, [.hwnd], WM_SETTEXT, 0, [.pwc]
        stdcall FreeMem, [.pwc]

.finish:
        pop     edx ecx eax
        return
endp



;_________________________________________________________________________________________



body _SetModalTowards
proc _GetWindowTextUtf8, .hwnd, .ptrUtf8
.pwc dd ?
.charlen dd ?
begin
        push    ebx ecx edx edi
        stdcall StrNew
        mov     ebx, eax

        invoke  SendMessage, [.hwnd], WM_GETTEXTLENGTH, 0, 0
        mov     [.charlen], eax
        lea     ecx, [eax*4]

        stdcall StrSetCapacity, ebx, ecx
        mov     edi, eax

        stdcall GetMem, ecx
        mov     [.pwc], eax

        invoke  SendMessage, [.hwnd], WM_GETTEXT, [.charlen], [.pwc]
        invoke  WideCharToMultiByte, CP_UTF8, 0, [.pwc], -1, edi, [edi+string.capacity], 0, 0
        stdcall FreeMem, [.pwc]
        stdcall StrFixLen, ebx
        mov     eax, ebx
        pop     edi edx ecx ebx
        return
endp



;_________________________________________________________________________________________


proc _EnableWindow, .hwnd, .flag
begin
        push    eax ecx edx
        invoke  EnableWindow, [.hwnd], [.flag]
        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _SetModalTowards, .hwnd, .hwndParent
begin
        push    eax ecx edx
        stdcall _SetWindowBorder, [.hwnd], borderModal
        invoke  SetWindowLongW, [.hwnd], GWL_HWNDPARENT, [.hwndParent]
        invoke  EnableWindow, [.hwndParent], FALSE

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _FinalizeModal, .hwnd, .hwndParent
body _FinalizeModal
begin
        push    eax ecx edx
        invoke  EnableWindow, [.hwndParent], TRUE
        invoke  SetFocus, [.hwndParent]
        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc __CommonWindowProc, .hwnd, .wmsg, .wparam, .lparam
begin
        stdcall __ProcessOneSystemEvent, [.hwnd], [.wmsg], [.wparam], [.lparam]         ; sometimes windows calls winproc directly instead of using postmessage.
        jnc     .finish

;        invoke  DefWindowProcW, [.hwnd], [.wmsg], [.wparam], [.lparam]
        invoke  DefWindowProcW, [.hwnd], [.wmsg], [.wparam], [.lparam]

.finish:
        return
endp

Changes to freshlib/gui/all.asm.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39




40

41
42

43
44
45
46
47

48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64









19
20
21
22
23
24
25



26
27
28
29
30
31
32
33



34
35
36
37
38
39
40
41
42
43
44
45


46
47

48
49
50
51
52


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70







-
-
-








-
-
-
+
+
+
+

+


+



-
-
+

-
+




-
-









+
+
+
+
+
+
+
+
+

include 'sysevents.asm'

include 'mouse.asm'
include 'textcaret.asm'

; OS independent support code
include 'realobjects.inc'

;include 'TAction.asm'

; Limited support for the old visual editor. Contains only macro definitions.
;include 'OldTemplates.inc'

; OS independent components

include 'TObject.asm'
include 'TApplication.asm'
include 'TWindow.asm'
include 'TBackWindow.asm'
include 'TScrollWindow.asm'
include 'TAction.asm'
include 'TActionList.asm'

include 'TWindow.asm'

include 'TScrollbar.asm'
include 'TForm.asm'
include 'TButton.asm'
include 'TCheckbox.asm'
include 'TEdit.asm'
include 'TLabel.asm'
include 'TImageLabel.asm'
;include 'TMenuItem.asm'
;include 'TMenu.asm'
include 'TMenu.asm'
include 'TProgressbar.asm'
;include 'TTreeView.asm'
include 'TTreeView.asm'
;include 'TGrid.asm'


include 'dialogs.asm'

include 'ThemeGUI.asm'
include 'SplitGrid.asm'


; OS independent main procedures.
include 'Main.asm'

; OS independent template engine.
include 'ObjTemplates.asm'

; Way to change the GUI themes in Runtime.
include 'themes.asm'

match theme, ThemeGUI {
  include 'themes/'#`theme#'.asm'
}

;include 'themes/flat_gui.asm'
;include 'themes/win_gui.asm'
Changes to freshlib/gui/dialogs.asm.
11
12
13
14
15
16
17
18
19
20
21




22
23
24
25
26
27
28



29
30
31
32
33
34
35
36
37
38









39
40
41
42
43
44
45
11
12
13
14
15
16
17




18
19
20
21

22
23
24



25
26
27
28









29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44







-
-
-
-
+
+
+
+
-



-
-
-
+
+
+

-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+







;
;  Notes:
;_________________________________________________________________________________________
module "Common dialogs library"


iglobal
   getfile _DlgIconError,       '%lib%/gui/images/error.gif'
   getfile _DlgIconInformation, '%lib%/gui/images/information.gif'
   getfile _DlgIconQuestion,    '%lib%/gui/images/question.gif'
   getfile _DlgIconWarning,     '%lib%/gui/images/warning.gif'
   getfile _DlgIconError,       '%lib%/gui/images/error.png'
   getfile _DlgIconInformation, '%lib%/gui/images/information.png'
   getfile _DlgIconQuestion,    '%lib%/gui/images/question.png'
   getfile _DlgIconWarning,     '%lib%/gui/images/warning.png'
   getfile _DlgMaskDialogIcons, '%lib%/gui/images/icon_mask.gif'

   if used _CommonDialogTemplate
    _CommonDialogTemplate:
        ObjTemplate  tfParent or tfEnd, TForm, frmCommonDialog,  x, 200, y, 100, width, 480, height, 100
           ObjTemplate tfChild, TImageLabel, .imgIcon, x, 4, y, 4, width, 50, height, 50, Visible, TRUE, ImageAlign, iaCenter or iaMiddle
           ObjTemplate tfChild, TLabel,  .LblText,   x,58, y, 4, width, 10, height, 10, TextAlign, dtfAlignLeft or dtfAlignMiddle or dtfWordWrap or dtfCRLF, Visible, TRUE
        ObjTemplate  tfParent or tfEnd, TForm, frmCommonDialog,  x = 200, y = 100, width = 480, height = 100, border = borderModal
           ObjTemplate tfChild, TImageLabel, .imgIcon, x = 4, y = 4, width = 70, height = 70, Visible = TRUE, ImageAlign = iaCenter or iaMiddle
           ObjTemplate tfChild, TLabel,  .LblText,   x = 74, y = 4, width = 10, height = 10, TextAlign = dtfAlignLeft or dtfAlignMiddle or dtfWordWrap or dtfCRLF, Visible = TRUE

           ObjTemplate tfChild, TButton, .btnOK,     x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'OK',     ModalResult, mrOK
           ObjTemplate tfChild, TButton, .btnCancel, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Cancel', ModalResult, mrCancel
           ObjTemplate tfChild, TButton, .btnAbort,  x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Abort',  ModalResult, mrAbort
           ObjTemplate tfChild, TButton, .btnRetry,  x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Retry',  ModalResult, mrRetry
           ObjTemplate tfChild, TButton, .btnIgnore, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Ignore', ModalResult, mrIgnore
           ObjTemplate tfChild, TButton, .btnYes,    x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Yes',    ModalResult, mrYes
           ObjTemplate tfChild, TButton, .btnNo,     x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'No',     ModalResult, mrNo
           ObjTemplate tfChild, TButton, .btnMaybe,  x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Maybe',  ModalResult, mrMaybe
           ObjTemplate tfEnd,   TButton, .btnHelp,   x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Help',   ModalResult, mrNone
           ObjTemplate tfChild, TButton, .btnOK,     x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter  or dtfAlignMiddle, Caption = 'OK',     ModalResult = mrOK
           ObjTemplate tfChild, TButton, .btnCancel, x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter  or dtfAlignMiddle, Caption = 'Cancel', ModalResult = mrCancel
           ObjTemplate tfChild, TButton, .btnAbort,  x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter  or dtfAlignMiddle, Caption = 'Abort',  ModalResult = mrAbort
           ObjTemplate tfChild, TButton, .btnRetry,  x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter  or dtfAlignMiddle, Caption = 'Retry',  ModalResult = mrRetry
           ObjTemplate tfChild, TButton, .btnIgnore, x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter  or dtfAlignMiddle, Caption = 'Ignore', ModalResult = mrIgnore
           ObjTemplate tfChild, TButton, .btnYes,    x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter  or dtfAlignMiddle, Caption = 'Yes',    ModalResult = mrYes
           ObjTemplate tfChild, TButton, .btnNo,     x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter  or dtfAlignMiddle, Caption = 'No',     ModalResult = mrNo
           ObjTemplate tfChild, TButton, .btnMaybe,  x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter  or dtfAlignMiddle, Caption = 'Maybe',  ModalResult = mrMaybe
           ObjTemplate tfEnd,   TButton, .btnHelp,   x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter  or dtfAlignMiddle, Caption = 'Help',   ModalResult = mrNone
   end if
endg


; buttons flags used:
smbOK     = $01
smbCancel = $02
59
60
61
62
63
64
65
66
67
68
69


70
71
72
73
74
75
76
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73
74
75
76







-



+
+










proc ShowMessage, .parent, .icon, .hTitle, .hMessage, .maskButtons
.xrow dd ?
.yrow dd ?
.hicon dd ?
.hmask dd ?
begin
        push    ebx ecx edx esi
        stdcall CreateFromTemplate, _CommonDialogTemplate, 0

        set     [frmCommonDialog], TWindow:_MainWindow, [.parent]

; First set the position and size of the dialog box, depending on the flags, and the size of the message.

; Set the message text:
        set     [frmCommonDialog.LblText], TLabel:Caption, [.hMessage]

; Set the message title:
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
95
96
97
98
99
100
101

102
103
104
105
106
107
108







-








        get     eax, ebx, TForm:width
        cmp     eax, edx
        jge     .widthok

        lea     eax, [edx+32]
        set     ebx, TForm:width, eax
        exec    ebx, TWindow:UpdateBounds

.widthok:

        sub     eax, edx
        sar     eax, 1  ; eax is the begin X coordinate of the row
        mov     [.xrow], eax

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161


162

163

164


165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139


140
141
142
143
144





145
146
147
148
149
150
151

152
153
154
155

156
157
158

159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190







-
















-
-
+
+



-
-
-
-
-







-


+
+
-
+

+
-
+
+






-
















+







        test    [.maskButtons], ecx
        jz      @f

        mov     esi, [edx]

        set     [esi], TButton:x, [.xrow]
        set     [esi], TButton:y, [.yrow]
        exec    [esi], TWindow:UpdateBounds

        set     [esi], TButton:Visible, TRUE
        add     [.xrow], 64+16

@@:
        add     edx, 4
        shl     ecx, 1
        cmp     ecx, smbMaxButton
        jbe     .btnLoop

; set the icon
        mov     eax, [.icon]
        cmp     eax, .iconCount
        jb      @f
        xor     eax, eax
@@:
        stdcall CreateImageGIF, [.iconTable+4*eax], [.iconSizes+4*eax]
        OutputRegister regEAX, 16
        stdcall CreateImagePNG, [.iconTable+4*eax], [.iconSizes+4*eax]

        mov     [.hicon], eax
        set     [frmCommonDialog.imgIcon], TImageLabel:Image, eax

        stdcall CreateImageGIF, _DlgMaskDialogIcons, _DlgMaskDialogIcons.size
        OutputRegister regEAX, 16
        mov     [.hmask], eax
        set     [frmCommonDialog.imgIcon], TImageLabel:Mask, eax

; set the text position and size.
        mov     ecx, [.yrow]
        sub     ecx, 8

        set     [frmCommonDialog.LblText], TLabel:height, ecx

        set     [frmCommonDialog.imgIcon], TImageLabel:height, ecx
        exec    [frmCommonDialog.imgIcon], TWindow:UpdateBounds

        get     eax, [frmCommonDialog], TForm:width
        get     ecx, [frmCommonDialog.LblText], TLabel:x

        sub     eax, 66
        sub     eax, ecx
        set     [frmCommonDialog.LblText], TLabel:width, eax

        exec    [frmCommonDialog.LblText], TWindow:UpdateBounds
;        exec    [frmCommonDialog.LblText], TWindow:Refresh
;        exec    [frmCommonDialog.imgIcon], TWindow:Refresh

        stdcall ShowModal, ebx, [.parent]

        destroy ebx

        stdcall DestroyImage, [.hicon]
        stdcall DestroyImage, [.hmask]

        pop     esi edx ecx ebx
        return

.btnTable dd frmCommonDialog.btnOK,     \
             frmCommonDialog.btnCancel, \
             frmCommonDialog.btnAbort,  \
             frmCommonDialog.btnRetry,  \
             frmCommonDialog.btnIgnore, \
             frmCommonDialog.btnYes,    \
             frmCommonDialog.btnNo,     \
             frmCommonDialog.btnMaybe,  \
             frmCommonDialog.btnHelp

.iconTable dd _DlgIconError, _DlgIconInformation, _DlgIconQuestion, _DlgIconWarning
.iconCount = ($ - .iconTable)/4

.iconSizes dd _DlgIconError.size, _DlgIconInformation.size, _DlgIconQuestion.size, _DlgIconWarning.size

endp


proc InputString, .parent
begin
Added freshlib/gui/images/_theme_circle/error.png.

cannot compute difference between binary files

Added freshlib/gui/images/_theme_circle/information.png.

cannot compute difference between binary files

Added freshlib/gui/images/_theme_circle/question.png.

cannot compute difference between binary files

Added freshlib/gui/images/_theme_circle/warning.png.

cannot compute difference between binary files

Changes to freshlib/gui/images/_theme_rhomb/Icons.odg.

cannot compute difference between binary files

Added freshlib/gui/images/checkbox/check.png.

cannot compute difference between binary files

Added freshlib/gui/images/checkbox/check.svg.



















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="13"
   height="13"
   viewBox="0 0 13 13"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="check.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/checkbox/check.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata43"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
     id="defs41" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview39"
     showgrid="false"
     inkscape:zoom="43.153846"
     inkscape:cx="2.6648841"
     inkscape:cy="6.5"
     inkscape:current-layer="Capa_1" /><g
     id="g3"
     transform="matrix(0.22441969,0,0,0.22441969,1.4999414,1.5000527)"
     style="fill:#0000ff;fill-opacity:1"><g
       id="g5"
       style="fill:#0000ff;fill-opacity:1"><path
         d="m 23.297,38.74 c -1.17,1.588 -2.992,2.564 -4.962,2.661 -1.97,0.098 -3.878,-0.696 -5.198,-2.162 L 1.308,26.112 c -1.88,-2.085 -1.713,-5.299 0.372,-7.179 2.087,-1.88 5.299,-1.712 7.179,0.374 l 8.369,9.288 c 0.124,0.138 0.304,0.212 0.489,0.203 0.186,-0.009 0.356,-0.102 0.467,-0.25 L 35.386,5.217 c 1.665,-2.26 4.847,-2.741 7.108,-1.075 2.259,1.666 2.739,4.848 1.073,7.107 L 23.297,38.74 Z"
         id="path7"
         inkscape:connector-curvature="0"
         style="fill:#0000ff;fill-opacity:1" /></g></g><g
     id="g9"
     transform="translate(0,-31.560001)" /><g
     id="g11"
     transform="translate(0,-31.560001)" /><g
     id="g13"
     transform="translate(0,-31.560001)" /><g
     id="g15"
     transform="translate(0,-31.560001)" /><g
     id="g17"
     transform="translate(0,-31.560001)" /><g
     id="g19"
     transform="translate(0,-31.560001)" /><g
     id="g21"
     transform="translate(0,-31.560001)" /><g
     id="g23"
     transform="translate(0,-31.560001)" /><g
     id="g25"
     transform="translate(0,-31.560001)" /><g
     id="g27"
     transform="translate(0,-31.560001)" /><g
     id="g29"
     transform="translate(0,-31.560001)" /><g
     id="g31"
     transform="translate(0,-31.560001)" /><g
     id="g33"
     transform="translate(0,-31.560001)" /><g
     id="g35"
     transform="translate(0,-31.560001)" /><g
     id="g37"
     transform="translate(0,-31.560001)" /></svg>
Added freshlib/gui/images/checkbox/check_flat.png.

cannot compute difference between binary files

Added freshlib/gui/images/checkbox/check_flat.svg.
















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="13"
   height="13"
   viewBox="0 0 13 13"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="check_flat.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/checkbox/check_flat.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata43"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
     id="defs41" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview39"
     showgrid="false"
     inkscape:zoom="43.153846"
     inkscape:cx="6.5"
     inkscape:cy="6.5"
     inkscape:current-layer="Capa_1" /><g
     id="g9"
     transform="translate(0,-31.560001)" /><g
     id="g11"
     transform="translate(0,-31.560001)" /><g
     id="g13"
     transform="translate(0,-31.560001)" /><g
     id="g15"
     transform="translate(0,-31.560001)" /><g
     id="g17"
     transform="translate(0,-31.560001)" /><g
     id="g19"
     transform="translate(0,-31.560001)" /><g
     id="g21"
     transform="translate(0,-31.560001)" /><g
     id="g23"
     transform="translate(0,-31.560001)" /><g
     id="g25"
     transform="translate(0,-31.560001)" /><g
     id="g27"
     transform="translate(0,-31.560001)" /><g
     id="g29"
     transform="translate(0,-31.560001)" /><g
     id="g31"
     transform="translate(0,-31.560001)" /><g
     id="g33"
     transform="translate(0,-31.560001)" /><g
     id="g35"
     transform="translate(0,-31.560001)" /><g
     id="g37"
     transform="translate(0,-31.560001)" /><rect
     style="fill:#e74c3c;fill-opacity:1;stroke:none;stroke-width:1.02100003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
     id="rect4169"
     width="5"
     height="5"
     x="4"
     y="4" /></svg>
Added freshlib/gui/images/checkbox/check_flat_gray.png.

cannot compute difference between binary files

Added freshlib/gui/images/checkbox/check_flat_gray.svg.
















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="13"
   height="13"
   viewBox="0 0 13 13"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="check_flat_gray.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/checkbox/check_flat_gray.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata43"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
     id="defs41" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview39"
     showgrid="false"
     inkscape:zoom="96.432248"
     inkscape:cx="4.7837691"
     inkscape:cy="6.4536542"
     inkscape:current-layer="Capa_1" /><g
     id="g9"
     transform="translate(0,-31.560001)" /><g
     id="g11"
     transform="translate(0,-31.560001)" /><g
     id="g13"
     transform="translate(0,-31.560001)" /><g
     id="g15"
     transform="translate(0,-31.560001)" /><g
     id="g17"
     transform="translate(0,-31.560001)" /><g
     id="g19"
     transform="translate(0,-31.560001)" /><g
     id="g21"
     transform="translate(0,-31.560001)" /><g
     id="g23"
     transform="translate(0,-31.560001)" /><g
     id="g25"
     transform="translate(0,-31.560001)" /><g
     id="g27"
     transform="translate(0,-31.560001)" /><g
     id="g29"
     transform="translate(0,-31.560001)" /><g
     id="g31"
     transform="translate(0,-31.560001)" /><g
     id="g33"
     transform="translate(0,-31.560001)" /><g
     id="g35"
     transform="translate(0,-31.560001)" /><g
     id="g37"
     transform="translate(0,-31.560001)" /><rect
     style="fill:#6f6f6f;fill-opacity:1;stroke:none;stroke-width:1.02100003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
     id="rect4169"
     width="5"
     height="5"
     x="4"
     y="4" /></svg>
Added freshlib/gui/images/checkbox/check_gray.png.

cannot compute difference between binary files

Added freshlib/gui/images/checkbox/check_gray.svg.



















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="13"
   height="13"
   viewBox="0 0 13 13"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="check_gray.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/checkbox/check_gray.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata43"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
     id="defs41" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview39"
     showgrid="false"
     inkscape:zoom="43.153846"
     inkscape:cx="2.6648841"
     inkscape:cy="6.5"
     inkscape:current-layer="Capa_1" /><g
     id="g3"
     transform="matrix(0.22441969,0,0,0.22441969,1.4999414,1.5000527)"
     style="fill:#404040;fill-opacity:1"><g
       id="g5"
       style="fill:#404040;fill-opacity:1"><path
         d="m 23.297,38.74 c -1.17,1.588 -2.992,2.564 -4.962,2.661 -1.97,0.098 -3.878,-0.696 -5.198,-2.162 L 1.308,26.112 c -1.88,-2.085 -1.713,-5.299 0.372,-7.179 2.087,-1.88 5.299,-1.712 7.179,0.374 l 8.369,9.288 c 0.124,0.138 0.304,0.212 0.489,0.203 0.186,-0.009 0.356,-0.102 0.467,-0.25 L 35.386,5.217 c 1.665,-2.26 4.847,-2.741 7.108,-1.075 2.259,1.666 2.739,4.848 1.073,7.107 L 23.297,38.74 Z"
         id="path7"
         inkscape:connector-curvature="0"
         style="fill:#404040;fill-opacity:1" /></g></g><g
     id="g9"
     transform="translate(0,-31.560001)" /><g
     id="g11"
     transform="translate(0,-31.560001)" /><g
     id="g13"
     transform="translate(0,-31.560001)" /><g
     id="g15"
     transform="translate(0,-31.560001)" /><g
     id="g17"
     transform="translate(0,-31.560001)" /><g
     id="g19"
     transform="translate(0,-31.560001)" /><g
     id="g21"
     transform="translate(0,-31.560001)" /><g
     id="g23"
     transform="translate(0,-31.560001)" /><g
     id="g25"
     transform="translate(0,-31.560001)" /><g
     id="g27"
     transform="translate(0,-31.560001)" /><g
     id="g29"
     transform="translate(0,-31.560001)" /><g
     id="g31"
     transform="translate(0,-31.560001)" /><g
     id="g33"
     transform="translate(0,-31.560001)" /><g
     id="g35"
     transform="translate(0,-31.560001)" /><g
     id="g37"
     transform="translate(0,-31.560001)" /></svg>
Deleted freshlib/gui/images/error.gif.

cannot compute difference between binary files

Added freshlib/gui/images/error.png.

cannot compute difference between binary files

Deleted freshlib/gui/images/icon_mask.gif.

cannot compute difference between binary files

Deleted freshlib/gui/images/information.gif.

cannot compute difference between binary files

Added freshlib/gui/images/information.png.

cannot compute difference between binary files

Added freshlib/gui/images/menu/check.png.

cannot compute difference between binary files

Added freshlib/gui/images/menu/check.svg.




















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="8"
   height="16"
   viewBox="0 0 8 16"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="check.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/menu/check.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata43"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
     id="defs41" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview39"
     showgrid="false"
     inkscape:zoom="35.0625"
     inkscape:cx="-0.7201426"
     inkscape:cy="8"
     inkscape:current-layer="Capa_1"
     inkscape:snap-page="true" /><g
     id="g3"
     transform="matrix(0.17953575,0,0,0.1795327,-4.6834361e-5,4.0001102)"
     style="fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:4.55629396;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"><g
       id="g5"
       style="fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:4.55629396;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"><path
         d="m 23.297,38.74 c -1.17,1.588 -2.992,2.564 -4.962,2.661 -1.97,0.098 -3.878,-0.696 -5.198,-2.162 L 1.308,26.112 c -1.88,-2.085 -1.713,-5.299 0.372,-7.179 2.087,-1.88 5.299,-1.712 7.179,0.374 l 8.369,9.288 c 0.124,0.138 0.304,0.212 0.489,0.203 0.186,-0.009 0.356,-0.102 0.467,-0.25 L 35.386,5.217 c 1.665,-2.26 4.847,-2.741 7.108,-1.075 2.259,1.666 2.739,4.848 1.073,7.107 L 23.297,38.74 Z"
         id="path7"
         inkscape:connector-curvature="0"
         style="fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:4.55629396;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /></g></g><g
     id="g9"
     transform="translate(0,-28.560001)" /><g
     id="g11"
     transform="translate(0,-28.560001)" /><g
     id="g13"
     transform="translate(0,-28.560001)" /><g
     id="g15"
     transform="translate(0,-28.560001)" /><g
     id="g17"
     transform="translate(0,-28.560001)" /><g
     id="g19"
     transform="translate(0,-28.560001)" /><g
     id="g21"
     transform="translate(0,-28.560001)" /><g
     id="g23"
     transform="translate(0,-28.560001)" /><g
     id="g25"
     transform="translate(0,-28.560001)" /><g
     id="g27"
     transform="translate(0,-28.560001)" /><g
     id="g29"
     transform="translate(0,-28.560001)" /><g
     id="g31"
     transform="translate(0,-28.560001)" /><g
     id="g33"
     transform="translate(0,-28.560001)" /><g
     id="g35"
     transform="translate(0,-28.560001)" /><g
     id="g37"
     transform="translate(0,-28.560001)" /></svg>
Added freshlib/gui/images/menu/check_flat.png.

cannot compute difference between binary files

Added freshlib/gui/images/menu/check_flat.svg.






















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="7"
   height="16"
   viewBox="0 0 7 16"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="check_flat.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/menu/check_flat.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata43"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
     id="defs41" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview39"
     showgrid="false"
     inkscape:zoom="33.519231"
     inkscape:cx="-0.93746414"
     inkscape:cy="8"
     inkscape:current-layer="Capa_1"
     inkscape:snap-page="true" /><g
     id="g3"
     transform="matrix(0.17953575,0,0,0.1795327,-4.6834361e-5,4.0001102)"
     style="fill:#e67e22;fill-opacity:1;stroke:none;stroke-width:4.55629396;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"><g
       id="g5"
       style="fill:#e67e22;fill-opacity:1;stroke:none;stroke-width:4.55629396;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /></g><g
     id="g9"
     transform="translate(0,-28.560001)" /><g
     id="g11"
     transform="translate(0,-28.560001)" /><g
     id="g13"
     transform="translate(0,-28.560001)" /><g
     id="g15"
     transform="translate(0,-28.560001)" /><g
     id="g17"
     transform="translate(0,-28.560001)" /><g
     id="g19"
     transform="translate(0,-28.560001)" /><g
     id="g21"
     transform="translate(0,-28.560001)" /><g
     id="g23"
     transform="translate(0,-28.560001)" /><g
     id="g25"
     transform="translate(0,-28.560001)" /><g
     id="g27"
     transform="translate(0,-28.560001)" /><g
     id="g29"
     transform="translate(0,-28.560001)" /><g
     id="g31"
     transform="translate(0,-28.560001)" /><g
     id="g33"
     transform="translate(0,-28.560001)" /><g
     id="g35"
     transform="translate(0,-28.560001)" /><g
     id="g37"
     transform="translate(0,-28.560001)" /><rect
     style="fill:#e74c3c;fill-opacity:1;stroke:none;stroke-width:1.02100003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
     id="rect4169"
     width="7"
     height="7"
     x="0"
     y="4.5" /></svg>
Added freshlib/gui/images/menu/check_flat_gray.png.

cannot compute difference between binary files

Added freshlib/gui/images/menu/check_flat_gray.svg.






















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="7"
   height="16"
   viewBox="0 0 7 16"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="check_flat_gray.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/menu/check_flat_gray.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata43"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
     id="defs41" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview39"
     showgrid="false"
     inkscape:zoom="33.519231"
     inkscape:cx="-0.93746414"
     inkscape:cy="8"
     inkscape:current-layer="Capa_1"
     inkscape:snap-page="true" /><g
     id="g3"
     transform="matrix(0.17953575,0,0,0.1795327,-4.6834361e-5,4.0001102)"
     style="fill:#e67e22;fill-opacity:1;stroke:none;stroke-width:4.55629396;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"><g
       id="g5"
       style="fill:#e67e22;fill-opacity:1;stroke:none;stroke-width:4.55629396;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /></g><g
     id="g9"
     transform="translate(0,-28.560001)" /><g
     id="g11"
     transform="translate(0,-28.560001)" /><g
     id="g13"
     transform="translate(0,-28.560001)" /><g
     id="g15"
     transform="translate(0,-28.560001)" /><g
     id="g17"
     transform="translate(0,-28.560001)" /><g
     id="g19"
     transform="translate(0,-28.560001)" /><g
     id="g21"
     transform="translate(0,-28.560001)" /><g
     id="g23"
     transform="translate(0,-28.560001)" /><g
     id="g25"
     transform="translate(0,-28.560001)" /><g
     id="g27"
     transform="translate(0,-28.560001)" /><g
     id="g29"
     transform="translate(0,-28.560001)" /><g
     id="g31"
     transform="translate(0,-28.560001)" /><g
     id="g33"
     transform="translate(0,-28.560001)" /><g
     id="g35"
     transform="translate(0,-28.560001)" /><g
     id="g37"
     transform="translate(0,-28.560001)" /><rect
     style="fill:#6e6e6e;fill-opacity:1;stroke:none;stroke-width:1.02100003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
     id="rect4169"
     width="7"
     height="7"
     x="0"
     y="4.5" /></svg>
Added freshlib/gui/images/menu/check_gray.png.

cannot compute difference between binary files

Added freshlib/gui/images/menu/check_gray.svg.




















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="8"
   height="16"
   viewBox="0 0 8 16"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="check_gray.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/menu/check_gray.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata43"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
     id="defs41" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview39"
     showgrid="false"
     inkscape:zoom="35.0625"
     inkscape:cx="-0.7201426"
     inkscape:cy="8"
     inkscape:current-layer="Capa_1"
     inkscape:snap-page="true" /><g
     id="g3"
     transform="matrix(0.17953575,0,0,0.1795327,-4.6834361e-5,4.0001102)"
     style="fill:#3f3f3f;fill-opacity:1;stroke:none;stroke-width:4.55629396;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"><g
       id="g5"
       style="fill:#3f3f3f;fill-opacity:1;stroke:none;stroke-width:4.55629396;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"><path
         d="m 23.297,38.74 c -1.17,1.588 -2.992,2.564 -4.962,2.661 -1.97,0.098 -3.878,-0.696 -5.198,-2.162 L 1.308,26.112 c -1.88,-2.085 -1.713,-5.299 0.372,-7.179 2.087,-1.88 5.299,-1.712 7.179,0.374 l 8.369,9.288 c 0.124,0.138 0.304,0.212 0.489,0.203 0.186,-0.009 0.356,-0.102 0.467,-0.25 L 35.386,5.217 c 1.665,-2.26 4.847,-2.741 7.108,-1.075 2.259,1.666 2.739,4.848 1.073,7.107 L 23.297,38.74 Z"
         id="path7"
         inkscape:connector-curvature="0"
         style="fill:#3f3f3f;fill-opacity:1;stroke:none;stroke-width:4.55629396;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /></g></g><g
     id="g9"
     transform="translate(0,-28.560001)" /><g
     id="g11"
     transform="translate(0,-28.560001)" /><g
     id="g13"
     transform="translate(0,-28.560001)" /><g
     id="g15"
     transform="translate(0,-28.560001)" /><g
     id="g17"
     transform="translate(0,-28.560001)" /><g
     id="g19"
     transform="translate(0,-28.560001)" /><g
     id="g21"
     transform="translate(0,-28.560001)" /><g
     id="g23"
     transform="translate(0,-28.560001)" /><g
     id="g25"
     transform="translate(0,-28.560001)" /><g
     id="g27"
     transform="translate(0,-28.560001)" /><g
     id="g29"
     transform="translate(0,-28.560001)" /><g
     id="g31"
     transform="translate(0,-28.560001)" /><g
     id="g33"
     transform="translate(0,-28.560001)" /><g
     id="g35"
     transform="translate(0,-28.560001)" /><g
     id="g37"
     transform="translate(0,-28.560001)" /></svg>
Added freshlib/gui/images/menu/submenu.png.

cannot compute difference between binary files

Added freshlib/gui/images/menu/submenu.svg.

























































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="6"
   height="11"
   viewBox="0 0 5.9999999 11"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="submenu.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/menu/submenu.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata42"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
     id="defs40" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="1920"
     inkscape:window-height="1061"
     id="namedview38"
     showgrid="false"
     inkscape:zoom="51"
     inkscape:cx="-0.24509804"
     inkscape:cy="5.5"
     inkscape:window-x="-4"
     inkscape:window-y="-4"
     inkscape:window-maximized="1"
     inkscape:current-layer="Capa_1"
     fit-margin-top="0"
     fit-margin-left="0"
     fit-margin-right="0"
     fit-margin-bottom="0" /><g
     id="g3"
     transform="matrix(0.02139037,0,0,0.03081232,-0.81818182,1.9073486e-6)"
     style="fill:#000000;fill-opacity:1"><g
       id="play-arrow"
       style="fill:#000000;fill-opacity:1"><polygon
         points="38.25,0 38.25,357 318.75,178.5 "
         id="polygon6"
         style="fill:#000000;fill-opacity:1" /></g></g><g
     id="g8"
     transform="translate(-7.9999995,-339)" /><g
     id="g10"
     transform="translate(-7.9999995,-339)" /><g
     id="g12"
     transform="translate(-7.9999995,-339)" /><g
     id="g14"
     transform="translate(-7.9999995,-339)" /><g
     id="g16"
     transform="translate(-7.9999995,-339)" /><g
     id="g18"
     transform="translate(-7.9999995,-339)" /><g
     id="g20"
     transform="translate(-7.9999995,-339)" /><g
     id="g22"
     transform="translate(-7.9999995,-339)" /><g
     id="g24"
     transform="translate(-7.9999995,-339)" /><g
     id="g26"
     transform="translate(-7.9999995,-339)" /><g
     id="g28"
     transform="translate(-7.9999995,-339)" /><g
     id="g30"
     transform="translate(-7.9999995,-339)" /><g
     id="g32"
     transform="translate(-7.9999995,-339)" /><g
     id="g34"
     transform="translate(-7.9999995,-339)" /><g
     id="g36"
     transform="translate(-7.9999995,-339)" /></svg>
Added freshlib/gui/images/menu/submenugray.png.

cannot compute difference between binary files

Added freshlib/gui/images/menu/submenugray.svg.

























































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="6"
   height="11"
   viewBox="0 0 5.9999999 11"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="submenugray.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/menu/submenugray.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata42"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
     id="defs40" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="1920"
     inkscape:window-height="1061"
     id="namedview38"
     showgrid="false"
     inkscape:zoom="51"
     inkscape:cx="3"
     inkscape:cy="5.5"
     inkscape:window-x="-4"
     inkscape:window-y="-4"
     inkscape:window-maximized="1"
     inkscape:current-layer="Capa_1"
     fit-margin-top="0"
     fit-margin-left="0"
     fit-margin-right="0"
     fit-margin-bottom="0" /><g
     id="g3"
     transform="matrix(0.02139037,0,0,0.03081232,-0.81818182,1.9073486e-6)"
     style="fill:#95a5a6;fill-opacity:1"><g
       id="play-arrow"
       style="fill:#95a5a6;fill-opacity:1"><polygon
         points="318.75,178.5 38.25,0 38.25,357 "
         id="polygon6"
         style="fill:#95a5a6;fill-opacity:1" /></g></g><g
     id="g8"
     transform="translate(-7.9999994,-339)" /><g
     id="g10"
     transform="translate(-7.9999994,-339)" /><g
     id="g12"
     transform="translate(-7.9999994,-339)" /><g
     id="g14"
     transform="translate(-7.9999994,-339)" /><g
     id="g16"
     transform="translate(-7.9999994,-339)" /><g
     id="g18"
     transform="translate(-7.9999994,-339)" /><g
     id="g20"
     transform="translate(-7.9999994,-339)" /><g
     id="g22"
     transform="translate(-7.9999994,-339)" /><g
     id="g24"
     transform="translate(-7.9999994,-339)" /><g
     id="g26"
     transform="translate(-7.9999994,-339)" /><g
     id="g28"
     transform="translate(-7.9999994,-339)" /><g
     id="g30"
     transform="translate(-7.9999994,-339)" /><g
     id="g32"
     transform="translate(-7.9999994,-339)" /><g
     id="g34"
     transform="translate(-7.9999994,-339)" /><g
     id="g36"
     transform="translate(-7.9999994,-339)" /></svg>
Added freshlib/gui/images/menu/submenusel.png.

cannot compute difference between binary files

Added freshlib/gui/images/menu/submenusel.svg.

























































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="6"
   height="10.999998"
   viewBox="0 0 5.9999999 10.999998"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="submenusel.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/menu/submenusel.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata42"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
     id="defs40" /><sodipodi:namedview
     pagecolor="#0000ff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="1920"
     inkscape:window-height="1061"
     id="namedview38"
     showgrid="false"
     inkscape:zoom="51.000009"
     inkscape:cx="3"
     inkscape:cy="5.499999"
     inkscape:window-x="-4"
     inkscape:window-y="-4"
     inkscape:window-maximized="1"
     inkscape:current-layer="Capa_1"
     fit-margin-top="0"
     fit-margin-left="0"
     fit-margin-right="0"
     fit-margin-bottom="0" /><g
     id="g3"
     transform="matrix(0.02139037,0,0,0.03081232,-0.81818182,-1.4734863e-7)"
     style="fill:#ffffff;fill-opacity:1"><g
       id="play-arrow"
       style="fill:#ffffff;fill-opacity:1"><polygon
         points="38.25,0 38.25,357 318.75,178.5 "
         id="polygon6"
         style="fill:#ffffff;fill-opacity:1" /></g></g><g
     id="g8"
     transform="translate(-7.9999995,-339)" /><g
     id="g10"
     transform="translate(-7.9999995,-339)" /><g
     id="g12"
     transform="translate(-7.9999995,-339)" /><g
     id="g14"
     transform="translate(-7.9999995,-339)" /><g
     id="g16"
     transform="translate(-7.9999995,-339)" /><g
     id="g18"
     transform="translate(-7.9999995,-339)" /><g
     id="g20"
     transform="translate(-7.9999995,-339)" /><g
     id="g22"
     transform="translate(-7.9999995,-339)" /><g
     id="g24"
     transform="translate(-7.9999995,-339)" /><g
     id="g26"
     transform="translate(-7.9999995,-339)" /><g
     id="g28"
     transform="translate(-7.9999995,-339)" /><g
     id="g30"
     transform="translate(-7.9999995,-339)" /><g
     id="g32"
     transform="translate(-7.9999995,-339)" /><g
     id="g34"
     transform="translate(-7.9999995,-339)" /><g
     id="g36"
     transform="translate(-7.9999995,-339)" /></svg>
Deleted freshlib/gui/images/question.gif.

cannot compute difference between binary files

Added freshlib/gui/images/question.png.

cannot compute difference between binary files

Added freshlib/gui/images/svg/error.svg.



































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   viewBox="0 0 310.285 310.285"
   style="enable-background:new 0 0 310.285 310.285;"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="error.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/svg/error.png"
   inkscape:export-xdpi="13.92"
   inkscape:export-ydpi="13.92"><metadata
     id="metadata39"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
     id="defs37" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview35"
     showgrid="false"
     inkscape:zoom="1.6820764"
     inkscape:cx="60.913725"
     inkscape:cy="152.51297"
     inkscape:current-layer="Capa_1" /><rect
     style="fill:#ffffff;fill-opacity:1"
     id="rect4167"
     width="183.70152"
     height="198.56412"
     x="67.773376"
     y="57.62109" /><path
     d="M264.845,45.441C235.542,16.139,196.582,0,155.143,0S74.743,16.139,45.44,45.441C16.138,74.743,0,113.703,0,155.143  c0,41.439,16.138,80.399,45.44,109.701c29.303,29.303,68.262,45.44,109.702,45.44s80.399-16.138,109.702-45.44  c29.302-29.302,45.44-68.262,45.44-109.701C310.285,113.703,294.147,74.743,264.845,45.441z M189.702,157.985l38.669,38.669  c3.12,3.119,3.12,8.194,0,11.313l-22.333,22.333c-1.507,1.507-3.516,2.337-5.657,2.337c-2.141,0-4.15-0.83-5.657-2.337  l-38.669-38.669c-0.748-0.746-2.08-0.746-2.829,0l-38.669,38.669c-1.507,1.507-3.516,2.337-5.657,2.337  c-2.141,0-4.149-0.83-5.657-2.336l-22.333-22.334c-1.507-1.507-2.337-3.516-2.337-5.656c0-2.142,0.83-4.15,2.337-5.657  l38.669-38.669c0.766-0.767,0.766-2.063-0.001-2.829l-40.302-40.302c-1.507-1.507-2.337-3.516-2.337-5.657  c0-2.141,0.83-4.149,2.337-5.656l22.333-22.333c1.507-1.507,3.516-2.337,5.657-2.337c2.141,0,4.149,0.83,5.656,2.337l40.303,40.303  c0.749,0.747,2.081,0.746,2.828,0l40.303-40.303c1.507-1.507,3.516-2.337,5.657-2.337c2.141,0,4.149,0.83,5.656,2.337l22.333,22.333  c1.507,1.507,2.337,3.516,2.337,5.656c0,2.142-0.83,4.15-2.337,5.658l-40.302,40.301  C188.936,155.923,188.936,157.219,189.702,157.985z"
     id="path3"
     style="fill:#e74c3c;fill-opacity:1" /><g
     id="g5" /><g
     id="g7" /><g
     id="g9" /><g
     id="g11" /><g
     id="g13" /><g
     id="g15" /><g
     id="g17" /><g
     id="g19" /><g
     id="g21" /><g
     id="g23" /><g
     id="g25" /><g
     id="g27" /><g
     id="g29" /><g
     id="g31" /><g
     id="g33" /></svg>
Added freshlib/gui/images/svg/information.svg.



































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   viewBox="0 0 315.772 315.772"
   style="enable-background:new 0 0 315.772 315.772;"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="information.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/svg/information.png"
   inkscape:export-xdpi="13.68"
   inkscape:export-ydpi="13.68"><metadata
     id="metadata39"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
     id="defs37" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview35"
     showgrid="false"
     inkscape:zoom="1.6528479"
     inkscape:cx="61.990908"
     inkscape:cy="155.20997"
     inkscape:current-layer="Capa_1" /><rect
     style="fill:#ffffff;fill-opacity:1"
     id="rect4167"
     width="183.70152"
     height="222.76477"
     x="60.613361"
     y="8.9693317" /><path
     d="M287.355,0H28.173C17.145,0,8.386,8.472,8.386,19.5v213.822c0,11.028,8.759,19.678,19.787,19.678h67.628  c5.514,0,9.585,4.809,9.585,10.322V302.5c0,9.169,5.476,13.272,10.697,13.272c3.053,0,6.293-1.282,9.423-3.813l62.314-50.482  c5.483-4.431,16.527-8.478,23.576-8.478h75.959c11.028,0,20.031-8.649,20.031-19.678V19.5C307.386,8.472,298.383,0,287.355,0z   M182.904,92.834l-26.124,90.563c-1.422,5.357-2.131,8.91-2.131,10.657c0,0.877,0.381,1.75,1.148,2.624  c0.763,0.876,1.583,1.311,2.459,1.311c1.529,0,3.005-0.656,4.427-1.967c3.781-3.067,8.186-8.43,13.213-16.087  c0.347-0.529,1.496-1.585,2.16-0.987l2.682,1.532c0.665,0.574,0.253,1.403-0.021,1.869c-13.096,22.234-26.977,33.347-41.643,33.347  c-5.685,0-10.222-1.614-13.608-4.836c-3.389-3.222-5.083-7.296-5.083-12.215c0-3.279,0.763-7.432,2.295-12.46l18.363-63.123  c1.747-6.009,2.623-10.546,2.623-13.608c0-1.967-0.848-3.714-2.541-5.246c-1.696-1.529-3.963-2.296-6.804-2.296  c-0.579,0-1.185,0.009-1.817,0.028c-0.922,0.026-2.655-0.706-2.359-1.632c0.25-0.779,0.509-1.617,0.618-2.063  c0.507-2.068,5.213-2.185,5.213-2.185l36.527-5.887c0,0,2.912-0.558,4.984-0.558c1.587,0,3.096,0.014,4.127,0  C184.41,89.577,182.904,92.834,182.904,92.834z M189.408,61.987c-3.827,3.771-8.418,5.656-13.772,5.656  c-5.247,0-9.755-1.885-13.526-5.656c-3.771-3.771-5.656-8.333-5.656-13.69c0-5.354,1.857-9.944,5.574-13.772  c3.715-3.825,8.251-5.739,13.608-5.739c5.464,0,10.083,1.914,13.854,5.739c3.771,3.828,5.656,8.419,5.656,13.772  C195.146,53.654,193.232,58.216,189.408,61.987z"
     id="path3"
     style="fill:#3498db;fill-opacity:1" /><g
     id="g5" /><g
     id="g7" /><g
     id="g9" /><g
     id="g11" /><g
     id="g13" /><g
     id="g15" /><g
     id="g17" /><g
     id="g19" /><g
     id="g21" /><g
     id="g23" /><g
     id="g25" /><g
     id="g27" /><g
     id="g29" /><g
     id="g31" /><g
     id="g33" /></svg>
Added freshlib/gui/images/svg/question.svg.































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   viewBox="0 0 45.333 45.333"
   style="enable-background:new 0 0 45.333 45.333;"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="question.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/svg/question.png"
   inkscape:export-xdpi="95.290001"
   inkscape:export-ydpi="95.290001"><metadata
     id="metadata41"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
     id="defs39" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview37"
     showgrid="false"
     inkscape:zoom="11.513094"
     inkscape:cx="8.8995661"
     inkscape:cy="22.282322"
     inkscape:current-layer="Capa_1" /><g
     id="g3"
     style="fill:#2ecc71;fill-opacity:1"><path
       style="fill:#2ecc71;fill-opacity:1"
       d="M38.291,4.927c-1.2-1.142-1.792-1.316-1.3-0.481c0.302,0.513,0.555,1.039,0.757,1.58   c0.543,1.457,0.815,2.814,0.815,4.074c0,2.087-0.272,3.803-0.815,5.15c-0.545,1.347-1.217,2.499-2.021,3.454   c-0.805,0.957-1.694,1.772-2.672,2.445c-0.978,0.675-1.903,1.347-2.771,2.021c-0.87,0.674-1.641,1.445-2.315,2.314   c-0.353,0.455-0.637,0.97-0.853,1.544c-0.344,0.915-0.419,2.27-0.419,2.954s-1.97,1.238-4.399,1.238s-4.399-0.657-4.399-1.467   v-1.467c0.131-1.867,0.488-3.432,1.075-4.693c0.587-1.26,1.271-2.336,2.053-3.227c0.783-0.889,1.607-1.662,2.477-2.314   c0.868-0.652,1.673-1.303,2.412-1.956c0.739-0.652,1.337-1.369,1.793-2.151c0.456-0.782,0.661-1.759,0.619-2.933   c0-1.999-0.488-3.476-1.466-4.433c-0.978-0.956-2.338-1.434-4.074-1.434c-1.174,0-2.184,0.228-3.033,0.684   c-0.847,0.456-1.542,1.065-2.085,1.826c-0.545,0.76-0.946,1.651-1.206,2.672c-0.134,0.525-0.234,1.07-0.299,1.635   c-0.105,0.912-2.237,1.658-4.883,1.658s-4.8-1.489-4.475-3.282c0.201-1.109,0.498-2.166,0.89-3.171   c0.759-1.956,1.825-3.651,3.193-5.085c0.047-0.05,0.098-0.096,0.148-0.142c0.084-0.076-1.022,0.527-2.327,1.548   C3.409,7.636,0,14.09,0,21.344c0,10.014,6.496,18.507,15.503,21.505c1.572,0.523,2.256,0.143,1.852-0.834   c-0.238-0.576-0.37-1.205-0.37-1.866c0-2.772,2.291-5.019,5.116-5.019s5.116,2.247,5.116,5.019c0,0.716-0.155,1.395-0.434,2.009   c-0.472,1.042,0.127,1.51,1.728,1.084c9.685-2.577,16.822-11.402,16.822-21.899C45.336,14.882,42.63,9.055,38.291,4.927z"
       id="path5" /></g><g
     id="g7" /><g
     id="g9" /><g
     id="g11" /><g
     id="g13" /><g
     id="g15" /><g
     id="g17" /><g
     id="g19" /><g
     id="g21" /><g
     id="g23" /><g
     id="g25" /><g
     id="g27" /><g
     id="g29" /><g
     id="g31" /><g
     id="g33" /><g
     id="g35" /></svg>
Added freshlib/gui/images/svg/warning.svg.

































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   viewBox="0 0 356.484 356.484"
   style="enable-background:new 0 0 356.484 356.484;"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="warning.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/svg/warning.png"
   inkscape:export-xdpi="12.12"
   inkscape:export-ydpi="12.12"><metadata
     id="metadata39"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
     id="defs37" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview35"
     showgrid="false"
     inkscape:zoom="1.4640855"
     inkscape:cx="15.341685"
     inkscape:cy="166.40318"
     inkscape:current-layer="Capa_1" /><path
     style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
     d="M 162.55881,58.687198 C 26.637788,317.55186 27.320808,318.9179 27.320808,318.9179 l 299.845872,5.46416 -1.36604,0 -124.9927,-262.962781 2.04906,1.36604"
     id="path3367"
     inkscape:connector-curvature="0" /><path
     d="M354.239,321.64L189.847,22.478c-2.79-5.078-7.01-7.991-11.578-7.991c-4.584,0-8.824,2.931-11.631,8.04L2.245,321.64  c-2.749,5.002-2.984,10.138-0.646,14.09c2.356,3.983,7.023,6.267,12.806,6.267H342.08c5.782,0,10.449-2.284,12.806-6.267  C357.224,331.778,356.988,326.642,354.239,321.64z M154.064,93.621c0.922-0.955,2.166-1.624,3.504-1.624h40.897  c1.338,0,2.581,0.669,3.501,1.624c0.92,0.955,1.4,2.289,1.35,3.627l-5.174,139.618c-0.102,2.735-2.411,5.132-5.147,5.132h-30.298  c-2.738,0-5.043-2.363-5.138-5.099l-4.851-139.584C152.661,95.977,153.143,94.575,154.064,93.621z M178.188,315.435  c-15.386,0-26.988-12.19-26.988-28.355c0-16.36,11.455-28.697,26.646-28.697c15.689,0,26.646,11.801,26.646,28.697  C204.491,303.775,193.675,315.435,178.188,315.435z"
     id="path3"
     style="fill:#f1c40f;fill-opacity:1" /><g
     id="g5" /><g
     id="g7" /><g
     id="g9" /><g
     id="g11" /><g
     id="g13" /><g
     id="g15" /><g
     id="g17" /><g
     id="g19" /><g
     id="g21" /><g
     id="g23" /><g
     id="g25" /><g
     id="g27" /><g
     id="g29" /><g
     id="g31" /><g
     id="g33" /></svg>
Added freshlib/gui/images/treeview/down.png.

cannot compute difference between binary files

Added freshlib/gui/images/treeview/minus.png.

cannot compute difference between binary files

Added freshlib/gui/images/treeview/plus.png.

cannot compute difference between binary files

Added freshlib/gui/images/treeview/right.png.

cannot compute difference between binary files

Added freshlib/gui/images/treeview/svg/down.svg.

























































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="10.999998"
   height="11"
   viewBox="0 0 10.999998 11"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="down.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/treeview/down.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata42"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
     id="defs40" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="1920"
     inkscape:window-height="1061"
     id="namedview38"
     showgrid="false"
     inkscape:zoom="28.828239"
     inkscape:cx="-11.563886"
     inkscape:cy="3.3388835"
     inkscape:window-x="-4"
     inkscape:window-y="-4"
     inkscape:window-maximized="1"
     inkscape:current-layer="Capa_1"
     fit-margin-top="0"
     fit-margin-left="0"
     fit-margin-right="0"
     fit-margin-bottom="0" /><g
     id="g3"
     transform="matrix(0,0.03565062,-0.03081232,0,10.999998,-0.86363513)"
     style="fill:#95a5a6;fill-opacity:1"><g
       id="play-arrow"
       style="fill:#95a5a6;fill-opacity:1"><polygon
         points="318.75,178.5 38.25,0 38.25,357 "
         id="polygon6"
         style="fill:#95a5a6;fill-opacity:1" /></g></g><g
     id="g8"
     transform="translate(-178.5,-165.60715)" /><g
     id="g10"
     transform="translate(-178.5,-165.60715)" /><g
     id="g12"
     transform="translate(-178.5,-165.60715)" /><g
     id="g14"
     transform="translate(-178.5,-165.60715)" /><g
     id="g16"
     transform="translate(-178.5,-165.60715)" /><g
     id="g18"
     transform="translate(-178.5,-165.60715)" /><g
     id="g20"
     transform="translate(-178.5,-165.60715)" /><g
     id="g22"
     transform="translate(-178.5,-165.60715)" /><g
     id="g24"
     transform="translate(-178.5,-165.60715)" /><g
     id="g26"
     transform="translate(-178.5,-165.60715)" /><g
     id="g28"
     transform="translate(-178.5,-165.60715)" /><g
     id="g30"
     transform="translate(-178.5,-165.60715)" /><g
     id="g32"
     transform="translate(-178.5,-165.60715)" /><g
     id="g34"
     transform="translate(-178.5,-165.60715)" /><g
     id="g36"
     transform="translate(-178.5,-165.60715)" /></svg>
Added freshlib/gui/images/treeview/svg/right.svg.

























































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="11"
   height="11"
   viewBox="0 0 11 11"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="right.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/gui/images/treeview/right.png"
   inkscape:export-xdpi="90"
   inkscape:export-ydpi="90"><metadata
     id="metadata42"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
     id="defs40" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="1920"
     inkscape:window-height="1061"
     id="namedview38"
     showgrid="false"
     inkscape:zoom="49.506957"
     inkscape:cx="1.8287641"
     inkscape:cy="4.8854653"
     inkscape:window-x="-4"
     inkscape:window-y="-4"
     inkscape:window-maximized="1"
     inkscape:current-layer="Capa_1"
     fit-margin-top="0"
     fit-margin-left="0"
     fit-margin-right="0"
     fit-margin-bottom="0" /><g
     id="g3"
     transform="matrix(0.03565062,0,0,0.03081232,-0.86363622,1.9073486e-6)"
     style="fill:#95a5a6;fill-opacity:1"><g
       id="play-arrow"
       style="fill:#95a5a6;fill-opacity:1"><polygon
         points="38.25,0 38.25,357 318.75,178.5 "
         id="polygon6"
         style="fill:#95a5a6;fill-opacity:1" /></g></g><g
     id="g8"
     transform="translate(-7.4999994,-339)" /><g
     id="g10"
     transform="translate(-7.4999994,-339)" /><g
     id="g12"
     transform="translate(-7.4999994,-339)" /><g
     id="g14"
     transform="translate(-7.4999994,-339)" /><g
     id="g16"
     transform="translate(-7.4999994,-339)" /><g
     id="g18"
     transform="translate(-7.4999994,-339)" /><g
     id="g20"
     transform="translate(-7.4999994,-339)" /><g
     id="g22"
     transform="translate(-7.4999994,-339)" /><g
     id="g24"
     transform="translate(-7.4999994,-339)" /><g
     id="g26"
     transform="translate(-7.4999994,-339)" /><g
     id="g28"
     transform="translate(-7.4999994,-339)" /><g
     id="g30"
     transform="translate(-7.4999994,-339)" /><g
     id="g32"
     transform="translate(-7.4999994,-339)" /><g
     id="g34"
     transform="translate(-7.4999994,-339)" /><g
     id="g36"
     transform="translate(-7.4999994,-339)" /></svg>
Deleted freshlib/gui/images/warning.gif.

cannot compute difference between binary files

Added freshlib/gui/images/warning.png.

cannot compute difference between binary files

Changes to freshlib/gui/mouse.asm.
17
18
19
20
21
22
23



24

25


























26
27
28
29
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58







+
+
+

+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




mcText  = 1
mcCross = 2
mcSizeH = 3
mcSizeV = 4
mcSizeUL_LR = 5
mcSizeLL_UR = 6
mcWait      = 7
mcHand      = 8
mcDragHand  = 9
mcPencil    = 10


mcCount = 8
mcCount = 11



proc SetMouseCapture, .window
begin
        pushad

        xor     edi, edi

        mov     esi, [.window]
        cmp     [.window], edi
        je      .setit

        get     edi, esi, TWindow:OSWindow
        mov     edi, [edi+TWindow.handle]

.setit:
        mov     [__MouseTarget], esi
        stdcall __MouseCapture, edi

        popad
        return
endp



include '%TargetOS%/mouse.asm'

endmodule
Deleted freshlib/gui/realobjects.asm.
Deleted freshlib/gui/realobjects.inc.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406






















































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
cParamMask = $fffe0000
cMethodMask = $ffff0000


macro __search_method flag, num, count, list, cname, method {
  define flag FALSE
  rept count i:1 \{ match mname, method \\{ match class | name , list\\#i \\\{ match =mname, name \\\\{
    define flag TRUE
    num equ i
  \\\\} \\\} \\} \}
}


macro object name, parent {
  obj@name   equ name
  obj@parent equ parent

  name#.param?num = 0

  name#@count equ 0

  match any, parent \{
    name#@count equ parent#@count
    rept parent\#@count i:1 \\{
      name\\#@method\\#i equ parent\\#@method\\#i
      match class | mname, parent\\#i \\\{
        name\\\#mname = i or cMethodMask
;        display 3, "Copy:", \\\`name,\\\`mname, ' = ', \\\`i, 13, 10
      \\\}
    \\}
  \}

  macro param paramname*, getval*, setval* \{
    paramname = name#.param?num or cParamMask
    name#.param?num = name#.param?num + 1

      if getval eq NONE
        paramname\#.get = -1
      else
        paramname\#.get = getval
      end if

      if setval eq NONE  ; read only
        paramname\#.set = -1
      else
        paramname\#.set = setval
      end if
  \}

  macro method mname, [marg] \{
  \common
  \local f1, n1
    name\#mname\#.arguments equ marg
    define f1 FALSE
    __search_method f1, n1, name\#@count, name\#@method, parent, mname
    match =FALSE, f1 \\{
      rept 1 x:name\\#@count+1 \\\{
        name\\\#@count equ x
        name\\\#@method\\\#x equ name | mname
;        display 3,'New method:', \\\`name,\\\`mname, ' = ', \\\`x, 13, 10
        methods.\\\#name\\\#mname\\\#.inherited equ NONE
      \\\}
    \\}
    match =TRUE, f1 \\{
      match num, n1 \\\{
        match class | mmname, name\\\#@method\\\#num \\\\{
          methods.\\\\#name\\\\#mname\\\\#.inherited equ methods.\\\\#class\\\\#mmname
        \\\\}
        name\\\#@method\\\#num equ name | mname
;        display 3,'Redefinition:', \\\`name,\\\`mname, ' = ', \\\`num, 13, 10
      \\\}
    \\}
  \}

  macro abstract mname, [marg] \{
  \common
    method mname, marg
    methods.\#name\#mname = 0
  \}


  macro name#@members \{
    macro method mname, [marg] \\{ \\}
    macro abstract mname, [marg] \\{ \\}
    match any, parent \\{
      parent\\#@members
    \\}
    purge method, abstract
}


endobj fix } obj_helper


macro obj_helper {
  match name, obj@name \{

    virtual at 0
      name dd ?           ; pointer to the methods table.
      name\#@members

      rept name\#@count i:1 \\{
        match class | meth, name\\#@method\\#i \\\{
          name\\\#meth = (i-1) or cMethodMask
;          display 1, "Method constant", \\\`name,\\\`meth, " = ", \\\`i, 13, 10
        \\\}
      \\}

      sizeof.\#name = $
    end virtual

    label vtables.\#name dword

    if used vtables.\#name\#.parent | used vtables.\#name
      .parent dd 0
    end if

    match parent, obj@parent \\{
      if defined vtables.\\#parent\\#.parent    ; in order to not use the address vtables.#parent
        store dword vtables.\\#parent\\#.parent at .parent
      end if
    \\}

    if used vtables.\#name
      .mcount dd name\#@count     ; methods count
;      display 2, \`name, " methods list ----------------------------------", 13, 10
      rept name\#@count i:1 \\{
        match class | meth, name\\#@method\\#i \\\{
;          display 1, \\\`class, \\\`meth, 13, 10
          if defined methods.\\\#class\\\#meth
            dd methods.\\\#class\\\#meth
          else
            dd 0
          end if
        \\\}
      \\}
    end if
  \}
  purge method, param
  restore obj@name, obj@parent
}


macro method name {
  local f1, f2
  define f1 TRUE
  if used methods.#name
    match =NONE, methods.#name#.inherited \{
      define f1 FALSE
      dd 0
    \}
    match =TRUE, f1 \{
      dd methods.\#name\#.inherited
    \}
  end if
  match =name#.arguments, name#.arguments \{
    "Error! Method not defined in any object."
  \}

  f2 equ FALSE
  match arguments, name#.arguments \{
    f2 equ TRUE
    proc methods.\#name, .self, arguments
  \}
  match =FALSE, f2 \{
    proc methods.\#name, .self
  \}
}



; Object manipulation macros. They all generate some assembly code and its syntax is
; designed to resemble the usual assembly language syntax. These macros are some
; kind of quasiinstructions.

; These macros uses FreshLib in order to allocate/deallocate dynamic memory.



macro create target, class {
   if ~target eq eax
        push    eax
   end if

        stdcall GetMem, sizeof.#class
        mov     dword [eax], vtables.#class

   if ~target eq eax
        mov     target, eax
   end if

   if defined class#.Create & (class#.Create and $ffff0000) = cMethodMask
        exec    eax, class#:Create
   end if

   if ~target eq eax
        pop     eax
   end if
}


macro destroy ptrObj {
   if defined TObject.Destroy & (TObject.Destroy and $ffff0000) = cMethodMask
        push    eax
        exec    ptrObj, TObject:Destroy
        pop     eax
   end if
       stdcall  FreeMem, ptrObj
}


macro exec ptrobj, method, [arg] {
common
  local ind
        ind equ NONE
        match class:meth, method \{
          ind equ class\#.\#meth
        \}

        match =NONE, ind \{
          disp 2, "Error! Invalid syntax. Use class:method.", 13, 10
          err
        \}

        if defined ind & ~(ind and $ffff0000) = cMethodMask
          match meth, ind \{
            disp 2, 'Error! ', \`meth, ' is not a method.', 13, 10
            err
          \}
        end if

reverse
        if ~arg eq
          pushx   arg
        end if
common
  local ..end

        if ptrobj eqtype 1
          pushd [ptrobj]
        else
          pushd   ptrobj          ; push .self argument
        end if

        if ptrobj eqtype eax
          mov  eax, [ptrobj]
        else
          if ptrobj eqtype 1
            mov  eax, [ptrobj]
            mov  eax, [eax]
          else
            mov  eax, ptrobj
            mov  eax, [eax]
          end if
        end if

        call dword [eax+8+4*(ind and $ffff)]
}



macro inherited [arg] {
common
  if ~arg eq
reverse
    pushx arg
common
  end if
  push [.self]
  call  dword [.__info.start-4]
}



macro get target, obj, param {
local flag

  flag equ FALSE

  match class:par, param \{
    flag equ TRUE
  \}

  match =FALSE, flag \{
    disp 2, "Error! Invalid syntax. Use class:method.", 13, 10
    err
  \}

  match class:par, param \{

    if class\#.\#par\#.get < sizeof.\#class ; field
      if obj eqtype eax
        if target eqtype eax
          mov target, [obj+class\#.\#par\#.get]
        else
          pushd [obj+class\#.\#par\#.get]
          popd  target
        end if
      else
        if ~target eq eax
          push eax
        end if
        if obj eqtype 1
          mov eax, [obj]
        else
          mov eax, obj
        end if
        if target eqtype eax
          mov target, [eax+class\#.\#par\#.get]
        else
          pushd [eax+class\#.\#par\#.get]
          popd  target
        end if
        if ~target eq eax
          pop eax
        end if
      end if
    else        ; by method
      if ~target eq eax
        push eax
      end if
      exec obj, class\#:\#par\#.get
      if ~target eq eax
        mov target, eax
        pop eax
      end if
    end if
  \}
}


macro set obj, param, value {
local flag

  flag equ FALSE

  match class:par, param \{
    flag equ TRUE
  \}

  match =FALSE, flag \{
    disp 2, "Error! Invalid syntax. Use class:method.", 13, 10
    err
  \}

  match class:par, param \{

    if class\#.\#par\#.set < sizeof.\#class ; field
      if obj eqtype eax
        if value eqtype eax
          mov [obj+class\#.\#par\#.set], value
        else
          pushd value
          popd  [obj+class\#.\#par\#.set]
        end if
      else
        if value eq eax
          push ecx
          mov  ecx, obj
          mov [ecx+class\#.\#par\#.set], value
          pop ecx
        else
          push eax
          mov  eax, obj
          if value eqtype eax
            mov [eax+class\#.\#par\#.set], value
          else
            pushd value
            popd  [eax+class\#.\#par\#.set]
          end if
          pop eax
        end if
      end if
    else        ; by method
      push eax
      exec obj, class\#:\#par\#.set, value
      pop  eax
    end if
  \}
}


; returns ZF = 1 if the type matches
; returns ZF = 0 if the type does not matches.

macro istype ptrobj, class {
  local ..itis, ..loop
        push    ecx

  if ptrobj eqtype eax    ; register
    if ~ptrobj eq ecx
        mov     ecx, ptrobj
    end if
  else
        mov     ecx, ptrobj
  end if

..loop:
        mov     ecx, [ecx]    ; get vtable, or the parent vtable
        jecxz   ..itis        ; if jump, ZF=0
        cmp     ecx, vtables.#class
        jne     ..loop
; here ZF = 1
..itis:
        pop     ecx
}
Changes to freshlib/gui/sysevents.asm.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31


32
33
34

35
36
37
38
39
40
41

42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158
159

160
161
162
163

164
165
166
167

168
169
170
171
172
173

174
175
176
177

178
179
180
181
182

183
184
185
186
187
188
189
9
10
11
12
13
14
15












16



17
18



19


20


21

22




23
24









25
26
27
28
29
30
31
32
33
34














35
36
37
38
39








40
41
42
43
44
45
46
47
48
49




























50
51
52
53



54



55
56






57
58









59
60
61
62

63
64
65


66
67
68
69
70
71

72
73
74
75

76
77
78
79
80

81
82
83
84
85
86
87
88







-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
+
+
-
-
-
+
-
-

-
-

-
+
-
-
-
-
+

-
-
-
-
-
-
-
-
-










-
-
-
-
-
-
-
-
-
-
-
-
-
-





-
-
-
-
-
-
-
-










-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




-
-
-

-
-
-


-
-
-
-
-
-
+

-
-
-
-
-
-
-
-
-
+



-
+


-
-
+





-
+



-
+




-
+







;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________
module "System events library"

seMouseMove        = $0001
seMouseEnter       = $0002
seMouseLeave       = $0003
seMouseBtnPress    = $0004
seMouseBtnRelease  = $0005
seMouseBtnClick    = $0006
seMouseBtnDblClick = $0007
seTimer            = $0008
seKbdKeyPress      = $0009
seKbdKeyRelease    = $000a
seKbdStatusChanged = $000b
seKbdChar          = $000c

seScroll           = $000d


mbLeft   = 1
mbMiddle = 2
sePaint            = $0100
seCloseRequest     = $0101

mbRight  = 3
seFocusIn          = $0102
seFocusOut         = $0103

seMove             = $0104
seResize           = $0105


mbScrollUp = 4
struct TSysEvent
  .event  dd  ?
ends

mbScrollDn = 5

struct TMouseMoveEvent
  . TSysEvent
  .x         dd ?
  .y         dd ?
ends

mbLeft   = 0
mbMiddle = 1
mbRight  = 2

maskBtnLeft   = $0100
maskBtnMiddle = $0200
maskBtnRight  = $0400
maskShift     = $1
maskCapsLock  = $2
maskCtrl      = $4
maskAlt       = $8
maskScrLk     = $10


struct TMouseButtonEvent
  . TSysEvent
  .Button    dd ?
  .kbdStatus dd ?
  .x         dd ?   ; coordinates of the mouse pointer in the client
  .y         dd ?
ends


struct TMouseEnterEvent
  . TSysEvent
ends


; These are scan codes for the non character keys. They are OS dependent and should be used by
; their names.
include '%TargetOS%/keycodes.inc'


struct TKeyboardEvent
  . TSysEvent
  .key       dd  ?      ; 1..4 bytes UTF-8 character typed by the keyboard, or 0 if non character key is pressed/released.
  .scancode  dd  ?      ; scan code of the pressed key.
  .kbdStatus dd  ?      ; same as mouse button event - contains mouse buttons and Ctrl, Shift and Alt keys status.
ends


scTrack   = 1
scUp      = 2
scDown    = 3
scWheelUp = 4
scWheelDn = 5

scrollX = 0
scrollY = 1


struct TScrollEvent
  . TSysEvent
  .ScrollBar  dd ?      ; 0
  .ScrollCmd  dd ?      ;
  .Value      dd ?      ; Distance for scUp and scDown and position for scTrack
ends


struct TTimerEvent
  . TSysEvent
  .timer dd ?
ends


struct TPaintEvent
  . TSysEvent

  .context dd ?  ; pointer to TContext structure, properly initialized.
  .rect   RECT
ends


struct TCloseEvent
  . TSysEvent
  .reason dd ?          ; how the close was requested?
ends

cerFromUser = 0         ; user pressed X button on the window header, pressed alt+F4 from the keyboard, or choose "Close" from the title menu.
cerFromProgram = 1      ; Method Close was executed from the program.


struct TFocusInEvent
  . TSysEvent
ends

struct TFocusOutEvent
  . TSysEvent
ends


struct TMoveEvent
  . TSysEvent
  .newX  dd ?
  .newY  dd ?
ends

; creates and returns a string with the textual identifier of the pressed/released key.

struct TResizeEvent
  . TSysEvent
  .newWidth  dd ?
  .newHeight dd ?
ends


; creates and returns a string with the textual identifier of the pressed/released key.
proc CreateKeyName, .pKeyEvent
proc CreateKeyName, .utf8, .scancode, .kbdStatus
begin
        push    ebx ecx esi edi

        stdcall StrDup, .strkey
        stdcall StrNew
        mov     ebx, eax

        mov     edi, [.pKeyEvent]
        test    [edi+TKeyboardEvent.kbdStatus], maskCtrl
        test    [.kbdStatus], maskCtrl
        jz      @f

        stdcall StrCharCat, ebx, 'Ctrl'
        stdcall StrCharCat, ebx, '+'
@@:
        test    [edi+TKeyboardEvent.kbdStatus], maskAlt
        test    [.kbdStatus], maskAlt
        jz      @f
        stdcall StrCharCat, ebx, 'Alt+'
@@:
        test    [edi+TKeyboardEvent.kbdStatus], maskShift
        test    [.kbdStatus], maskShift
        jz      @f
        stdcall StrCharCat, ebx, 'Shif'
        stdcall StrCharCat, ebx, 't+'
@@:
        mov     ecx, [edi+TKeyboardEvent.key]
        mov     ecx, [.utf8]
        jecxz   .searchlist

        cmp     ecx, ' '
        jne     @f
        mov     ecx, 'Spc'
@@:
        cmp     ecx, ' '
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138







-
+
















-
+








.searchlist:
        mov     esi, __FunctionalKeyNames

.loop:
        movzx   ecx, word [esi]
        jecxz   .notfound
        cmp     ecx, [edi+TKeyboardEvent.scancode]
        cmp     ecx, [.scancode]
        je      .found
        add     esi, 4
        jmp     .loop

.found:
        movsx   eax, word [esi+2]
        add     esi, eax
        stdcall StrCat, ebx, esi
        jmp     .exitok

.notfound:
        stdcall StrDel, ebx
        xor     eax, eax
        stc
        jmp     .finish

.strkey db 'key', 0
;.strkey db 'key', 0
endp


macro keynames lbl, [scancode, name] {
common
  label lbl word
forward
285
286
287
288
289
290
291
292
293
294



295
296
297
298



299
300
301
302
184
185
186
187
188
189
190



191
192
193
194



195
196
197
198
199
200
201







-
-
-
+
+
+

-
-
-
+
+
+




            keyF8,             'F8',                     \
            keyF9,             'F9',                     \
            keyF10,            'F10',                    \
            keyF11,            'F11',                    \
            keyF12,            'F12',                    \
            keyCapsLock,       'CapsLock',               \
            keyShiftLeft,      'ShiftL',                 \
            keyCtrlLeft,       'CtrlL',                  \
            keyAltLeft,        'AltL',                   \
            keyAltRight,       'AltR',                   \
            keyCtrlLeft,       'LeftCtrl',                  \
            keyAltLeft,        'LeftAlt',                   \
            keyAltRight,       'RightAlt',                   \
            keyPopupMenu,      'PopupMenu',              \
            keyShiftRight,     'ShiftR',                 \
            keyCtrlRight,      'CtrlR',                  \
            keyBackSpace,      'BackSp'
            keyShiftRight,     'RightShift',                 \
            keyCtrlRight,      'RightCtrl',                  \
            keyBackSpace,      'BkSp'
  end if
endg

endmodule
Changes to freshlib/gui/textcaret.asm.
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
179
180
181
182
183
184
185

186
187
188
189
190
191
192
193







-
+









proc __CaretTimerProc, .timer
begin
        cmp     [Caret.pWindow], 0
        je      .exit

        mov     eax, -1
        or      eax, -1
        xchg    [Caret.sync], eax
        test    eax, eax
        jnz     .exit                   ; don't wait for lock.

        cmp     [Caret.visible], 0
        je      @f
        mov     eax, 2
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245

246
247

248
249
250
251

252
253
254
255





256
257
258
259
260
261
262
263
209
210
211
212
213
214
215


216
217
218
219

220
221
222
223


224






225

226
227
228
229
230

231



232
233

234
235



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253







-
-




-




-
-
+
-
-
-
-
-
-

-
+




-

-
-
-
+

-
+

-
-
-
+




+
+
+
+
+








        mov     eax, [Caret.state]
        cmp     eax, [.operation]
        je      .exit

        cmp     [Caret.pWindow], 0
        je      .exit

        push    $ffffffff

        xor     eax, 1
        mov     [Caret.state], eax

        mov     ecx, [Caret.timer]
        mov     eax, [Caret.state]
        mov     eax, [CaretTimes+4*eax]
        mov     [ecx+TTimer.interval], eax
        mov     [ecx+TTimer.value], 0

        test    eax, eax
        jnz     .draw
        jz      .clean
; clear
        push    [Caret.OldPos.height]
        push    [Caret.OldPos.width]
        push    [Caret.OldPos.y]
        push    [Caret.OldPos.x]
        jmp     .drawit

.draw:
        push    $ffFF0000
        push    [Caret.Pos.height] [Caret.Pos.width] [Caret.Pos.y] [Caret.Pos.x]
        push    [Caret.Pos.height] [Caret.Pos.width] [Caret.Pos.y] [Caret.Pos.x]
        pop     [Caret.OldPos.x] [Caret.OldPos.y] [Caret.OldPos.width] [Caret.OldPos.height]

.drawit:
        mov     eax, [Caret.pWindow]
        stdcall AllocateContext, [eax+TWindow.handle]
        test    eax, eax
        jz      .exit
        get     esi, [Caret.pWindow], TWindow:Canvas

        mov     esi, eax
        stdcall DrawSolidRect, esi ; arguments from the stack

        stdcall SetDrawMode, esi, cmXor
        stdcall DrawFillRect, esi  ; arguments from the stack
        stdcall ReleaseContext, esi
        exec    [Caret.pWindow], TWindow:Update

.exit:
        pop     esi ecx
        return

.clean:
        exec    [Caret.pWindow], TWindow:Refresh        ; cleans the caret by repainting the whole window? - not good solution, actually!!!
        jmp     .exit

endp




endmodule


Added freshlib/gui/themes.asm.















































































































































































































































































































































































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: This file contains procedures and data, that form the appearance of the
;               FreshLib GUI application. Colors, control borders, backgrownd drawing etc.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: The user should be able to change these settings and if he uses external
;         procedures, then the code from this library should not be compiled.
;_________________________________________________________________________________________

module "Runtime GUI themes support"


; Box border type
bxNone   = 0
bxRaised = 1
bxSunken = 2
bxFlat   = 3
bxFocused = 4
bxNoFill = $80000000
bxDisabled = $40000000




struct TMetaHeader
  .pData dd ?           ; pointer to the NamedArray data fields.
  .length dd ?          ; total length of the NamedArray structure: fields+static data+meta data.
  .count dd ?           ; count of the TMetaFields following.
ends

struct TMetaField
  .pName  dd  ?
  .type   dw  ?
  .len    dw  ?         ; length of the field in dwords
  .offset dd  ?         ; offset of the field, relative to the start of the array.
ends


;
; The NamedArray is a type of structure that contains
; the fields names together with the field values.
; This way, the values of the array can be write to
; text files and then restored in runtime, based not
; on the fields offsets (that can differ) but based on
; field names.
;


___natNUM     = 0          ; NUM,  Stored as decimal, signed.
___natHEX     = 1          ; HEX,  Stored as hex, unsigned.
___natTXT     = 2          ; TXT,  Stored as string. Needs postprocessing.
___natFONT    = 3          ; FONT, Stored as multivalue: face, size, flags, etc.
___natPNG     = 4          ; PNG,  Stored as a hex array. Need postprocessing.
___natFILE    = 5          ; FILE, Stored as a hex array.


macro NamedArray lbl, [name, type, value] {
common
  local ..fake_lbl

  label ..fake_lbl dword
  label lbl dword

; data fields

forward
  local ..len, ..fake_name

    ..len = 0

    label ..fake_name dword

    if used lbl#.#name | (defined options.WholeTheme & options.WholeTheme)
      label lbl#.#name dword
      irp val, value \{

        ..len = ..len + 1

        if (type eq NUM)|(type eq HEX)
          dd val
        else
          if type eq TXT
            if val eqtype 1
              dd val
            else
              dd 0        ; will be changed later in the macro
            end if
          else
            if (type eq FONT) | (type eq PNG)
              dd 0        ; will be changed later in the macro.
              dd 0
            else
              if type eq FILE
                dd 0          ; pointer to data
              else
                Error! Unknown `type type.
              end if
            end if
          end if
        end if
      \}
    end if

; data for the strings, images, files, etc.
forward
local ..index

    ..index = 0

    irp val, value \{
    \local ..dta, ..len

      if used lbl\#.\#name | (defined options.WholeTheme & options.WholeTheme)
        if type eq TXT
          if ~ val eqtype 1
              ..dta db val
                    db 0
          end if
        end if

        if type eq FONT
          match face : size : weight : flags, val \\{         ; For the Linux port, this structure is enough and not need FontCreate call.
            \\local ..font_face

            ..dta dd  ..font_face   ; font face string
                  dd  size          ; NUM
                  dd  weight        ; NUM
                  dd  flags         ; HEX

            ..font_face db face, 0
          \\}

          ..index = ..index + 4
        end if

        if type eq PNG
                dd ..len
          ..dta file val
          ..len = $ - ..dta

          ..index = ..index + 4
        end if

        if type eq FILE
                dd ..len
          ..dta file val
          ..len = $ - ..dta
        end if

        if defined ..dta
          store dword ..dta at ..fake_name + ..index
        end if
      end if

      ..index = ..index + 4
    \}

; Header of the meta data.
common
  local ..cnt, ..total, ..fake_meta
  ..cnt = 0

  if used lbl#.#meta | (defined options.WholeTheme & options.WholeTheme)

    label lbl#.#meta dword
    label ..fake_meta  dword

    dd ..fake_lbl
    dd lbl#.#size
    dd ..total

; metadata
forward
  local ..namestr

; array with the fields names and offsets.
    if defined lbl#.#name

      dd  ..namestr
      dw  ___nat#type
      dw  ..len     ; dwords
      dd  ..fake_name - ..fake_lbl

      ..cnt = ..cnt + 1

    end if

; field names
forward

    if used ..namestr | (defined options.WholeTheme & options.WholeTheme)
      ..namestr db `name, 0
    end if

; Initialization code
common
  end if

    if used lbl#.#Init | (defined options.WholeTheme & options.WholeTheme)
      lbl#.#Init:

forward

local ..index

      ..index = 0

      irp val, value \{
        if used lbl\#.\#name | (defined options.WholeTheme & options.WholeTheme)
          if type eq FONT
            mov     eax, [..fake_name+..index+4]
            stdcall  FontCreate, [eax+__TFont.hFontFace], [eax+__TFont.height], [eax+__TFont.weight], [eax+__TFont.flags]
            mov      [..fake_name+..index], eax

            ..index = ..index + 4
          end if

          if (type eq PNG)
            mov     eax, [..fake_name+..index+4]
            stdcall  CreateImagePNG, eax, [eax-4]
            mov      [..fake_name+..index], eax

            ..index = ..index + 4
          end if
        end if

        ..index = ..index + 4
      \}

common
          retn
    end if
common
  lbl#.#size = $ - ..fake_lbl

  ..total = ..cnt
}



; Serializes the NamedArray to a string.
; .pMeta - poitner to the meta data of the named array structure.

proc NamedArrayToString, .pMeta
.array dd ?
.data2string dd ?
.datalen     dd ?
begin
        pushad

        mov     esi, [.pMeta]
        stdcall StrNew
        mov     edi, eax

        lodsd
        mov     [.array], eax

        lodsd   ; TMetaHeader.length

        lodsd
        mov     ecx, eax        ; count of the meta records.

.loop:
        dec     ecx
        js      .end_loop

        lodsd                   ; pointer to the field name.

        stdcall StrCat, edi, eax
        stdcall StrCharCat, edi, " = "

        lodsw                   ; data type
        movzx   eax, ax
        push    [.data_handlers+4*eax]
        push    [.data_len+4*eax]

        pop     [.datalen]
        pop     [.data2string]

        lodsw
        movzx   edx, ax         ; number of sub values

        lodsd                   ; offset, relative to [.array]
        mov     ebx, eax
        add     ebx, [.array]   ; pointer to the values

.loop2:
        dec     edx
        js      .end_loop2

        stdcall [.data2string], ebx
        push    eax

        stdcall StrCat, edi, eax
        stdcall StrDel ; from the stack

        add     ebx, [.datalen]

        test    edx, edx
        jz      .loop2

        stdcall StrCharCat, edi, ", "
        jmp     .loop2

.end_loop2:
        stdcall StrCharCat, edi, $0a0d
        jmp     .loop

.end_loop:
        mov     [esp+regEAX*4], edi
        popad
        return


.data_handlers dd __DataToNum, __DataToHex, __DataToTxt, __DataToFont, __DataToPng, __DataToFile
.data_len      dd 4,           4,           4,           8,            8,            4

endp


proc __DataToNum, .pData
begin
        mov     eax, [.pData]
        stdcall NumToStr, [eax], ntsDec or ntsSigned
        return
endp



proc __DataToHex, .pData
begin
        mov     eax, [.pData]
        stdcall NumToStr, [eax], ntsHex or ntsUnsigned
        stdcall StrCharInsert, eax, '$', 0
        return
endp



proc __DataToTxt, .pData
begin
        mov     eax, [.pData]
        stdcall StrDupMem, [eax]
        stdcall StrSetQuotes, eax, 0
        return
endp



proc __DataToFont, .pData
begin
        push    esi ebx

        mov     esi, [.pData]
        mov     esi, [esi+4]

        stdcall StrDup, [esi+__TFont.hFontFace]    ; face name
        stdcall StrSetQuotes, eax, 0
        mov     ebx, eax

        stdcall StrCharCat, ebx, " : "

        stdcall NumToStr, [esi+__TFont.height], ntsDec or ntsUnsigned    ; size
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax

        stdcall StrCharCat, ebx, " : "

        stdcall NumToStr, [esi+__TFont.weight], ntsDec or ntsUnsigned    ; weight
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax

        stdcall StrCharCat, ebx, " : $"

        stdcall NumToStr, [esi+__TFont.flags], ntsHex or ntsUnsigned    ; flags
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax

        mov     eax, ebx

        pop     ebx esi
        return
endp



proc __DataToPng, .pData
begin
        pushad

        mov     esi, [.pData]
        mov     esi, [esi+4]            ; pointer to the compressed file.
        mov     ecx, [esi-4]            ; length
        jmp     __DataToFile.convert_file
endp



proc __DataToFile, .pData
begin
        pushad

        mov     esi, [.pData]
        mov     esi, [esi]              ; pointer to the compressed file.
        mov     ecx, [esi-4]            ; length

.convert_file:
        stdcall NumToStr, ecx, ntsDec or ntsUnsigned
        mov     ebx, eax

        stdcall StrCharCat, ebx, ":"

        stdcall EncodeBase64, esi, ecx
        push    eax

        stdcall StrCat, ebx, eax
        stdcall StrDel ; from the stack

        mov     [esp+regEAX*4], ebx
        popad
        return
endp




proc StringToNamedArray, .pMeta, .hString
.string2data dd ?
.free_data   dd ?
.data_start  dd ?
.data_end    dd ?
begin
        pushad

        mov     esi, [.pMeta]
        mov     eax, [esi+TMetaHeader.pData]
        mov     [.data_start], eax
        add     eax, [esi+TMetaHeader.length]
        mov     [.data_end], eax

        stdcall StrSplitList, [.hString], $0a, FALSE
        mov     esi, eax

        xor     ecx, ecx

.loop:
        cmp     ecx, [esi+TArray.count]
        jae     .end_loop

        stdcall StrSplitList, [esi+TArray.array+4*ecx], "=", FALSE
        mov     edi, eax

        cmp     [edi+TArray.count], 2
        jne     .next_line

        stdcall __SearchName, [.pMeta], [edi+TArray.array]
        test    eax, eax
        jz      .free1

        push    esi ecx

        mov     ebx, eax

        stdcall StrSplitList, [edi+TArray.array+4], ',', FALSE
        mov     edx, eax

        movzx   ecx, [ebx+TMetaField.len]
        cmp     ecx, [edx+TArray.count]
        jb      .free2                          ; there is no place to restore this parameter.

        movzx   eax, [ebx+TMetaField.type]
        push    [.data_handlers+4*eax]
        push    [.free_handlers+4*eax]

        pop     [.free_data]
        pop     [.string2data]

        mov     esi, [ebx+TMetaField.offset]
        add     esi, [.data_start]      ; pointer to the data field.

        xor     ecx, ecx

.loop2:
        cmp     ecx, [edx+TArray.count]
        jae     .free2

        call    [.free_data]
        stdcall [.string2data], [edx+TArray.array+4*ecx]

        inc     ecx
        jmp     .loop2


.free2:
        stdcall ListFree, edx, StrDel

        pop     ecx esi

.free1:
        stdcall ListFree, edi, StrDel

.next_line:
        inc     ecx
        jmp     .loop

.end_loop:
        stdcall ListFree, esi, StrDel
        popad
        return

.data_handlers dd __NumToData, __NumToData, __TxtToData, __FontToData, __PngToData, __FileToData
.free_handlers dd .end_free,   .end_free,   .free_txt,   .free_font,   .free_png,   .free_file


.check_ptr:
        test    eax, eax
        jz      .out

        cmp     eax, [.data_start]
        jb      .out
        cmp     eax, [.data_end]
        ja      .out
;in
        stc
        retn

.out:
        clc
        retn

.free_txt:
        stdcall StrDel, [esi]
        retn

.free_font:
        stdcall FontDestroy, [esi]
        mov     eax, [esi+4]
        call    .check_ptr
        jc      .end_free

        stdcall StrDel, [eax+__TFont.hFontFace]
        retn

.free_png:
        stdcall DestroyImage, [esi]
        mov     eax, [esi+4]

.free_ptr:
        sub     eax, 4
        call    .check_ptr
        jc      .end_free

        stdcall FreeMem, eax

.end_free:
        retn


.free_file:
        mov     eax, [esi]
        jmp     .free_ptr

endp



proc __NumToData, .hString
begin
        stdcall StrToNumEx, [.hString]
        mov     [esi], eax
        add     esi, 4
        return
endp


proc __TxtToData, .hString
begin
        stdcall StrDup, [.hString]
        stdcall StrClipQuotes, eax
        mov     [esi], eax
        add     esi, 4
        return
endp



proc __FontToData, .hString
begin
        push    ebx ecx edx edi

        xor     eax, eax
        mov     [esi], eax

        mov     edi, [esi+4]    ; pointer to the font parameters.

        stdcall StrSplitList, [.hString], ":", FALSE
        mov     edx, eax

        cmp     [edx+TArray.count], 4
        jne     .finish

        stdcall StrClipQuotes, [edx+TArray.array]
        stdcall StrDup, [edx+TArray.array]
        mov     [edi+__TFont.hFontFace], eax

        stdcall StrToNumEx, [edx+TArray.array+4]        ; size
        mov     [edi+__TFont.height], eax
        mov     ebx, eax

        stdcall StrToNumEx, [edx+TArray.array+8]        ; weight
        mov     [edi+__TFont.weight], eax
        mov     ecx, eax

        stdcall StrToNumEx, [edx+TArray.array+12]       ; flags
        mov     [edi+__TFont.flags], eax
        mov     edi, eax

        stdcall StrPtr, [edx+TArray.array]
        stdcall FontCreate, eax, ebx, ecx, edi

        stdcall ListFree, edx, StrDel

        mov     [esi], eax
        add     esi, 8

.finish:
        pop     edi edx ecx ebx
        return
endp



proc __PngToData, .hString
begin
        push    edx

        stdcall StrSplitList, [.hString], ":", FALSE
        mov     edx, eax

        cmp     [edx+TArray.count], 2
        jne     .finish

        stdcall DecodeBase64, [edx+TArray.array+4]

        mov     [esi+4], eax

        stdcall CreateImagePNG, eax, [eax-4]
        mov     [esi], eax

.finish:
        add     esi, 8
        pop     edx
        return
endp



proc __FileToData, .hString
begin
        push    edx

        stdcall StrSplitList, [.hString], ":", FALSE
        mov     edx, eax

        cmp     [edx+TArray.count], 2
        jne     .finish

        stdcall DecodeBase64, [edx+TArray.array+4]

        mov     [esi], eax

.finish:
        add     esi, 4
        pop     edx
        return
endp



; returns a pointer to the parameter description block: name, count, offset.

proc __SearchName, .pMeta, .hName
begin
        push    esi ecx

        mov     esi, [.pMeta]

        mov     ecx, [esi+TMetaHeader.count]
        add     esi, sizeof.TMetaHeader

.search:
        dec     ecx
        js      .not_found

        stdcall StrCompCase, [esi+TMetaField.pName], [.hName]
        jc      .found

        add     esi, sizeof.TMetaField
        jmp     .search

.not_found:
        xor     esi, esi

.found:
        mov     eax, esi
        pop     ecx esi
        return
endp




iglobal
; drawing functions.

  var DrawBox = DrawBoxDefault
  var DrawSlider = DrawSliderDefault

  var DrawSplitter = DrawSplitterDefault
endg



proc DrawBoxDefault, .pImage, .pBounds, .bkground, .border, .brd_width
begin
        pushad

        mov     esi, [.pBounds]

        mov     edx, [.border]
        and     edx, $ff
        jz      .borderok

        mov     eax, [GUI.clBorderLight]
        mov     ecx, [GUI.clBorderDark]

        test    [.border], bxDisabled
        jz      .enabled_ok

        mov     eax, [GUI.clBorderLightGray]
        mov     ecx, [GUI.clBorderDarkGray]

.enabled_ok:
        cmp     edx, bxRaised
        je      .colorok

        xchg    eax, ecx

        cmp     edx, bxSunken
        je      .colorok

        mov     eax, [GUI.clBorderNeutralGray]

        test    [.border], bxDisabled
        jnz     .flat_ok

        mov     eax, [GUI.clBorderNeutral]

.flat_ok:
        mov     ecx, eax
        cmp     edx, bxFlat
        je      .colorok

        mov     eax, [GUI.clBorderFocused]
        mov     ecx, eax

.colorok:
        mov     ebx, [.brd_width]

; left border line
        stdcall DrawSolidRect, [.pImage], [esi+TBounds.x],[esi+TBounds.y], ebx, [esi+TBounds.height], eax

; top
        add     [esi+TBounds.x], ebx
        sub     [esi+TBounds.width], ebx

        stdcall DrawSolidRect, [.pImage], [esi+TBounds.x], [esi+TBounds.y], [esi+TBounds.width], ebx, eax

; right
        sub     [esi+TBounds.width], ebx
        add     [esi+TBounds.y], ebx
        sub     [esi+TBounds.height], ebx

        mov     edx, [esi+TBounds.width]
        add     edx, [esi+TBounds.x]
        stdcall DrawSolidRect, [.pImage], edx, [esi+TBounds.y], ebx, [esi+TBounds.height], ecx

; bottom
        sub     [esi+TBounds.height], ebx

        mov     edx, [esi+TBounds.y]
        add     edx, [esi+TBounds.height]
        stdcall DrawSolidRect, [.pImage], [esi+TBounds.x], edx, [esi+TBounds.width], ebx, ecx

.borderok:
        bt      [.border], 31
        jc      .fillok

        stdcall DrawSolidRect, [.pImage], [esi+TBounds.x], [esi+TBounds.y], [esi+TBounds.width], [esi+TBounds.height], [.bkground]

.fillok:

        popad
        return
endp



sliderHorizontal = 0
sliderVertical   = 1

proc DrawSliderDefault, .pImage, .pBounds, .bkground, .type
begin
        stdcall DrawBoxDefault, [.pImage], [.pBounds], [.bkground], [scrollBorder], 2
        return
endp





proc DrawSplitterDefault, .pImage, .pRect, .type
begin
        pushad

        mov     esi, [.pRect]
        mov     eax, [esi+RECT.right]
        mov     ecx, [esi+RECT.bottom]
        sub     eax, [esi+RECT.left]
        sub     ecx, [esi+RECT.top]

        stdcall DrawSolidRect, [.pImage], [esi+RECT.left], [esi+RECT.top], eax, ecx, [GUI.clSplitter]
        popad
        return
endp


proc DrawSplitterDefault2, .pImage, .pRect, .type
.bounds TBounds
begin
        pushad

        mov     esi, [.pRect]
        mov     eax, [esi+RECT.left]
        mov     ecx, [esi+RECT.top]
        mov     edx, [esi+RECT.right]
        mov     ebx, [esi+RECT.bottom]
        sub     edx, eax
        sub     ebx, ecx
        mov     [.bounds.x], eax
        mov     [.bounds.y], ecx
        mov     [.bounds.width], edx
        mov     [.bounds.height], ebx
        lea     eax, [.bounds]

        stdcall DrawBoxDefault, [.pImage], eax, [GUI.clDialogBk], bxSunken, [GUI.boxBorderWidth]

        popad
        return
endp






endmodule





Added freshlib/gui/themes/flat_gui.asm.





















































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: This file contains procedures and data, that form the appearance of the
;               FreshLib GUI application. Colors, control borders, backgrownd drawing etc.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: The user should be able to change these settings and if he uses external
;         procedures, then the code from this library should not be compiled.
;_________________________________________________________________________________________
module "GUI theme data and code library"

; Named theme colors

; cyan
clTurquoise = $ff1abc9c
clGreenSea  = $ff16A085

; green
clEmerald   = $ff2ecc71
clNephritis = $ff27ae60

; blue

clPetermann = $ff3498db
clBelizeHole = $ff2980b9

; purple

clAmethyst = $ff9b59b6
clWisteria = $ff8e44ad

; black

clWetAsphalt = $ff34495e
clMidnight = $ff2c3e50

; gray

clConcrete = $ff95a5a6
clAsbestos = $ff7f8c8d

; light gray / white

clClouds = $ffecf0f1
clSilver = $ffbdc3c7
clWhite  = $ffffffff

; Yellow / orange

clSunflower = $fff1c40f
clOrange = $fff39c12

; Brown / orange

clCarrot = $ffe67e22
clPumpkin = $ffd35400

; Red

clAlizarin =    $ffe74c3c
clPomegranate = $ffc0392b

iglobal

        NamedArray      GUI,                                         \
\
\ ; Widgets border colors and width
                clBorderNeutral,   HEX, clTurquoise,                   \
                clBorderLight,     HEX, clTurquoise,                   \
                clBorderDark,      HEX, clTurquoise,                   \
                clBorderNeutralGray, HEX, $ff606060,                   \
                clBorderLightGray, HEX, $ff606060,                     \
                clBorderDarkGray,  HEX, $ff606060,                     \
                clBorderFocused,   HEX, clAlizarin,                    \
\
                boxBorderWidth,  NUM, 2,                             \
\
\ ; TButton colors and styles. The multivalue fields are for Neutral, Hovered and Pressed states.
\
               clBtnBk,         HEX, <clTurquoise, $ff48c9b0, clGreenSea, $807b7b7b>,   \
               clBtnTxt,        HEX, <clWhite, clWhite, clSilver, $80ffffff>,           \
               btnBorder,       NUM, <bxNone, bxNone, bxNone, bxNone>,                  \
               btnPressedOfsX,  NUM, 0,                                      \
               btnPressedOfsY,  NUM, 0,                                      \
               btnMarginX,      NUM, 8,                                      \
               btnMarginY,      NUM, 8,                                      \
\
\ ; TEdit colors and styles.
\
               clEditBk,          HEX, clClouds,                             \
               clEditBkFocused,   HEX, clClouds,                             \
               clEditTxt,         HEX, $ff000000,                            \
               clEditSel,         HEX, clBelizeHole and $00ffffff or $60000000,                         \
               clEditSelTxt,      HEX, $ffffffff,                            \
               editBorder,        NUM, bxFlat,                               \
               editBorderFocused, NUM, bxFlat,                               \
\
\ ; Dialog boxes and TForm color and styles
\
               clDialogBk,        HEX, clClouds,                             \
               clDialogTxt,       HEX, $ff000000,                            \
               clSplitter,        HEX, clWetAsphalt,                          \
\
\ ; TProgress colors and styles
\
              clProgressBk,       HEX, clClouds,                             \
              clProgressBar,      HEX, clTurquoise,                          \
              progressBorder,     NUM, bxFlat,                               \
\
\ ; TScrollbar colors and styles
\
              clScrollBk,         HEX, <clSilver and $3fffffff, clSilver and $a0ffffff>,     \
              clScrollSlider,     HEX, <clAsbestos and $7fffffff, clTurquoise>,              \
              borderScroll,       NUM, bxNone,                                               \
              scrollWidth,        NUM, 12,                                                   \
              minSliderHeight,    NUM, 12,                                                   \
\
\ ; TLabel colors and styles
\
              clLabelBk,          HEX, $00000000,                                            \
              clLabelTxt,         HEX, $ff000000,                                            \
\
\ ; TTreeView colors and styles.
\
              clTreeViewBack,     HEX, clClouds,                                             \
              clTreeViewText,     HEX, $ff000000,                                            \
              clTreeSelected,     HEX, clBelizeHole,                                         \
              clTreeSelectedTxt,  HEX, clWhite,                                              \
              clTreeFocused,      HEX, clPumpkin,                                            \
              clTreeFocusedTxt,   HEX, clWhite,                                              \
\
              tvBorder,           NUM, bxFlat,                                               \
\
              tvIcons,            PNG, <"%lib%/gui/images/treeview/right.png", "%lib%/gui/images/treeview/down.png">,     \
\
\ ; TMenu colors and styles
\
              clMenuBack,         HEX, clClouds,                                             \
              clMenuText,         HEX, $ff000000,                                            \
              clMenuTextGray,     HEX, $90000000,                                            \
              borderMenu,         NUM, bxFlat,                                               \
              menuIconMargin,     NUM, 4,                                                    \
              menuMinTextDist,    NUM, 32,                                                   \
              menuSubIcon,        PNG, "%lib%/gui/images/menu/submenu.png",                  \
              menuSubIconSel,     PNG, "%lib%/gui/images/menu/submenusel.png",               \
              menuSubIconGray,    PNG, "%lib%/gui/images/menu/submenugray.png",              \
\
\ ; Menu graphics
\
              iconMenuChecked,    PNG, "%lib%/gui/images/menu/check_flat.png",               \
              iconMenuCheckedGray, PNG, "%lib%/gui/images/menu/check_flat_gray.png",         \
\
\ ; Checkbox colors
\
              clCheckboxBack,     HEX, <$ffe0e0e0, $ffffffff, $ffc0c0c0, $80c0c0c0>,         \
              clCheckboxTxt,      HEX, $ff000000,                                            \
              clCheckboxTxtGray,  HEX, $ff606060,                                            \
              cbIconSize,         NUM, 13,                                                   \
              cbMargin,           NUM, 2,                                                    \
              borderCheckbox,     NUM, bxFlat,                                               \
              iconChecked,        PNG, "%lib%/gui/images/checkbox/check_flat.png",           \
              iconCheckedGray,    PNG, "%lib%/gui/images/checkbox/check_flat_gray.png",      \
\
\ ; Default font
\
              DefaultFont,        FONT, "Liberation Sans": 13 : fwDemibold : 0

endg






endmodule
Added freshlib/gui/themes/win_gui.asm.


































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: This file contains procedures and data, that form the appearance of the
;               FreshLib GUI application. Colors, control borders, backgrownd drawing etc.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: The user should be able to change these settings and if he uses external
;         procedures, then the code from this library should not be compiled.
;_________________________________________________________________________________________
module "GUI theme data and code library"


; Theme colors and other parameters as margins, offsets, fonts, etc.
iglobal


        NamedArray      GUI,                                    \
\
\ ; Widgets border colors and width
                clBorderNeutral, HEX, $ffa0a0a0,                     \
                clBorderLight,   HEX, $ffffffff,                     \
                clBorderDark,    HEX, $ff404040,                     \
                clBorderNeutralGray, HEX, $ff909090,                   \
                clBorderLightGray, HEX, $ffe0e0e0,                     \
                clBorderDarkGray,  HEX, $ff808080,                     \
                clBorderFocused, HEX, $ffff8000,                     \
\
                boxBorderWidth,  NUM, 1,                             \
\
\ ; TButton colors and styles. The multivalue fields are for Neutral, Hovered and Pressed states.
\
               clBtnBk,         HEX, <$ffd4d0c8, $ffe0e0e0, $ffa0a0a0, $80d4d0c8>,      \
               clBtnTxt,        HEX, <$ff000000, $ff000000, $ff000000, $ff606060>,           \
               btnBorder,       NUM, <bxRaised, bxRaised, bxSunken>,               \
               btnPressedOfsX,  NUM, 1,                                      \
               btnPressedOfsY,  NUM, 1,                                      \
               btnMarginX,      NUM, 8,                                      \
               btnMarginY,      NUM, 8,                                      \
\
\ ; TEdit colors and styles.
\
               clEditBk,          HEX, $ffffffff,                            \
               clEditBkFocused,   HEX, $ffffffff,                            \
               clEditTxt,         HEX, $ff000000,                            \
               clEditSel,         HEX, $600a246c,                            \
               clEditSelTxt,      HEX, $ffffffff,                            \
               editBorder,        NUM, bxSunken,                             \
               editBorderFocused, NUM, bxSunken,                             \
\
\ ; Dialog boxes and TForm color and styles
\
               clDialogBk,        HEX, $ffd4d0c8,                            \
               clDialogTxt,       HEX, $ff000000,                            \
               clSplitter,        HEX, $ff606060,                            \
\
\ ; TProgress colors and styles
\
              clProgressBk,       HEX, $ffd4d0c8,                            \
              clProgressBar,      HEX, $ff0a246c,                            \
              progressBorder,     NUM, bxSunken,                             \
\
\ ; TScrollbar colors and styles
\
              clScrollBk,         HEX, <$3f808080, $a0d4d0c8>,                               \
              clScrollSlider,     HEX, <$7fd4d0c8, $ffd4d0c8>,                               \
              borderScroll,       NUM, bxRaised,                                             \
              scrollWidth,        NUM, 16,                                                   \
              minSliderHeight,    NUM, 16,                                                   \
\
\ ; TLabel colors and styles
\
              clLabelBk,          HEX, $00ffffff,                                            \
              clLabelTxt,         HEX, $ff000000,                                            \
\
\ ; TTreeView colors and styles.
\
              clTreeViewBack,     HEX, $ffffffff,                                            \
              clTreeViewText,     HEX, $ff000000,                                            \
              clTreeSelected,     HEX, $ff0a246c,                                            \
              clTreeSelectedTxt,  HEX, $ffffffff,                                            \
              clTreeFocused,      HEX, $ff0a246c,                                            \
              clTreeFocusedTxt,   HEX, $ffffff00,                                            \
\
              tvBorder,           NUM, bxSunken,                                             \
\
              tvIcons,            PNG, <"%lib%/gui/images/treeview/plus.png", "%lib%/gui/images/treeview/minus.png">,     \
\
\ ; TMenu colors and styles
\
              clMenuBack,         HEX, $ffd4d0c8,                                            \
              clMenuText,         HEX, $ff000000,                                            \
              clMenuTextGray,     HEX, $80000000,                                            \
              borderMenu,         NUM, bxRaised,                                             \
              menuIconMargin,     NUM, 4,                                                    \
              menuMinTextDist,    NUM, 32,                                                   \
              menuSubIcon,        PNG, "%lib%/gui/images/menu/submenu.png",                  \
              menuSubIconSel,     PNG, "%lib%/gui/images/menu/submenusel.png",               \
              menuSubIconGray,    PNG, "%lib%/gui/images/menu/submenugray.png",              \
\
\ ; Menu graphics
\
              iconMenuChecked,    PNG, "%lib%/gui/images/menu/check.png",                    \
              iconMenuCheckedGray,PNG, "%lib%/gui/images/menu/check_gray.png",               \
\
\ ; Checkbox colors
\
              clCheckboxBack,     HEX, <$ffffffff, $ffffffff, $ffffffff, $ffc0c0c0>,         \
              clCheckboxTxt,      HEX, $ff000000,                                            \
              clCheckboxTxtGray,  HEX, $ff808080,                                            \
              cbIconSize,         NUM, 13,                                                   \
              cbMargin,           NUM, 2,                                                    \
              borderCheckbox,     NUM, bxSunken,                                             \
              iconChecked,        PNG, "%lib%/gui/images/checkbox/check.png",                \
              iconCheckedGray,    PNG, "%lib%/gui/images/checkbox/check_gray.png",           \
\
\ ; Default font
\
              DefaultFont,        FONT, "Liberation Sans":13:fwNormal:0

endg



endmodule
Changes to freshlib/imports/Linux/libFC.inc.
11
12
13
14
15
16
17


18
19
20
21
22
23
24
25
26
27
28
29


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

31
32







+
+











-
+
+
;
;  Notes:
;_________________________________________________________________________________________



import_proto 'libfontconfig.so.1',                                                                              \
             FcInit,                   <VOID>,                          'FcInit',                               \
             FcFini,                   <VOID>,                          'FcFini',                               \
             FcInitLoadConfigAndFonts, <VOID>,                          'FcInitLoadConfigAndFonts',             \
             FcPatternCreate,          <VOID>,                          'FcPatternCreate',                      \
             FcObjectSetBuild,         <.first, ...>,                   'FcObjectSetBuild',                     \
             FcFontList,               <.config, .pPattern, .ObjSet>,   'FcFontList',                           \
             FcPatternGetString,       <.pPattern, .obj, .n, .pBuffer>, 'FcPatternGetString',                   \
             FcPatternGetInteger,      <.pPattern, .obj, .n, .pInt>,    'FcPatternGetInteger',                  \
             FcFontSetDestroy,         <.pFontSet>,                     'FcFontSetDestroy',                     \
             FcNameParse,              <.name>,                         'FcNameParse',                          \
             FcConfigSubstitute,       <.config, .pattern, .matchkind>, 'FcConfigSubstitute',                   \
             FcDefaultSubstitute,      <.pattern>,                      'FcDefaultSubstitute',                  \
             FcFontMatch,              <.config, .pattern, .pResult>,   'FcFontMatch',                          \
             FcPatternDestroy,         <.pattern>,                      'FcPatternDestroy'
             FcPatternDestroy,         <.pattern>,                      'FcPatternDestroy',                     \
             FcPatternPrint,           <.pattern>,                      'FcPatternPrint'
Changes to freshlib/imports/Linux/libFT.inc.
30
31
32
33
34
35
36


37
38
39
40
41
42
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44







+
+






                                  .max_bytes, .requester, .req_data, .pManager>, 'FTC_Manager_New',                         \
             FTC_Manager_LookupFace, <.manager, .face_id, .pFace>,           'FTC_Manager_LookupFace',                      \
             FTC_Manager_LookupSize, <.manager, .scaler, .pSize>,            'FTC_Manager_LookupSize',                      \
             FTC_Manager_RemoveFaceID, <.manager, .face_id>,                 'FTC_Manager_RemoveFaceID',                    \
             FTC_ImageCache_New, <.manager, .pImageCache>,                   'FTC_ImageCache_New',                          \
             FTC_ImageCache_Lookup, <.cache, .type, .glyph_index,                                                           \
                                     .pGlyph, .pNode>,                       'FTC_ImageCache_Lookup',                       \
             FTC_ImageCache_LookupScaler, <.cache, .scaler, .load_flags,                                                    \
                                           .gindex, .pGlyph, .pNode>,        'FTC_ImageCache_LookupScaler',                 \
             FTC_CMapCache_New,  <.manager, .pCMapCache>,                    'FTC_CMapCache_New',                           \
             FTC_CMapCache_Lookup, <.cache, .face_id, .cmap_index, .char_code>, 'FTC_CMapCache_Lookup'




Changes to freshlib/imports/Linux/libX11.inc.
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89







-
+










-
+



















-
+







        XBlackPixelOfScreen                     ,<NONE>,                                    'XBlackPixelOfScreen',                                      \
        XCellsOfScreen                          ,<NONE>,                                    'XCellsOfScreen',                                           \
        XChangeActivePointerGrab                ,<NONE>,                                    'XChangeActivePointerGrab',                                 \
        XChangeGC                               ,<NONE>,                                    'XChangeGC',                                                \
        XChangeKeyboardControl                  ,<NONE>,                                    'XChangeKeyboardControl',                                   \
        XChangeKeyboardMapping                  ,<NONE>,                                    'XChangeKeyboardMapping',                                   \
        XChangePointerControl                   ,<NONE>,                                    'XChangePointerControl',                                    \
        XChangeProperty                         ,<NONE>,                                    'XChangeProperty',                                          \
        XChangeProperty                         ,<.display, .wnd, .property, .type, .format, .mode, .pData, .n_elements>, 'XChangeProperty',            \
        XChangeSaveSet                          ,<NONE>,                                    'XChangeSaveSet',                                           \
        XChangeWindowAttributes                 ,<.display, .hwnd, .valmask, .pSetWinAttr>, 'XChangeWindowAttributes',                                  \
        XCheckIfEvent                           ,<NONE>,                                    'XCheckIfEvent',                                            \
        XCheckMaskEvent                         ,<NONE>,                                    'XCheckMaskEvent',                                          \
        XCheckTypedEvent                        ,<.display, .event_type, .pEvent>,          'XCheckTypedEvent',                                         \
        XCheckTypedWindowEvent                  ,<NONE>,                                    'XCheckTypedWindowEvent',                                   \
        XCheckWindowEvent                       ,<NONE>,                                    'XCheckWindowEvent',                                        \
        XCirculateSubwindows                    ,<NONE>,                                    'XCirculateSubwindows',                                     \
        XCirculateSubwindowsDown                ,<NONE>,                                    'XCirculateSubwindowsDown',                                 \
        XCirculateSubwindowsUp                  ,<NONE>,                                    'XCirculateSubwindowsUp',                                   \
        XClearArea                              ,<NONE>,                                    'XClearArea',                                               \
        XClearArea                              ,<.display, .window, .x, .y, .width, .height, .exposures>, 'XClearArea',                                               \
        XClearWindow                            ,<NONE>,                                    'XClearWindow',                                             \
        XClipBox                                ,<NONE>,                                    'XClipBox',                                                 \
        XCloseDisplay                           ,<NONE>,                                    'XCloseDisplay',                                            \
        XCloseIM                                ,<NONE>,                                    'XCloseIM',                                                 \
        XCloseOM                                ,<NONE>,                                    'XCloseOM',                                                 \
        XConfigureWindow                        ,<NONE>,                                    'XConfigureWindow',                                         \
        XConnectionNumber                       ,<NONE>,                                    'XConnectionNumber',                                        \
        XContextDependentDrawing                ,<NONE>,                                    'XContextDependentDrawing',                                 \
        XContextualDrawing                      ,<NONE>,                                    'XContextualDrawing',                                       \
        XConvertCase                            ,<NONE>,                                    'XConvertCase',                                             \
        XConvertSelection                       ,<.display, .selection, .target, .property, .requestor, .time>, 'XConvertSelection',                    \
        XCopyArea                               ,<NONE>,                                                'XCopyArea',                                    \
        XCopyColormapAndFree                    ,<NONE>,                                                'XCopyColormapAndFree',                         \
        XCopyGC                                 ,<NONE>,                                                'XCopyGC',                                      \
        XCopyPlane                              ,<NONE>,                                                'XCopyPlane',                                   \
        XCreateBitmapFromData                   ,<NONE>,                                                'XCreateBitmapFromData',                        \
        XCreateColormap                         ,<NONE>,                                                'XCreateColormap',                              \
        XCreateFontCursor                       ,<NONE>,                                                'XCreateFontCursor',                            \
        XCreateFontSet                          ,<NONE>,                                                'XCreateFontSet',                               \
        XCreateGC                               ,<NONE>,                                                'XCreateGC',                                    \
        XCreateGC                               ,<.display, .drawable, .mask, .pValues>,                'XCreateGC',                                    \
        XCreateGlyphCursor                      ,<NONE>,                                                'XCreateGlyphCursor',                           \
        XCreateIC                               ,<NONE>,                                                'XCreateIC',                                    \
        XCreateImage                            ,<NONE>,                                                'XCreateImage',                                 \
        XCreateOC                               ,<NONE>,                                                'XCreateOC',                                    \
        XCreatePixmap                           ,<NONE>,                                                'XCreatePixmap',                                \
        XCreatePixmapCursor                     ,<NONE>,                                                'XCreatePixmapCursor',                          \
        XCreatePixmapFromBitmapData             ,<NONE>,                                                'XCreatePixmapFromBitmapData',                  \
Added freshlib/imports/Win32/gdiplus.inc.
























































































































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
;   gdiplus.dll API calls (ASCII) 
import_proto gdiplus,  \
    GdipAddPathArc, <NONE>,  'GdipAddPathArc',  \
    GdipAddPathArcI, <NONE>,  'GdipAddPathArcI',  \
    GdipAddPathBezier, <NONE>,  'GdipAddPathBezier',  \
    GdipAddPathBezierI, <NONE>,  'GdipAddPathBezierI',  \
    GdipAddPathBeziers, <NONE>,  'GdipAddPathBeziers',  \
    GdipAddPathBeziersI, <NONE>,  'GdipAddPathBeziersI',  \
    GdipAddPathClosedCurve, <NONE>,  'GdipAddPathClosedCurve',  \
    GdipAddPathClosedCurve2, <NONE>,  'GdipAddPathClosedCurve2',  \
    GdipAddPathClosedCurve2I, <NONE>,  'GdipAddPathClosedCurve2I',  \
    GdipAddPathClosedCurveI, <NONE>,  'GdipAddPathClosedCurveI',  \
    GdipAddPathCurve, <NONE>,  'GdipAddPathCurve',  \
    GdipAddPathCurve2, <NONE>,  'GdipAddPathCurve2',  \
    GdipAddPathCurve2I, <NONE>,  'GdipAddPathCurve2I',  \
    GdipAddPathCurve3, <NONE>,  'GdipAddPathCurve3',  \
    GdipAddPathCurve3I, <NONE>,  'GdipAddPathCurve3I',  \
    GdipAddPathCurveI, <NONE>,  'GdipAddPathCurveI',  \
    GdipAddPathEllipse, <NONE>,  'GdipAddPathEllipse',  \
    GdipAddPathEllipseI, <NONE>,  'GdipAddPathEllipseI',  \
    GdipAddPathLine, <NONE>,  'GdipAddPathLine',  \
    GdipAddPathLine2, <NONE>,  'GdipAddPathLine2',  \
    GdipAddPathLine2I, <NONE>,  'GdipAddPathLine2I',  \
    GdipAddPathLineI, <NONE>,  'GdipAddPathLineI',  \
    GdipAddPathPath, <NONE>,  'GdipAddPathPath',  \
    GdipAddPathPie, <NONE>,  'GdipAddPathPie',  \
    GdipAddPathPieI, <NONE>,  'GdipAddPathPieI',  \
    GdipAddPathPolygon, <NONE>,  'GdipAddPathPolygon',  \
    GdipAddPathPolygonI, <NONE>,  'GdipAddPathPolygonI',  \
    GdipAddPathRectangle, <NONE>,  'GdipAddPathRectangle',  \
    GdipAddPathRectangleI, <NONE>,  'GdipAddPathRectangleI',  \
    GdipAddPathRectangles, <NONE>,  'GdipAddPathRectangles',  \
    GdipAddPathRectanglesI, <NONE>,  'GdipAddPathRectanglesI',  \
    GdipAddPathString, <NONE>,  'GdipAddPathString',  \
    GdipAddPathStringI, <NONE>,  'GdipAddPathStringI',  \
    GdipAlloc, <NONE>,  'GdipAlloc',  \
    GdipBeginContainer, <NONE>,  'GdipBeginContainer',  \
    GdipBeginContainer2, <NONE>,  'GdipBeginContainer2',  \
    GdipBeginContainerI, <NONE>,  'GdipBeginContainerI',  \
    GdipBitmapApplyEffect, <NONE>,  'GdipBitmapApplyEffect',  \
    GdipBitmapConvertFormat, <NONE>,  'GdipBitmapConvertFormat',  \
    GdipBitmapCreateApplyEffect, <NONE>,  'GdipBitmapCreateApplyEffect',  \
    GdipBitmapGetHistogram, <NONE>,  'GdipBitmapGetHistogram',  \
    GdipBitmapGetHistogramSize, <NONE>,  'GdipBitmapGetHistogramSize',  \
    GdipBitmapGetPixel, <NONE>,  'GdipBitmapGetPixel',  \
    GdipBitmapLockBits, <NONE>,  'GdipBitmapLockBits',  \
    GdipBitmapSetPixel, <NONE>,  'GdipBitmapSetPixel',  \
    GdipBitmapSetResolution, <NONE>,  'GdipBitmapSetResolution',  \
    GdipBitmapUnlockBits, <NONE>,  'GdipBitmapUnlockBits',  \
    GdipClearPathMarkers, <NONE>,  'GdipClearPathMarkers',  \
    GdipCloneBitmapArea, <NONE>,  'GdipCloneBitmapArea',  \
    GdipCloneBitmapAreaI, <NONE>,  'GdipCloneBitmapAreaI',  \
    GdipCloneBrush, <NONE>,  'GdipCloneBrush',  \
    GdipCloneCustomLineCap, <NONE>,  'GdipCloneCustomLineCap',  \
    GdipCloneFont, <NONE>,  'GdipCloneFont',  \
    GdipCloneFontFamily, <NONE>,  'GdipCloneFontFamily',  \
    GdipCloneImage, <NONE>,  'GdipCloneImage',  \
    GdipCloneImageAttributes, <NONE>,  'GdipCloneImageAttributes',  \
    GdipCloneMatrix, <NONE>,  'GdipCloneMatrix',  \
    GdipClonePath, <NONE>,  'GdipClonePath',  \
    GdipClonePen, <NONE>,  'GdipClonePen',  \
    GdipCloneRegion, <NONE>,  'GdipCloneRegion',  \
    GdipCloneStringFormat, <NONE>,  'GdipCloneStringFormat',  \
    GdipClosePathFigure, <NONE>,  'GdipClosePathFigure',  \
    GdipClosePathFigures, <NONE>,  'GdipClosePathFigures',  \
    GdipCombineRegionPath, <NONE>,  'GdipCombineRegionPath',  \
    GdipCombineRegionRect, <NONE>,  'GdipCombineRegionRect',  \
    GdipCombineRegionRectI, <NONE>,  'GdipCombineRegionRectI',  \
    GdipCombineRegionRegion, <NONE>,  'GdipCombineRegionRegion',  \
    GdipComment, <NONE>,  'GdipComment',  \
    GdipConvertToEmfPlus, <NONE>,  'GdipConvertToEmfPlus',  \
    GdipConvertToEmfPlusToFile, <NONE>,  'GdipConvertToEmfPlusToFile',  \
    GdipConvertToEmfPlusToStream, <NONE>,  'GdipConvertToEmfPlusToStream',  \
    GdipCreateAdjustableArrowCap, <NONE>,  'GdipCreateAdjustableArrowCap',  \
    GdipCreateBitmapFromDirectDrawSurface, <NONE>,  'GdipCreateBitmapFromDirectDrawSurface',  \
    GdipCreateBitmapFromFile, <NONE>,  'GdipCreateBitmapFromFile',  \
    GdipCreateBitmapFromFileICM, <NONE>,  'GdipCreateBitmapFromFileICM',  \
    GdipCreateBitmapFromGdiDib, <NONE>,  'GdipCreateBitmapFromGdiDib',  \
    GdipCreateBitmapFromGraphics, <NONE>,  'GdipCreateBitmapFromGraphics',  \
    GdipCreateBitmapFromHBITMAP, <NONE>,  'GdipCreateBitmapFromHBITMAP',  \
    GdipCreateBitmapFromHICON, <NONE>,  'GdipCreateBitmapFromHICON',  \
    GdipCreateBitmapFromResource, <NONE>,  'GdipCreateBitmapFromResource',  \
    GdipCreateBitmapFromScan0, <NONE>,  'GdipCreateBitmapFromScan0',  \
    GdipCreateBitmapFromStream, <NONE>,  'GdipCreateBitmapFromStream',  \
    GdipCreateBitmapFromStreamICM, <NONE>,  'GdipCreateBitmapFromStreamICM',  \
    GdipCreateCachedBitmap, <NONE>,  'GdipCreateCachedBitmap',  \
    GdipCreateCustomLineCap, <NONE>,  'GdipCreateCustomLineCap',  \
    GdipCreateEffect, <NONE>,  'GdipCreateEffect',  \
    GdipCreateFont, <NONE>,  'GdipCreateFont',  \
    GdipCreateFontFamilyFromName, <NONE>,  'GdipCreateFontFamilyFromName',  \
    GdipCreateFontFromDC, <NONE>,  'GdipCreateFontFromDC',  \
    GdipCreateFontFromLogfontA, <NONE>,  'GdipCreateFontFromLogfontA',  \
    GdipCreateFontFromLogfontW, <NONE>,  'GdipCreateFontFromLogfontW',  \
    GdipCreateFromHDC, <NONE>,  'GdipCreateFromHDC',  \
    GdipCreateFromHDC2, <NONE>,  'GdipCreateFromHDC2',  \
    GdipCreateFromHWND, <NONE>,  'GdipCreateFromHWND',  \
    GdipCreateFromHWNDICM, <NONE>,  'GdipCreateFromHWNDICM',  \
    GdipCreateHBITMAPFromBitmap, <NONE>,  'GdipCreateHBITMAPFromBitmap',  \
    GdipCreateHICONFromBitmap, <NONE>,  'GdipCreateHICONFromBitmap',  \
    GdipCreateHalftonePalette, <NONE>,  'GdipCreateHalftonePalette',  \
    GdipCreateHatchBrush, <NONE>,  'GdipCreateHatchBrush',  \
    GdipCreateImageAttributes, <NONE>,  'GdipCreateImageAttributes',  \
    GdipCreateLineBrush, <NONE>,  'GdipCreateLineBrush',  \
    GdipCreateLineBrushFromRect, <NONE>,  'GdipCreateLineBrushFromRect',  \
    GdipCreateLineBrushFromRectI, <NONE>,  'GdipCreateLineBrushFromRectI',  \
    GdipCreateLineBrushFromRectWithAngle, <NONE>,  'GdipCreateLineBrushFromRectWithAngle',  \
    GdipCreateLineBrushFromRectWithAngleI, <NONE>,  'GdipCreateLineBrushFromRectWithAngleI',  \
    GdipCreateLineBrushI, <NONE>,  'GdipCreateLineBrushI',  \
    GdipCreateMatrix, <NONE>,  'GdipCreateMatrix',  \
    GdipCreateMatrix2, <NONE>,  'GdipCreateMatrix2',  \
    GdipCreateMatrix3, <NONE>,  'GdipCreateMatrix3',  \
    GdipCreateMatrix3I, <NONE>,  'GdipCreateMatrix3I',  \
    GdipCreateMetafileFromEmf, <NONE>,  'GdipCreateMetafileFromEmf',  \
    GdipCreateMetafileFromFile, <NONE>,  'GdipCreateMetafileFromFile',  \
    GdipCreateMetafileFromStream, <NONE>,  'GdipCreateMetafileFromStream',  \
    GdipCreateMetafileFromWmf, <NONE>,  'GdipCreateMetafileFromWmf',  \
    GdipCreateMetafileFromWmfFile, <NONE>,  'GdipCreateMetafileFromWmfFile',  \
    GdipCreatePath, <NONE>,  'GdipCreatePath',  \
    GdipCreatePath2, <NONE>,  'GdipCreatePath2',  \
    GdipCreatePath2I, <NONE>,  'GdipCreatePath2I',  \
    GdipCreatePathGradient, <NONE>,  'GdipCreatePathGradient',  \
    GdipCreatePathGradientFromPath, <NONE>,  'GdipCreatePathGradientFromPath',  \
    GdipCreatePathGradientI, <NONE>,  'GdipCreatePathGradientI',  \
    GdipCreatePathIter, <NONE>,  'GdipCreatePathIter',  \
    GdipCreatePen1, <NONE>,  'GdipCreatePen1',  \
    GdipCreatePen2, <NONE>,  'GdipCreatePen2',  \
    GdipCreateRegion, <NONE>,  'GdipCreateRegion',  \
    GdipCreateRegionHrgn, <NONE>,  'GdipCreateRegionHrgn',  \
    GdipCreateRegionPath, <NONE>,  'GdipCreateRegionPath',  \
    GdipCreateRegionRect, <NONE>,  'GdipCreateRegionRect',  \
    GdipCreateRegionRectI, <NONE>,  'GdipCreateRegionRectI',  \
    GdipCreateRegionRgnData, <NONE>,  'GdipCreateRegionRgnData',  \
    GdipCreateSolidFill, <NONE>,  'GdipCreateSolidFill',  \
    GdipCreateStreamOnFile, <NONE>,  'GdipCreateStreamOnFile',  \
    GdipCreateStringFormat, <NONE>,  'GdipCreateStringFormat',  \
    GdipCreateTexture, <NONE>,  'GdipCreateTexture',  \
    GdipCreateTexture2, <NONE>,  'GdipCreateTexture2',  \
    GdipCreateTexture2I, <NONE>,  'GdipCreateTexture2I',  \
    GdipCreateTextureIA, <NONE>,  'GdipCreateTextureIA',  \
    GdipCreateTextureIAI, <NONE>,  'GdipCreateTextureIAI',  \
    GdipDeleteBrush, <NONE>,  'GdipDeleteBrush',  \
    GdipDeleteCachedBitmap, <NONE>,  'GdipDeleteCachedBitmap',  \
    GdipDeleteCustomLineCap, <NONE>,  'GdipDeleteCustomLineCap',  \
    GdipDeleteEffect, <NONE>,  'GdipDeleteEffect',  \
    GdipDeleteFont, <NONE>,  'GdipDeleteFont',  \
    GdipDeleteFontFamily, <NONE>,  'GdipDeleteFontFamily',  \
    GdipDeleteGraphics, <NONE>,  'GdipDeleteGraphics',  \
    GdipDeleteMatrix, <NONE>,  'GdipDeleteMatrix',  \
    GdipDeletePath, <NONE>,  'GdipDeletePath',  \
    GdipDeletePathIter, <NONE>,  'GdipDeletePathIter',  \
    GdipDeletePen, <NONE>,  'GdipDeletePen',  \
    GdipDeletePrivateFontCollection, <NONE>,  'GdipDeletePrivateFontCollection',  \
    GdipDeleteRegion, <NONE>,  'GdipDeleteRegion',  \
    GdipDeleteStringFormat, <NONE>,  'GdipDeleteStringFormat',  \
    GdipDisposeImage, <NONE>,  'GdipDisposeImage',  \
    GdipDisposeImageAttributes, <NONE>,  'GdipDisposeImageAttributes',  \
    GdipDrawArc, <NONE>,  'GdipDrawArc',  \
    GdipDrawArcI, <NONE>,  'GdipDrawArcI',  \
    GdipDrawBezier, <NONE>,  'GdipDrawBezier',  \
    GdipDrawBezierI, <NONE>,  'GdipDrawBezierI',  \
    GdipDrawBeziers, <NONE>,  'GdipDrawBeziers',  \
    GdipDrawBeziersI, <NONE>,  'GdipDrawBeziersI',  \
    GdipDrawCachedBitmap, <NONE>,  'GdipDrawCachedBitmap',  \
    GdipDrawClosedCurve, <NONE>,  'GdipDrawClosedCurve',  \
    GdipDrawClosedCurve2, <NONE>,  'GdipDrawClosedCurve2',  \
    GdipDrawClosedCurve2I, <NONE>,  'GdipDrawClosedCurve2I',  \
    GdipDrawClosedCurveI, <NONE>,  'GdipDrawClosedCurveI',  \
    GdipDrawCurve, <NONE>,  'GdipDrawCurve',  \
    GdipDrawCurve2, <NONE>,  'GdipDrawCurve2',  \
    GdipDrawCurve2I, <NONE>,  'GdipDrawCurve2I',  \
    GdipDrawCurve3, <NONE>,  'GdipDrawCurve3',  \
    GdipDrawCurve3I, <NONE>,  'GdipDrawCurve3I',  \
    GdipDrawCurveI, <NONE>,  'GdipDrawCurveI',  \
    GdipDrawDriverString, <NONE>,  'GdipDrawDriverString',  \
    GdipDrawEllipse, <NONE>,  'GdipDrawEllipse',  \
    GdipDrawEllipseI, <NONE>,  'GdipDrawEllipseI',  \
    GdipDrawImage, <NONE>,  'GdipDrawImage',  \
    GdipDrawImageFX, <NONE>,  'GdipDrawImageFX',  \
    GdipDrawImageI, <NONE>,  'GdipDrawImageI',  \
    GdipDrawImagePointRect, <NONE>,  'GdipDrawImagePointRect',  \
    GdipDrawImagePointRectI, <NONE>,  'GdipDrawImagePointRectI',  \
    GdipDrawImagePoints, <NONE>,  'GdipDrawImagePoints',  \
    GdipDrawImagePointsI, <NONE>,  'GdipDrawImagePointsI',  \
    GdipDrawImagePointsRect, <NONE>,  'GdipDrawImagePointsRect',  \
    GdipDrawImagePointsRectI, <NONE>,  'GdipDrawImagePointsRectI',  \
    GdipDrawImageRect, <NONE>,  'GdipDrawImageRect',  \
    GdipDrawImageRectI, <NONE>,  'GdipDrawImageRectI',  \
    GdipDrawImageRectRect, <NONE>,  'GdipDrawImageRectRect',  \
    GdipDrawImageRectRectI, <NONE>,  'GdipDrawImageRectRectI',  \
    GdipDrawLine, <NONE>,  'GdipDrawLine',  \
    GdipDrawLineI, <NONE>,  'GdipDrawLineI',  \
    GdipDrawLines, <NONE>,  'GdipDrawLines',  \
    GdipDrawLinesI, <NONE>,  'GdipDrawLinesI',  \
    GdipDrawPath, <NONE>,  'GdipDrawPath',  \
    GdipDrawPie, <NONE>,  'GdipDrawPie',  \
    GdipDrawPieI, <NONE>,  'GdipDrawPieI',  \
    GdipDrawPolygon, <NONE>,  'GdipDrawPolygon',  \
    GdipDrawPolygonI, <NONE>,  'GdipDrawPolygonI',  \
    GdipDrawRectangle, <NONE>,  'GdipDrawRectangle',  \
    GdipDrawRectangleI, <NONE>,  'GdipDrawRectangleI',  \
    GdipDrawRectangles, <NONE>,  'GdipDrawRectangles',  \
    GdipDrawRectanglesI, <NONE>,  'GdipDrawRectanglesI',  \
    GdipDrawString, <NONE>,  'GdipDrawString',  \
    GdipEmfToWmfBits, <NONE>,  'GdipEmfToWmfBits',  \
    GdipEndContainer, <NONE>,  'GdipEndContainer',  \
    GdipEnumerateMetafileDestPoint, <NONE>,  'GdipEnumerateMetafileDestPoint',  \
    GdipEnumerateMetafileDestPointI, <NONE>,  'GdipEnumerateMetafileDestPointI',  \
    GdipEnumerateMetafileDestPoints, <NONE>,  'GdipEnumerateMetafileDestPoints',  \
    GdipEnumerateMetafileDestPointsI, <NONE>,  'GdipEnumerateMetafileDestPointsI',  \
    GdipEnumerateMetafileDestRect, <NONE>,  'GdipEnumerateMetafileDestRect',  \
    GdipEnumerateMetafileDestRectI, <NONE>,  'GdipEnumerateMetafileDestRectI',  \
    GdipEnumerateMetafileSrcRectDestPoint, <NONE>,  'GdipEnumerateMetafileSrcRectDestPoint',  \
    GdipEnumerateMetafileSrcRectDestPointI, <NONE>,  'GdipEnumerateMetafileSrcRectDestPointI',  \
    GdipEnumerateMetafileSrcRectDestPoints, <NONE>,  'GdipEnumerateMetafileSrcRectDestPoints',  \
    GdipEnumerateMetafileSrcRectDestPointsI, <NONE>,  'GdipEnumerateMetafileSrcRectDestPointsI',  \
    GdipEnumerateMetafileSrcRectDestRect, <NONE>,  'GdipEnumerateMetafileSrcRectDestRect',  \
    GdipEnumerateMetafileSrcRectDestRectI, <NONE>,  'GdipEnumerateMetafileSrcRectDestRectI',  \
    GdipFillClosedCurve, <NONE>,  'GdipFillClosedCurve',  \
    GdipFillClosedCurve2, <NONE>,  'GdipFillClosedCurve2',  \
    GdipFillClosedCurve2I, <NONE>,  'GdipFillClosedCurve2I',  \
    GdipFillClosedCurveI, <NONE>,  'GdipFillClosedCurveI',  \
    GdipFillEllipse, <NONE>,  'GdipFillEllipse',  \
    GdipFillEllipseI, <NONE>,  'GdipFillEllipseI',  \
    GdipFillPath, <NONE>,  'GdipFillPath',  \
    GdipFillPie, <NONE>,  'GdipFillPie',  \
    GdipFillPieI, <NONE>,  'GdipFillPieI',  \
    GdipFillPolygon, <NONE>,  'GdipFillPolygon',  \
    GdipFillPolygon2, <NONE>,  'GdipFillPolygon2',  \
    GdipFillPolygon2I, <NONE>,  'GdipFillPolygon2I',  \
    GdipFillPolygonI, <NONE>,  'GdipFillPolygonI',  \
    GdipFillRectangle, <NONE>,  'GdipFillRectangle',  \
    GdipFillRectangleI, <NONE>,  'GdipFillRectangleI',  \
    GdipFillRectangles, <NONE>,  'GdipFillRectangles',  \
    GdipFillRectanglesI, <NONE>,  'GdipFillRectanglesI',  \
    GdipFillRegion, <NONE>,  'GdipFillRegion',  \
    GdipFindFirstImageItem, <NONE>,  'GdipFindFirstImageItem',  \
    GdipFindNextImageItem, <NONE>,  'GdipFindNextImageItem',  \
    GdipFlattenPath, <NONE>,  'GdipFlattenPath',  \
    GdipFlush, <NONE>,  'GdipFlush',  \
    GdipFree, <NONE>,  'GdipFree',  \
    GdipGetAdjustableArrowCapFillState, <NONE>,  'GdipGetAdjustableArrowCapFillState',  \
    GdipGetAdjustableArrowCapHeight, <NONE>,  'GdipGetAdjustableArrowCapHeight',  \
    GdipGetAdjustableArrowCapMiddleInset, <NONE>,  'GdipGetAdjustableArrowCapMiddleInset',  \
    GdipGetAdjustableArrowCapWidth, <NONE>,  'GdipGetAdjustableArrowCapWidth',  \
    GdipGetAllPropertyItems, <NONE>,  'GdipGetAllPropertyItems',  \
    GdipGetBrushType, <NONE>,  'GdipGetBrushType',  \
    GdipGetCellAscent, <NONE>,  'GdipGetCellAscent',  \
    GdipGetCellDescent, <NONE>,  'GdipGetCellDescent',  \
    GdipGetClip, <NONE>,  'GdipGetClip',  \
    GdipGetClipBounds, <NONE>,  'GdipGetClipBounds',  \
    GdipGetClipBoundsI, <NONE>,  'GdipGetClipBoundsI',  \
    GdipGetCompositingMode, <NONE>,  'GdipGetCompositingMode',  \
    GdipGetCompositingQuality, <NONE>,  'GdipGetCompositingQuality',  \
    GdipGetCustomLineCapBaseCap, <NONE>,  'GdipGetCustomLineCapBaseCap',  \
    GdipGetCustomLineCapBaseInset, <NONE>,  'GdipGetCustomLineCapBaseInset',  \
    GdipGetCustomLineCapStrokeCaps, <NONE>,  'GdipGetCustomLineCapStrokeCaps',  \
    GdipGetCustomLineCapStrokeJoin, <NONE>,  'GdipGetCustomLineCapStrokeJoin',  \
    GdipGetCustomLineCapType, <NONE>,  'GdipGetCustomLineCapType',  \
    GdipGetCustomLineCapWidthScale, <NONE>,  'GdipGetCustomLineCapWidthScale',  \
    GdipGetDC, <NONE>,  'GdipGetDC',  \
    GdipGetDpiX, <NONE>,  'GdipGetDpiX',  \
    GdipGetDpiY, <NONE>,  'GdipGetDpiY',  \
    GdipGetEffectParameterSize, <NONE>,  'GdipGetEffectParameterSize',  \
    GdipGetEffectParameters, <NONE>,  'GdipGetEffectParameters',  \
    GdipGetEmHeight, <NONE>,  'GdipGetEmHeight',  \
    GdipGetEncoderParameterList, <NONE>,  'GdipGetEncoderParameterList',  \
    GdipGetEncoderParameterListSize, <NONE>,  'GdipGetEncoderParameterListSize',  \
    GdipGetFamily, <NONE>,  'GdipGetFamily',  \
    GdipGetFamilyName, <NONE>,  'GdipGetFamilyName',  \
    GdipGetFontCollectionFamilyCount, <NONE>,  'GdipGetFontCollectionFamilyCount',  \
    GdipGetFontCollectionFamilyList, <NONE>,  'GdipGetFontCollectionFamilyList',  \
    GdipGetFontHeight, <NONE>,  'GdipGetFontHeight',  \
    GdipGetFontHeightGivenDPI, <NONE>,  'GdipGetFontHeightGivenDPI',  \
    GdipGetFontSize, <NONE>,  'GdipGetFontSize',  \
    GdipGetFontStyle, <NONE>,  'GdipGetFontStyle',  \
    GdipGetFontUnit, <NONE>,  'GdipGetFontUnit',  \
    GdipGetGenericFontFamilyMonospace, <NONE>,  'GdipGetGenericFontFamilyMonospace',  \
    GdipGetGenericFontFamilySansSerif, <NONE>,  'GdipGetGenericFontFamilySansSerif',  \
    GdipGetGenericFontFamilySerif, <NONE>,  'GdipGetGenericFontFamilySerif',  \
    GdipGetHatchBackgroundColor, <NONE>,  'GdipGetHatchBackgroundColor',  \
    GdipGetHatchForegroundColor, <NONE>,  'GdipGetHatchForegroundColor',  \
    GdipGetHatchStyle, <NONE>,  'GdipGetHatchStyle',  \
    GdipGetHemfFromMetafile, <NONE>,  'GdipGetHemfFromMetafile',  \
    GdipGetImageAttributesAdjustedPalette, <NONE>,  'GdipGetImageAttributesAdjustedPalette',  \
    GdipGetImageBounds, <NONE>,  'GdipGetImageBounds',  \
    GdipGetImageDecoders, <NONE>,  'GdipGetImageDecoders',  \
    GdipGetImageDecodersSize, <NONE>,  'GdipGetImageDecodersSize',  \
    GdipGetImageDimension, <NONE>,  'GdipGetImageDimension',  \
    GdipGetImageEncoders, <NONE>,  'GdipGetImageEncoders',  \
    GdipGetImageEncodersSize, <NONE>,  'GdipGetImageEncodersSize',  \
    GdipGetImageFlags, <NONE>,  'GdipGetImageFlags',  \
    GdipGetImageGraphicsContext, <NONE>,  'GdipGetImageGraphicsContext',  \
    GdipGetImageHeight, <NONE>,  'GdipGetImageHeight',  \
    GdipGetImageHorizontalResolution, <NONE>,  'GdipGetImageHorizontalResolution',  \
    GdipGetImageItemData, <NONE>,  'GdipGetImageItemData',  \
    GdipGetImagePalette, <NONE>,  'GdipGetImagePalette',  \
    GdipGetImagePaletteSize, <NONE>,  'GdipGetImagePaletteSize',  \
    GdipGetImagePixelFormat, <NONE>,  'GdipGetImagePixelFormat',  \
    GdipGetImageRawFormat, <NONE>,  'GdipGetImageRawFormat',  \
    GdipGetImageThumbnail, <NONE>,  'GdipGetImageThumbnail',  \
    GdipGetImageType, <NONE>,  'GdipGetImageType',  \
    GdipGetImageVerticalResolution, <NONE>,  'GdipGetImageVerticalResolution',  \
    GdipGetImageWidth, <NONE>,  'GdipGetImageWidth',  \
    GdipGetInterpolationMode, <NONE>,  'GdipGetInterpolationMode',  \
    GdipGetLineBlend, <NONE>,  'GdipGetLineBlend',  \
    GdipGetLineBlendCount, <NONE>,  'GdipGetLineBlendCount',  \
    GdipGetLineColors, <NONE>,  'GdipGetLineColors',  \
    GdipGetLineGammaCorrection, <NONE>,  'GdipGetLineGammaCorrection',  \
    GdipGetLinePresetBlend, <NONE>,  'GdipGetLinePresetBlend',  \
    GdipGetLinePresetBlendCount, <NONE>,  'GdipGetLinePresetBlendCount',  \
    GdipGetLineRect, <NONE>,  'GdipGetLineRect',  \
    GdipGetLineRectI, <NONE>,  'GdipGetLineRectI',  \
    GdipGetLineSpacing, <NONE>,  'GdipGetLineSpacing',  \
    GdipGetLineTransform, <NONE>,  'GdipGetLineTransform',  \
    GdipGetLineWrapMode, <NONE>,  'GdipGetLineWrapMode',  \
    GdipGetLogFontA, <NONE>,  'GdipGetLogFontA',  \
    GdipGetLogFontW, <NONE>,  'GdipGetLogFontW',  \
    GdipGetMatrixElements, <NONE>,  'GdipGetMatrixElements',  \
    GdipGetMetafileDownLevelRasterizationLimit, <NONE>,  'GdipGetMetafileDownLevelRasterizationLimit',  \
    GdipGetMetafileHeaderFromEmf, <NONE>,  'GdipGetMetafileHeaderFromEmf',  \
    GdipGetMetafileHeaderFromFile, <NONE>,  'GdipGetMetafileHeaderFromFile',  \
    GdipGetMetafileHeaderFromMetafile, <NONE>,  'GdipGetMetafileHeaderFromMetafile',  \
    GdipGetMetafileHeaderFromStream, <NONE>,  'GdipGetMetafileHeaderFromStream',  \
    GdipGetMetafileHeaderFromWmf, <NONE>,  'GdipGetMetafileHeaderFromWmf',  \
    GdipGetNearestColor, <NONE>,  'GdipGetNearestColor',  \
    GdipGetPageScale, <NONE>,  'GdipGetPageScale',  \
    GdipGetPageUnit, <NONE>,  'GdipGetPageUnit',  \
    GdipGetPathData, <NONE>,  'GdipGetPathData',  \
    GdipGetPathFillMode, <NONE>,  'GdipGetPathFillMode',  \
    GdipGetPathGradientBlend, <NONE>,  'GdipGetPathGradientBlend',  \
    GdipGetPathGradientBlendCount, <NONE>,  'GdipGetPathGradientBlendCount',  \
    GdipGetPathGradientCenterColor, <NONE>,  'GdipGetPathGradientCenterColor',  \
    GdipGetPathGradientCenterPoint, <NONE>,  'GdipGetPathGradientCenterPoint',  \
    GdipGetPathGradientCenterPointI, <NONE>,  'GdipGetPathGradientCenterPointI',  \
    GdipGetPathGradientFocusScales, <NONE>,  'GdipGetPathGradientFocusScales',  \
    GdipGetPathGradientGammaCorrection, <NONE>,  'GdipGetPathGradientGammaCorrection',  \
    GdipGetPathGradientPath, <NONE>,  'GdipGetPathGradientPath',  \
    GdipGetPathGradientPointCount, <NONE>,  'GdipGetPathGradientPointCount',  \
    GdipGetPathGradientPresetBlend, <NONE>,  'GdipGetPathGradientPresetBlend',  \
    GdipGetPathGradientPresetBlendCount, <NONE>,  'GdipGetPathGradientPresetBlendCount',  \
    GdipGetPathGradientRect, <NONE>,  'GdipGetPathGradientRect',  \
    GdipGetPathGradientRectI, <NONE>,  'GdipGetPathGradientRectI',  \
    GdipGetPathGradientSurroundColorCount, <NONE>,  'GdipGetPathGradientSurroundColorCount',  \
    GdipGetPathGradientSurroundColorsWithCount, <NONE>,  'GdipGetPathGradientSurroundColorsWithCount',  \
    GdipGetPathGradientTransform, <NONE>,  'GdipGetPathGradientTransform',  \
    GdipGetPathGradientWrapMode, <NONE>,  'GdipGetPathGradientWrapMode',  \
    GdipGetPathLastPoint, <NONE>,  'GdipGetPathLastPoint',  \
    GdipGetPathPoints, <NONE>,  'GdipGetPathPoints',  \
    GdipGetPathPointsI, <NONE>,  'GdipGetPathPointsI',  \
    GdipGetPathTypes, <NONE>,  'GdipGetPathTypes',  \
    GdipGetPathWorldBounds, <NONE>,  'GdipGetPathWorldBounds',  \
    GdipGetPathWorldBoundsI, <NONE>,  'GdipGetPathWorldBoundsI',  \
    GdipGetPenBrushFill, <NONE>,  'GdipGetPenBrushFill',  \
    GdipGetPenColor, <NONE>,  'GdipGetPenColor',  \
    GdipGetPenCompoundArray, <NONE>,  'GdipGetPenCompoundArray',  \
    GdipGetPenCompoundCount, <NONE>,  'GdipGetPenCompoundCount',  \
    GdipGetPenCustomEndCap, <NONE>,  'GdipGetPenCustomEndCap',  \
    GdipGetPenCustomStartCap, <NONE>,  'GdipGetPenCustomStartCap',  \
    GdipGetPenDashArray, <NONE>,  'GdipGetPenDashArray',  \
    GdipGetPenDashCap197819, <NONE>,  'GdipGetPenDashCap197819',  \
    GdipGetPenDashCount, <NONE>,  'GdipGetPenDashCount',  \
    GdipGetPenDashOffset, <NONE>,  'GdipGetPenDashOffset',  \
    GdipGetPenDashStyle, <NONE>,  'GdipGetPenDashStyle',  \
    GdipGetPenEndCap, <NONE>,  'GdipGetPenEndCap',  \
    GdipGetPenFillType, <NONE>,  'GdipGetPenFillType',  \
    GdipGetPenLineJoin, <NONE>,  'GdipGetPenLineJoin',  \
    GdipGetPenMiterLimit, <NONE>,  'GdipGetPenMiterLimit',  \
    GdipGetPenMode, <NONE>,  'GdipGetPenMode',  \
    GdipGetPenStartCap, <NONE>,  'GdipGetPenStartCap',  \
    GdipGetPenTransform, <NONE>,  'GdipGetPenTransform',  \
    GdipGetPenUnit, <NONE>,  'GdipGetPenUnit',  \
    GdipGetPenWidth, <NONE>,  'GdipGetPenWidth',  \
    GdipGetPixelOffsetMode, <NONE>,  'GdipGetPixelOffsetMode',  \
    GdipGetPointCount, <NONE>,  'GdipGetPointCount',  \
    GdipGetPropertyCount, <NONE>,  'GdipGetPropertyCount',  \
    GdipGetPropertyIdList, <NONE>,  'GdipGetPropertyIdList',  \
    GdipGetPropertyItem, <NONE>,  'GdipGetPropertyItem',  \
    GdipGetPropertyItemSize, <NONE>,  'GdipGetPropertyItemSize',  \
    GdipGetPropertySize, <NONE>,  'GdipGetPropertySize',  \
    GdipGetRegionBounds, <NONE>,  'GdipGetRegionBounds',  \
    GdipGetRegionBoundsI, <NONE>,  'GdipGetRegionBoundsI',  \
    GdipGetRegionData, <NONE>,  'GdipGetRegionData',  \
    GdipGetRegionDataSize, <NONE>,  'GdipGetRegionDataSize',  \
    GdipGetRegionHRgn, <NONE>,  'GdipGetRegionHRgn',  \
    GdipGetRegionScans, <NONE>,  'GdipGetRegionScans',  \
    GdipGetRegionScansCount, <NONE>,  'GdipGetRegionScansCount',  \
    GdipGetRegionScansI, <NONE>,  'GdipGetRegionScansI',  \
    GdipGetRenderingOrigin, <NONE>,  'GdipGetRenderingOrigin',  \
    GdipGetSmoothingMode, <NONE>,  'GdipGetSmoothingMode',  \
    GdipGetSolidFillColor, <NONE>,  'GdipGetSolidFillColor',  \
    GdipGetStringFormatAlign, <NONE>,  'GdipGetStringFormatAlign',  \
    GdipGetStringFormatDigitSubstitution, <NONE>,  'GdipGetStringFormatDigitSubstitution',  \
    GdipGetStringFormatFlags, <NONE>,  'GdipGetStringFormatFlags',  \
    GdipGetStringFormatHotkeyPrefix, <NONE>,  'GdipGetStringFormatHotkeyPrefix',  \
    GdipGetStringFormatLineAlign, <NONE>,  'GdipGetStringFormatLineAlign',  \
    GdipGetStringFormatMeasurableCharacterRangeCount, <NONE>,  'GdipGetStringFormatMeasurableCharacterRangeCount',  \
    GdipGetStringFormatTabStopCount, <NONE>,  'GdipGetStringFormatTabStopCount',  \
    GdipGetStringFormatTabStops, <NONE>,  'GdipGetStringFormatTabStops',  \
    GdipGetStringFormatTrimming, <NONE>,  'GdipGetStringFormatTrimming',  \
    GdipGetTextContrast, <NONE>,  'GdipGetTextContrast',  \
    GdipGetTextRenderingHint, <NONE>,  'GdipGetTextRenderingHint',  \
    GdipGetTextureImage, <NONE>,  'GdipGetTextureImage',  \
    GdipGetTextureTransform, <NONE>,  'GdipGetTextureTransform',  \
    GdipGetTextureWrapMode, <NONE>,  'GdipGetTextureWrapMode',  \
    GdipGetVisibleClipBounds, <NONE>,  'GdipGetVisibleClipBounds',  \
    GdipGetVisibleClipBoundsI, <NONE>,  'GdipGetVisibleClipBoundsI',  \
    GdipGetWorldTransform, <NONE>,  'GdipGetWorldTransform',  \
    GdipGraphicsClear, <NONE>,  'GdipGraphicsClear',  \
    GdipGraphicsSetAbort, <NONE>,  'GdipGraphicsSetAbort',  \
    GdipImageForceValidation, <NONE>,  'GdipImageForceValidation',  \
    GdipImageGetFrameCount, <NONE>,  'GdipImageGetFrameCount',  \
    GdipImageGetFrameDimensionsCount, <NONE>,  'GdipImageGetFrameDimensionsCount',  \
    GdipImageGetFrameDimensionsList, <NONE>,  'GdipImageGetFrameDimensionsList',  \
    GdipImageRotateFlip, <NONE>,  'GdipImageRotateFlip',  \
    GdipImageSelectActiveFrame, <NONE>,  'GdipImageSelectActiveFrame',  \
    GdipImageSetAbort, <NONE>,  'GdipImageSetAbort',  \
    GdipInitializePalette, <NONE>,  'GdipInitializePalette',  \
    GdipInvertMatrix, <NONE>,  'GdipInvertMatrix',  \
    GdipIsClipEmpty, <NONE>,  'GdipIsClipEmpty',  \
    GdipIsEmptyRegion, <NONE>,  'GdipIsEmptyRegion',  \
    GdipIsEqualRegion, <NONE>,  'GdipIsEqualRegion',  \
    GdipIsInfiniteRegion, <NONE>,  'GdipIsInfiniteRegion',  \
    GdipIsMatrixEqual, <NONE>,  'GdipIsMatrixEqual',  \
    GdipIsMatrixIdentity, <NONE>,  'GdipIsMatrixIdentity',  \
    GdipIsMatrixInvertible, <NONE>,  'GdipIsMatrixInvertible',  \
    GdipIsOutlineVisiblePathPoint, <NONE>,  'GdipIsOutlineVisiblePathPoint',  \
    GdipIsOutlineVisiblePathPointI, <NONE>,  'GdipIsOutlineVisiblePathPointI',  \
    GdipIsStyleAvailable, <NONE>,  'GdipIsStyleAvailable',  \
    GdipIsVisibleClipEmpty, <NONE>,  'GdipIsVisibleClipEmpty',  \
    GdipIsVisiblePathPoint, <NONE>,  'GdipIsVisiblePathPoint',  \
    GdipIsVisiblePathPointI, <NONE>,  'GdipIsVisiblePathPointI',  \
    GdipIsVisiblePoint, <NONE>,  'GdipIsVisiblePoint',  \
    GdipIsVisiblePointI, <NONE>,  'GdipIsVisiblePointI',  \
    GdipIsVisibleRect, <NONE>,  'GdipIsVisibleRect',  \
    GdipIsVisibleRectI, <NONE>,  'GdipIsVisibleRectI',  \
    GdipIsVisibleRegionPoint, <NONE>,  'GdipIsVisibleRegionPoint',  \
    GdipIsVisibleRegionPointI, <NONE>,  'GdipIsVisibleRegionPointI',  \
    GdipIsVisibleRegionRect, <NONE>,  'GdipIsVisibleRegionRect',  \
    GdipIsVisibleRegionRectI, <NONE>,  'GdipIsVisibleRegionRectI',  \
    GdipLoadImageFromFile, <NONE>,  'GdipLoadImageFromFile',  \
    GdipLoadImageFromFileICM, <NONE>,  'GdipLoadImageFromFileICM',  \
    GdipLoadImageFromStream, <NONE>,  'GdipLoadImageFromStream',  \
    GdipLoadImageFromStreamICM, <NONE>,  'GdipLoadImageFromStreamICM',  \
    GdipMeasureCharacterRanges, <NONE>,  'GdipMeasureCharacterRanges',  \
    GdipMeasureDriverString, <NONE>,  'GdipMeasureDriverString',  \
    GdipMeasureString, <NONE>,  'GdipMeasureString',  \
    GdipMultiplyLineTransform, <NONE>,  'GdipMultiplyLineTransform',  \
    GdipMultiplyMatrix, <NONE>,  'GdipMultiplyMatrix',  \
    GdipMultiplyPathGradientTransform, <NONE>,  'GdipMultiplyPathGradientTransform',  \
    GdipMultiplyPenTransform, <NONE>,  'GdipMultiplyPenTransform',  \
    GdipMultiplyTextureTransform, <NONE>,  'GdipMultiplyTextureTransform',  \
    GdipMultiplyWorldTransform, <NONE>,  'GdipMultiplyWorldTransform',  \
    GdipNewInstalledFontCollection, <NONE>,  'GdipNewInstalledFontCollection',  \
    GdipNewPrivateFontCollection, <NONE>,  'GdipNewPrivateFontCollection',  \
    GdipPathIterCopyData, <NONE>,  'GdipPathIterCopyData',  \
    GdipPathIterEnumerate, <NONE>,  'GdipPathIterEnumerate',  \
    GdipPathIterGetCount, <NONE>,  'GdipPathIterGetCount',  \
    GdipPathIterGetSubpathCount, <NONE>,  'GdipPathIterGetSubpathCount',  \
    GdipPathIterHasCurve, <NONE>,  'GdipPathIterHasCurve',  \
    GdipPathIterIsValid, <NONE>,  'GdipPathIterIsValid',  \
    GdipPathIterNextMarker, <NONE>,  'GdipPathIterNextMarker',  \
    GdipPathIterNextMarkerPath, <NONE>,  'GdipPathIterNextMarkerPath',  \
    GdipPathIterNextPathType, <NONE>,  'GdipPathIterNextPathType',  \
    GdipPathIterNextSubpath, <NONE>,  'GdipPathIterNextSubpath',  \
    GdipPathIterNextSubpathPath, <NONE>,  'GdipPathIterNextSubpathPath',  \
    GdipPathIterRewind, <NONE>,  'GdipPathIterRewind',  \
    GdipPlayMetafileRecord, <NONE>,  'GdipPlayMetafileRecord',  \
    GdipPlayTSClientRecord, <NONE>,  'GdipPlayTSClientRecord',  \
    GdipPrivateAddFontFile, <NONE>,  'GdipPrivateAddFontFile',  \
    GdipPrivateAddMemoryFont, <NONE>,  'GdipPrivateAddMemoryFont',  \
    GdipRecordMetafile, <NONE>,  'GdipRecordMetafile',  \
    GdipRecordMetafileFileName, <NONE>,  'GdipRecordMetafileFileName',  \
    GdipRecordMetafileFileNameI, <NONE>,  'GdipRecordMetafileFileNameI',  \
    GdipRecordMetafileI, <NONE>,  'GdipRecordMetafileI',  \
    GdipRecordMetafileStream, <NONE>,  'GdipRecordMetafileStream',  \
    GdipRecordMetafileStreamI, <NONE>,  'GdipRecordMetafileStreamI',  \
    GdipReleaseDC, <NONE>,  'GdipReleaseDC',  \
    GdipRemovePropertyItem, <NONE>,  'GdipRemovePropertyItem',  \
    GdipResetClip, <NONE>,  'GdipResetClip',  \
    GdipResetImageAttributes, <NONE>,  'GdipResetImageAttributes',  \
    GdipResetLineTransform, <NONE>,  'GdipResetLineTransform',  \
    GdipResetPageTransform, <NONE>,  'GdipResetPageTransform',  \
    GdipResetPath, <NONE>,  'GdipResetPath',  \
    GdipResetPathGradientTransform, <NONE>,  'GdipResetPathGradientTransform',  \
    GdipResetPenTransform, <NONE>,  'GdipResetPenTransform',  \
    GdipResetTextureTransform, <NONE>,  'GdipResetTextureTransform',  \
    GdipResetWorldTransform, <NONE>,  'GdipResetWorldTransform',  \
    GdipRestoreGraphics, <NONE>,  'GdipRestoreGraphics',  \
    GdipReversePath, <NONE>,  'GdipReversePath',  \
    GdipRotateLineTransform, <NONE>,  'GdipRotateLineTransform',  \
    GdipRotateMatrix, <NONE>,  'GdipRotateMatrix',  \
    GdipRotatePathGradientTransform, <NONE>,  'GdipRotatePathGradientTransform',  \
    GdipRotatePenTransform, <NONE>,  'GdipRotatePenTransform',  \
    GdipRotateTextureTransform, <NONE>,  'GdipRotateTextureTransform',  \
    GdipRotateWorldTransform, <NONE>,  'GdipRotateWorldTransform',  \
    GdipSaveAdd, <NONE>,  'GdipSaveAdd',  \
    GdipSaveAddImage, <NONE>,  'GdipSaveAddImage',  \
    GdipSaveGraphics, <NONE>,  'GdipSaveGraphics',  \
    GdipSaveImageToFile, <NONE>,  'GdipSaveImageToFile',  \
    GdipSaveImageToStream, <NONE>,  'GdipSaveImageToStream',  \
    GdipScaleLineTransform, <NONE>,  'GdipScaleLineTransform',  \
    GdipScaleMatrix, <NONE>,  'GdipScaleMatrix',  \
    GdipScalePathGradientTransform, <NONE>,  'GdipScalePathGradientTransform',  \
    GdipScalePenTransform, <NONE>,  'GdipScalePenTransform',  \
    GdipScaleTextureTransform, <NONE>,  'GdipScaleTextureTransform',  \
    GdipScaleWorldTransform, <NONE>,  'GdipScaleWorldTransform',  \
    GdipSetAdjustableArrowCapFillState, <NONE>,  'GdipSetAdjustableArrowCapFillState',  \
    GdipSetAdjustableArrowCapHeight, <NONE>,  'GdipSetAdjustableArrowCapHeight',  \
    GdipSetAdjustableArrowCapMiddleInset, <NONE>,  'GdipSetAdjustableArrowCapMiddleInset',  \
    GdipSetAdjustableArrowCapWidth, <NONE>,  'GdipSetAdjustableArrowCapWidth',  \
    GdipSetClipGraphics, <NONE>,  'GdipSetClipGraphics',  \
    GdipSetClipHrgn, <NONE>,  'GdipSetClipHrgn',  \
    GdipSetClipPath, <NONE>,  'GdipSetClipPath',  \
    GdipSetClipRect, <NONE>,  'GdipSetClipRect',  \
    GdipSetClipRectI, <NONE>,  'GdipSetClipRectI',  \
    GdipSetClipRegion, <NONE>,  'GdipSetClipRegion',  \
    GdipSetCompositingMode, <NONE>,  'GdipSetCompositingMode',  \
    GdipSetCompositingQuality, <NONE>,  'GdipSetCompositingQuality',  \
    GdipSetCustomLineCapBaseCap, <NONE>,  'GdipSetCustomLineCapBaseCap',  \
    GdipSetCustomLineCapBaseInset, <NONE>,  'GdipSetCustomLineCapBaseInset',  \
    GdipSetCustomLineCapStrokeCaps, <NONE>,  'GdipSetCustomLineCapStrokeCaps',  \
    GdipSetCustomLineCapStrokeJoin, <NONE>,  'GdipSetCustomLineCapStrokeJoin',  \
    GdipSetCustomLineCapWidthScale, <NONE>,  'GdipSetCustomLineCapWidthScale',  \
    GdipSetEffectParameters, <NONE>,  'GdipSetEffectParameters',  \
    GdipSetEmpty, <NONE>,  'GdipSetEmpty',  \
    GdipSetImageAttributesCachedBackground, <NONE>,  'GdipSetImageAttributesCachedBackground',  \
    GdipSetImageAttributesColorKeys, <NONE>,  'GdipSetImageAttributesColorKeys',  \
    GdipSetImageAttributesColorMatrix, <NONE>,  'GdipSetImageAttributesColorMatrix',  \
    GdipSetImageAttributesGamma, <NONE>,  'GdipSetImageAttributesGamma',  \
    GdipSetImageAttributesNoOp, <NONE>,  'GdipSetImageAttributesNoOp',  \
    GdipSetImageAttributesOutputChannel, <NONE>,  'GdipSetImageAttributesOutputChannel',  \
    GdipSetImageAttributesOutputChannelColorProfile, <NONE>,  'GdipSetImageAttributesOutputChannelColorProfile',  \
    GdipSetImageAttributesRemapTable, <NONE>,  'GdipSetImageAttributesRemapTable',  \
    GdipSetImageAttributesThreshold, <NONE>,  'GdipSetImageAttributesThreshold',  \
    GdipSetImageAttributesToIdentity, <NONE>,  'GdipSetImageAttributesToIdentity',  \
    GdipSetImageAttributesWrapMode, <NONE>,  'GdipSetImageAttributesWrapMode',  \
    GdipSetImagePalette, <NONE>,  'GdipSetImagePalette',  \
    GdipSetInfinite, <NONE>,  'GdipSetInfinite',  \
    GdipSetInterpolationMode, <NONE>,  'GdipSetInterpolationMode',  \
    GdipSetLineBlend, <NONE>,  'GdipSetLineBlend',  \
    GdipSetLineColors, <NONE>,  'GdipSetLineColors',  \
    GdipSetLineGammaCorrection, <NONE>,  'GdipSetLineGammaCorrection',  \
    GdipSetLineLinearBlend, <NONE>,  'GdipSetLineLinearBlend',  \
    GdipSetLinePresetBlend, <NONE>,  'GdipSetLinePresetBlend',  \
    GdipSetLineSigmaBlend, <NONE>,  'GdipSetLineSigmaBlend',  \
    GdipSetLineTransform, <NONE>,  'GdipSetLineTransform',  \
    GdipSetLineWrapMode, <NONE>,  'GdipSetLineWrapMode',  \
    GdipSetMatrixElements, <NONE>,  'GdipSetMatrixElements',  \
    GdipSetMetafileDownLevelRasterizationLimit, <NONE>,  'GdipSetMetafileDownLevelRasterizationLimit',  \
    GdipSetPageScale, <NONE>,  'GdipSetPageScale',  \
    GdipSetPageUnit, <NONE>,  'GdipSetPageUnit',  \
    GdipSetPathFillMode, <NONE>,  'GdipSetPathFillMode',  \
    GdipSetPathGradientBlend, <NONE>,  'GdipSetPathGradientBlend',  \
    GdipSetPathGradientCenterColor, <NONE>,  'GdipSetPathGradientCenterColor',  \
    GdipSetPathGradientCenterPoint, <NONE>,  'GdipSetPathGradientCenterPoint',  \
    GdipSetPathGradientCenterPointI, <NONE>,  'GdipSetPathGradientCenterPointI',  \
    GdipSetPathGradientFocusScales, <NONE>,  'GdipSetPathGradientFocusScales',  \
    GdipSetPathGradientGammaCorrection, <NONE>,  'GdipSetPathGradientGammaCorrection',  \
    GdipSetPathGradientLinearBlend, <NONE>,  'GdipSetPathGradientLinearBlend',  \
    GdipSetPathGradientPath, <NONE>,  'GdipSetPathGradientPath',  \
    GdipSetPathGradientPresetBlend, <NONE>,  'GdipSetPathGradientPresetBlend',  \
    GdipSetPathGradientSigmaBlend, <NONE>,  'GdipSetPathGradientSigmaBlend',  \
    GdipSetPathGradientSurroundColorsWithCount, <NONE>,  'GdipSetPathGradientSurroundColorsWithCount',  \
    GdipSetPathGradientTransform, <NONE>,  'GdipSetPathGradientTransform',  \
    GdipSetPathGradientWrapMode, <NONE>,  'GdipSetPathGradientWrapMode',  \
    GdipSetPathMarker, <NONE>,  'GdipSetPathMarker',  \
    GdipSetPenBrushFill, <NONE>,  'GdipSetPenBrushFill',  \
    GdipSetPenColor, <NONE>,  'GdipSetPenColor',  \
    GdipSetPenCompoundArray, <NONE>,  'GdipSetPenCompoundArray',  \
    GdipSetPenCustomEndCap, <NONE>,  'GdipSetPenCustomEndCap',  \
    GdipSetPenCustomStartCap, <NONE>,  'GdipSetPenCustomStartCap',  \
    GdipSetPenDashArray, <NONE>,  'GdipSetPenDashArray',  \
    GdipSetPenDashCap197819, <NONE>,  'GdipSetPenDashCap197819',  \
    GdipSetPenDashOffset, <NONE>,  'GdipSetPenDashOffset',  \
    GdipSetPenDashStyle, <NONE>,  'GdipSetPenDashStyle',  \
    GdipSetPenEndCap, <NONE>,  'GdipSetPenEndCap',  \
    GdipSetPenLineCap197819, <NONE>,  'GdipSetPenLineCap197819',  \
    GdipSetPenLineJoin, <NONE>,  'GdipSetPenLineJoin',  \
    GdipSetPenMiterLimit, <NONE>,  'GdipSetPenMiterLimit',  \
    GdipSetPenMode, <NONE>,  'GdipSetPenMode',  \
    GdipSetPenStartCap, <NONE>,  'GdipSetPenStartCap',  \
    GdipSetPenTransform, <NONE>,  'GdipSetPenTransform',  \
    GdipSetPenUnit, <NONE>,  'GdipSetPenUnit',  \
    GdipSetPenWidth, <NONE>,  'GdipSetPenWidth',  \
    GdipSetPixelOffsetMode, <NONE>,  'GdipSetPixelOffsetMode',  \
    GdipSetPropertyItem, <NONE>,  'GdipSetPropertyItem',  \
    GdipSetRenderingOrigin, <NONE>,  'GdipSetRenderingOrigin',  \
    GdipSetSmoothingMode, <NONE>,  'GdipSetSmoothingMode',  \
    GdipSetSolidFillColor, <NONE>,  'GdipSetSolidFillColor',  \
    GdipSetStringFormatAlign, <NONE>,  'GdipSetStringFormatAlign',  \
    GdipSetStringFormatDigitSubstitution, <NONE>,  'GdipSetStringFormatDigitSubstitution',  \
    GdipSetStringFormatFlags, <NONE>,  'GdipSetStringFormatFlags',  \
    GdipSetStringFormatHotkeyPrefix, <NONE>,  'GdipSetStringFormatHotkeyPrefix',  \
    GdipSetStringFormatLineAlign, <NONE>,  'GdipSetStringFormatLineAlign',  \
    GdipSetStringFormatMeasurableCharacterRanges, <NONE>,  'GdipSetStringFormatMeasurableCharacterRanges',  \
    GdipSetStringFormatTabStops, <NONE>,  'GdipSetStringFormatTabStops',  \
    GdipSetStringFormatTrimming, <NONE>,  'GdipSetStringFormatTrimming',  \
    GdipSetTextContrast, <NONE>,  'GdipSetTextContrast',  \
    GdipSetTextRenderingHint, <NONE>,  'GdipSetTextRenderingHint',  \
    GdipSetTextureTransform, <NONE>,  'GdipSetTextureTransform',  \
    GdipSetTextureWrapMode, <NONE>,  'GdipSetTextureWrapMode',  \
    GdipSetWorldTransform, <NONE>,  'GdipSetWorldTransform',  \
    GdipShearMatrix, <NONE>,  'GdipShearMatrix',  \
    GdipStartPathFigure, <NONE>,  'GdipStartPathFigure',  \
    GdipStringFormatGetGenericDefault, <NONE>,  'GdipStringFormatGetGenericDefault',  \
    GdipStringFormatGetGenericTypographic, <NONE>,  'GdipStringFormatGetGenericTypographic',  \
    GdipTestControl, <NONE>,  'GdipTestControl',  \
    GdipTransformMatrixPoints, <NONE>,  'GdipTransformMatrixPoints',  \
    GdipTransformMatrixPointsI, <NONE>,  'GdipTransformMatrixPointsI',  \
    GdipTransformPath, <NONE>,  'GdipTransformPath',  \
    GdipTransformPoints, <NONE>,  'GdipTransformPoints',  \
    GdipTransformPointsI, <NONE>,  'GdipTransformPointsI',  \
    GdipTransformRegion, <NONE>,  'GdipTransformRegion',  \
    GdipTranslateClip, <NONE>,  'GdipTranslateClip',  \
    GdipTranslateClipI, <NONE>,  'GdipTranslateClipI',  \
    GdipTranslateLineTransform, <NONE>,  'GdipTranslateLineTransform',  \
    GdipTranslateMatrix, <NONE>,  'GdipTranslateMatrix',  \
    GdipTranslatePathGradientTransform, <NONE>,  'GdipTranslatePathGradientTransform',  \
    GdipTranslatePenTransform, <NONE>,  'GdipTranslatePenTransform',  \
    GdipTranslateRegion, <NONE>,  'GdipTranslateRegion',  \
    GdipTranslateRegionI, <NONE>,  'GdipTranslateRegionI',  \
    GdipTranslateTextureTransform, <NONE>,  'GdipTranslateTextureTransform',  \
    GdipTranslateWorldTransform, <NONE>,  'GdipTranslateWorldTransform',  \
    GdipVectorTransformMatrixPoints, <NONE>,  'GdipVectorTransformMatrixPoints',  \
    GdipVectorTransformMatrixPointsI, <NONE>,  'GdipVectorTransformMatrixPointsI',  \
    GdipWarpPath, <NONE>,  'GdipWarpPath',  \
    GdipWidenPath, <NONE>,  'GdipWidenPath',  \
    GdipWindingModeOutline, <NONE>,  'GdipWindingModeOutline',  \
    GdiplusNotificationHook, <NONE>,  'GdiplusNotificationHook',  \
    GdiplusNotificationUnhook, <NONE>,  'GdiplusNotificationUnhook',  \
    GdiplusShutdown, <NONE>,  'GdiplusShutdown',  \
    GdiplusStartup, <NONE>,  'GdiplusStartup'
Changes to freshlib/macros/Linux/_import.inc.
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48







-
+







    else
      virtual at ebp+8
        ..start:
forward
        if ~arg eq ...
          arg dd ?
        else
          label .more… dword
          label .more_arguments dword
        end if
common
        .__info.argsize = $ - ..start
      end virtual
      .__info.argtype = 2
    end if
  end if
67
68
69
70
71
72
73

74
75
76
77
78
79
80
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81







+







      \\}

    \forward
      \local fstr
      rept 1 i:func+1 \\{
        func equ i
        func\\#i equ fstr:cnt:iname:ename:arg
        iname\\#.@here:
      \\}
  \}

  macro __ImportAll \{
  \common
    \local strtab,strsz,symtab,rel,relsz,hash,tcnt, size1, size2

Changes to freshlib/macros/_display.inc.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
28
29
30
31
32
33
34


35
36
37
38
39
40
41






42
43
44
45
46
47
48







-
-







-
-
-
-
-
-







    display 'A'+num-10
   end if
}


macro _disp arg1, arg2
{
   local ..var

   if arg2 eq
    display arg1
   else
    local ..tmp, ..val

    ..tmp = arg1

;    ..val = arg1
;    virtual at 0
;      dd ..val
;      load ..tmp dword from 0
;    end virtual

    virtual at 0
     repeat 32
      if ..tmp > 0
       db ..tmp mod arg2
       ..tmp = ..tmp / arg2
      end if
     end repeat
Changes to freshlib/macros/_globals.inc.
206
207
208
209
210
211
212
213

214
215
216
217


218
219

220
221
222
223


224
225

226
227
228
229


230
231

232
233
234
235


236
237

238
239
240
241


242
243

244
245
246
247
248
249
250
206
207
208
209
210
211
212

213
214
215


216
217
218

219
220
221


222
223
224

225
226
227


228
229
230

231
232
233


234
235
236

237
238
239


240
241
242

243
244
245
246
247
248
249
250







-
+


-
-
+
+

-
+


-
-
+
+

-
+


-
-
+
+

-
+


-
-
+
+

-
+


-
-
+
+

-
+







}


__InitStringEngine


macro IncludeAllGlobals {
  local begin
  local ..start

  align 4
  begin =  $-$$
  disp 3, 'Initialized data address: $', <begin, 16>, 13
  ..start = $
  disp 3, 'Initialized data address: $', <..start, 16>, 13
  IncludeIGlobals
  DispSize 'Initialized data', ($ - begin)
  DispSize 'Initialized data', ($ - ..start)

  align 4
  begin = $-$$
  disp 3, 'Strings address: $', <begin, 16>, 13
  ..start = $
  disp 3, 'Strings address: $', <..start, 16>, 13
  _IncludeAllStrings
  DispSize 'String data', ($ - begin)
  DispSize 'String data', ($ - ..start)

  align 4
  begin = $-$$
  disp 3, 'I18n strings data:', <begin, 16>, 13
  ..start = $
  disp 3, 'I18n strings data:', <..start, 16>, 13
  __IncludeI18nStrings
  DispSize 'I18n strings data', ($ - begin)
  DispSize 'I18n strings data', ($ - ..start)

  align 4
  begin = $-$$
  disp 3, 'Uninitialized data address: $', <begin, 16>, 13
  ..start = $
  disp 3, 'Uninitialized data address: $', <..start, 16>, 13
  IncludeUGlobals
  DispSize 'Uninitialized data', ($ - begin)
  DispSize 'Uninitialized data', ($ - ..start)

  align 4
  begin = $-$$
  disp 3, 'I18n strings placeholders: $', <begin, 16>, 13
  ..start = $
  disp 3, 'I18n strings placeholders: $', <..start, 16>, 13
  IncludeI18nLabels
  DispSize 'I18n strings placeholders', ($ - begin)
  DispSize 'I18n strings placeholders', ($ - ..start)
}



macro var expr {
common
  match name==value, expr \{
Added freshlib/macros/_realobjects.inc.
































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
cParamMask = $fffe0000
cMethodMask = $ffff0000


macro __search_method flag, num, count, list, cname, method {
  define flag FALSE
  rept count i:1 \{ match mname, method \\{ match class | name , list\\#i \\\{ match =mname, name \\\\{
    define flag TRUE
    num equ i
  \\\\} \\\} \\} \}
}


macro object name, parent {
  obj@name   equ name
  obj@parent equ parent

  name#.param?num = 0

  name#@count equ 0

  match any, parent \{
    name#@count equ parent#@count
    rept parent\#@count i:1 \\{
      name\\#@method\\#i equ parent\\#@method\\#i
      match class | mname, parent\\#i \\\{
        name\\\#mname = i or cMethodMask
;        display 3, "Copy:", \\\`name,\\\`mname, ' = ', \\\`i, 13, 10
      \\\}
    \\}
  \}

  macro param paramname*, getval*, setval* \{
    paramname = name#.param?num or cParamMask
    name#.param?num = name#.param?num + 1

      if getval eq NONE
        paramname\#.get = -1
      else
        paramname\#.get = getval
      end if

      if setval eq NONE  ; read only
        paramname\#.set = -1
      else
        paramname\#.set = setval
      end if
  \}

  macro method mname, [marg] \{
  \common
  \local f1, n1
    name\#mname\#.arguments equ marg
    define f1 FALSE
    __search_method f1, n1, name\#@count, name\#@method, parent, mname
    match =FALSE, f1 \\{
      rept 1 x:name\\#@count+1 \\\{
        name\\\#@count equ x
        name\\\#@method\\\#x equ name | mname
;        display 3,'New method:', \\\`name,\\\`mname, ' = ', \\\`x, 13, 10
        methods.\\\#name\\\#mname\\\#.inherited equ NONE
      \\\}
    \\}
    match =TRUE, f1 \\{
      match num, n1 \\\{
        match class | mmname, name\\\#@method\\\#num \\\\{
          methods.\\\\#name\\\\#mname\\\\#.inherited equ methods.\\\\#class\\\\#mmname
        \\\\}
        name\\\#@method\\\#num equ name | mname
;        display 3,'Redefinition:', \\\`name,\\\`mname, ' = ', \\\`num, 13, 10
      \\\}
    \\}
  \}

  macro abstract mname, [marg] \{
  \common
    method mname, marg
    methods.\#name\#mname = 0
  \}


  macro name#@members \{
    macro method mname, [marg] \\{ \\}
    macro abstract mname, [marg] \\{ \\}
    match any, parent \\{
      parent\\#@members
    \\}
    purge method, abstract
}


endobj fix } obj_helper


macro obj_helper {
  match name, obj@name \{

    virtual at 0
      name dd ?           ; pointer to the methods table.
      name\#@members

      rept name\#@count i:1 \\{
        match class | meth, name\\#@method\\#i \\\{
          name\\\#meth = (i-1) or cMethodMask
;          display 1, "Method constant", \\\`name,\\\`meth, " = ", \\\`i, 13, 10
        \\\}
      \\}

      sizeof.\#name = $
    end virtual

    label vtables.\#name dword

    if used vtables.\#name\#.parent | used vtables.\#name
      .parent dd 0
    end if

    match parent, obj@parent \\{
      if defined vtables.\\#parent\\#.parent & used vtables.\\#name   ; in order to not use the address vtables.#parent
        store dword vtables.\\#parent\\#.parent at .parent
      end if
    \\}

    if used vtables.\#name
      .mcount dd name\#@count     ; methods count
      rept name\#@count i:1 \\{
        match class | meth, name\\#@method\\#i \\\{
            dd methods.\\\#class\\\#meth
        \\\}
      \\}
    end if
  \}
  purge method, param
  restore obj@name, obj@parent
}


macro method name {
  local f1, f2
  define f1 TRUE
  if used methods.#name
    match =NONE, methods.#name#.inherited \{
      define f1 FALSE
      dd 0
    \}
    match =TRUE, f1 \{
      dd methods.\#name\#.inherited
    \}
  end if
  match =name#.arguments, name#.arguments \{
    "Error! Method not defined in any object."
  \}

  f2 equ FALSE
  match arguments, name#.arguments \{
    f2 equ TRUE
    proc methods.\#name, .self, arguments
  \}
  match =FALSE, f2 \{
    proc methods.\#name, .self
  \}
}



; Object manipulation macros. They all generate some assembly code and its syntax is
; designed to resemble the usual assembly language syntax. These macros are some
; kind of quasiinstructions.

; These macros uses FreshLib in order to allocate/deallocate dynamic memory.



macro create target, class, [arg] {
common
   if ~target eq eax
        push    eax
   end if

        stdcall GetMem, sizeof.#class
        mov     dword [eax], vtables.#class

   if ~target eq eax
        mov     target, eax
   end if

reverse
   if ~arg eq
        pushx   arg
   end if
common

   if defined class#.Create & (class#.Create and $ffff0000) = cMethodMask
        exec    eax, class#:Create
   end if

   if ~target eq eax
        pop     eax
   end if
}


macro destroy ptrObj {
   if defined TObject.Destroy & (TObject.Destroy and $ffff0000) = cMethodMask
        push    eax
        exec    ptrObj, TObject:Destroy
        pop     eax
   end if
       stdcall  FreeMem, ptrObj
}


macro exec ptrobj, method, [arg] {
common
  local ind
        ind equ NONE
        match class:meth, method \{
          ind equ class\#.\#meth
        \}

        match =NONE, ind \{
          disp 2, "Error! Invalid syntax. Use class:method.", 13, 10
          err
        \}

        if defined ind & ~(ind and $ffff0000) = cMethodMask
          match meth, ind \{
            disp 2, 'Error! ', \`meth, ' is not a method.', 13, 10
            err
          \}
        end if

reverse
        if ~arg eq
          pushx   arg
        end if
common
        if ptrobj eqtype 1
          pushd [ptrobj]
        else
          pushd   ptrobj          ; push .self argument
        end if

        if ptrobj eqtype eax
          mov  eax, [ptrobj]
        else
          if ptrobj eqtype 1
            mov  eax, [ptrobj]
            mov  eax, [eax]
          else
            mov  eax, ptrobj
            mov  eax, [eax]
          end if
        end if

        call dword [eax+8+4*(ind and $ffff)]
}


macro getm  target, ptrobj, method {
  local ind
  ind equ NONE
  match class:meth, method \{
    ind equ class\#.\#meth
  \}

  match =NONE, ind \{
    disp 2, "Error! Invalid syntax. Use class:method.", 13, 10
    err
  \}

  if defined ind & ~(ind and $ffff0000) = cMethodMask
    match meth, ind \{
      disp 2, 'Error! ', \`meth, ' is not a method.', 13, 10
      err
    \}
  end if

  if ~target eq eax
    push  eax
  end if

  if ptrobj eqtype eax
    mov  eax, [ptrobj]
  else
    if ptrobj eqtype 1
      mov  eax, [ptrobj]
      mov  eax, [eax]
    else
      mov  eax, ptrobj
      mov  eax, [eax]
    end if
  end if

  push  dword [eax+8+4*(ind and $ffff)]
  pop   target

  if ~target eq eax
    pop eax
  end if
}


macro inherited [arg] {
common
  if ~arg eq
reverse
    pushx arg
common
  end if
  push [.self]
  call  dword [.__info.start-4]
}



macro get target, obj, param {
local flag

  flag equ FALSE

  match class:par, param \{
    flag equ TRUE
  \}

  match =FALSE, flag \{
    disp 2, "Error! Invalid syntax. Use class:method.", 13, 10
    err
  \}

  match class:par, param \{

    if class\#.\#par\#.get < sizeof.\#class ; field
      if obj eqtype eax
        if target eqtype eax
          mov target, [obj+class\#.\#par\#.get]
        else
          pushd [obj+class\#.\#par\#.get]
          popd  target
        end if
      else
        if ~target eq eax
          push eax
        end if
        if obj eqtype 1
          mov eax, [obj]
        else
          mov eax, obj
        end if
        if target eqtype eax
          mov target, [eax+class\#.\#par\#.get]
        else
          pushd [eax+class\#.\#par\#.get]
          popd  target
        end if
        if ~target eq eax
          pop eax
        end if
      end if
    else        ; by method
      if ~target eq eax
        push eax
      end if
      exec obj, class\#:\#par\#.get
      if ~target eq eax
        mov target, eax
        pop eax
      end if
    end if
  \}
}


macro set obj, param, value {
local flag

  flag equ FALSE

  match class:par, param \{
    flag equ TRUE
  \}

  match =FALSE, flag \{
    disp 2, "Error! Invalid syntax. Use class:method.", 13, 10
    err
  \}

  match class:par, param \{

    if class\#.\#par\#.set < sizeof.\#class ; field
      if obj eqtype eax
        if value eqtype eax
          mov [obj+class\#.\#par\#.set], value
        else
          pushd value
          popd  [obj+class\#.\#par\#.set]
        end if
      else
        if value eq eax
          push ecx
          mov  ecx, obj
          mov [ecx+class\#.\#par\#.set], value
          pop ecx
        else
          push eax
          mov  eax, obj
          if value eqtype eax
            mov [eax+class\#.\#par\#.set], value
          else
            pushd value
            popd  [eax+class\#.\#par\#.set]
          end if
          pop eax
        end if
      end if
    else        ; by method
      push eax
      exec obj, class\#:\#par\#.set, value
      pop  eax
    end if
  \}
}


; returns ZF = 1 if the type matches
; returns ZF = 0 if the type does not matches.

macro istype ptrobj, class {
  local ..itis, ..loop
        push    ecx

  if ptrobj eqtype eax    ; register
    if ~ptrobj eq ecx
        mov     ecx, ptrobj
    end if
  else
        mov     ecx, ptrobj
  end if

..loop:
        mov     ecx, [ecx]    ; get vtable, or the parent vtable
        jecxz   ..itis        ; if jump, ZF=0
        cmp     ecx, vtables.#class
        jne     ..loop
; here ZF = 1
..itis:
        pop     ecx
}
Changes to freshlib/macros/allmacros.inc.
17
18
19
20
21
22
23

24
25
17
18
19
20
21
22
23
24
25
26







+


include '_struct.inc'
include '_stdcall.inc'
include '_display.inc'
include '_itext.inc'
include '_globals.inc'
include '_datamacros.inc'
include '_dispatch.inc'
include '_realobjects.inc'

include '%TargetOS%/allmacros.inc'
Changes to freshlib/simpledebug/Linux/debug.asm.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
28
29
30
31
32
33
34






35
36
37
38
39
40
41







-
-
-
-
-
-







        int     $80

        popad
        return
endp


macro Output string {
if defined options.DebugMode & options.DebugMode = 1
        stdcall Output, string
end if
}


proc GetTimestamp
begin
        pushad
        mov     eax, 78
        mov     ebx, _timestamp
        xor     ecx, ecx
Changes to freshlib/simpledebug/Win32/debug.asm.
35
36
37
38
39
40
41















42
43
44
45
46
47
48
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







        invoke  GetStdHandle, STD_ERROR_HANDLE
        mov     [debug_con_handle], eax
        invoke  SetConsoleTitleW, cConsoleTitle
        return
endp
end if


if (defined options.DebugMode & options.DebugMode)
finalize FinishDebugConsole
.string rb 10
begin
        invoke  WriteFile, [STDERR], ___CloseMsg, ___CloseMsg.length, 0, 0
        lea     eax, [.string]
        invoke  ReadFile, [STDIN], eax, 1, 0, 0
        return
endp

___CloseMsg text "Press ENTER to close."

end if


maxConsoleWrite = 1024

proc Output, .ptrStr
.dummy dd ?
begin
        pushad
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
84
85
86
87
88
89
90






91
92
93
94
95
96
97







-
-
-
-
-
-








.finish:
        popad
        return
endp


macro Output string {
if defined options.DebugMode & options.DebugMode = 1
        stdcall Output, string
end if
}


proc GetTimestamp
begin
        pushad
        invoke  GetTickCount
        mov     [esp+4*regEAX], eax
        popad
Changes to freshlib/simpledebug/debug.asm.
10
11
12
13
14
15
16



17
18
19
20
21
22
23
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26







+
+
+







;  Dependencies: Not dependent on other libraries.
;
;  Notes: use options.DebugMode={1|0} to enable/disable debug output of this library.
;_________________________________________________________________________________________
module "Simple debug library"

SimpleDebugLoaded = 1

include "%TargetOS%/debug.asm"


match =DBG_CHAR_NEWLINE, DBG_CHAR_NEWLINE {
  DBG_CHAR_NEWLINE equ $0d, $0a
}


macro dbrk {
48
49
50
51
52
53
54
















55
56
57
58
59
60
61
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







        stdcall Output, ..msg
        jmp     ..skip
  ..msg db msg, DBG_CHAR_NEWLINE, 0

  label ..skip
}



macro Output string {
if defined options.DebugMode & options.DebugMode = 1
        stdcall Output, string
end if
}


macro OutputLn string {
if defined options.DebugMode & options.DebugMode = 1
        stdcall Output, string
        stdcall Output, <" ", DBG_CHAR_NEWLINE>
end if
}



proc OutputMemory, .ptr, .size
begin
        pushad

        mov     esi, [.ptr]
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
164
165
166
167
168
169
170









171
172
173
174
175
176
177







-
-
-
-
-
-
-
-
-







macro OutputNumber number, radix, digits {
if defined options.DebugMode & options.DebugMode
        stdcall OutputNumber, number, radix, digits
end if
}


regEDI = 0
regESI = 1
regEBP = 2
regESP = 3
regEBX = 4
regEDX = 5
regECX = 6
regEAX = 7


proc OutputRegister, .reg, .radix
begin
        pushad

        cmp     [.reg], 7
        ja      .exit
254
255
256
257
258
259
260


261
262
263
264
265
266
267


268
269
270
271
272
273
274
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288







+
+







+
+







endg



proc __simpStrLength;, .pString
begin
        mov     ecx, [esp+4]
        jecxz   .ret

.scan:
        cmp     byte [ecx], 0
        lea     ecx, [ecx+1]
        jne     .scan

        stc
        sbb     ecx, [esp+4]

.ret:
        retn 4
endp


;*****************************************************
; NumToStrF:
;   Converts signed integer value to string.
359
360
361
362
363
364
365
366
367
368
369
370
373
374
375
376
377
378
379


380
381
382







-
-



    das
    stosb
    return
endp



include "%TargetOS%/debug.asm"



endmodule
Changes to freshlib/system/Linux/files.asm.
25
26
27
28
29
30
31
32
33
34
35
36
37






38
39
40
41



42
43
44
45
46
47
48






49
50
51
52
53
54
55
25
26
27
28
29
30
31






32
33
34
35
36
37
38



39
40
41
42






43
44
45
46
47
48
49
50
51
52
53
54
55







-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+







faReadWrite  = O_RDWR

faOpenAlways   = O_CREAT             ; if the file does not exists it will be created.
faCreateAlways = O_CREAT or O_TRUNC  ; Creates new file always. If the file exists, truncates it.
faCreateOnly   = O_CREAT or O_EXCL   ; Creates new file only if not exists, else error.



initialize InitStdHandles
begin
  if used STDIN
        mov     dword [__std_handle_in], 0
  end if
if used STDIN | used STDOUT | used STDERR
  initialize InitStdHandles
  begin
    if used STDIN
          mov     dword [__std_handle_in], 0
    end if

  if used STDOUT
        mov     dword [__std_handle_out], 1
  end if
    if used STDOUT
          mov     dword [__std_handle_out], 1
    end if

  if used STDERR
        mov     dword [__std_handle_err], 2
  end if
        return
endp

    if used STDERR
          mov     dword [__std_handle_err], 2
    end if
          return
  endp
end if



body FileOpenAccess
begin
        push    edx ecx ebx

Changes to freshlib/system/Linux/timers.asm.
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36







-
+







    __FlagTimerTerminate  dd ?
  end if
endg



if used TimerCreate
  if ~(defined options.DebugMode & options.DebugMode=1)
  if ~(defined options.DebugMode.NoTimers & options.DebugMode.NoTimers)

initialize InitLinuxTimers
  .action lnx_sigaction
  .timer lnx_sigevent
  .time  lnx_itimerspec
begin
; set the signal handler.
54
55
56
57
58
59
60
61

62
63
64
65
66
67

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91

92
93
94
95
96
97
















98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116


117

118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
54
55
56
57
58
59
60

61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117













118

119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144



145
146
147
148
149
150
151







-
+





-
+














-
+









+





-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
-
-
-
-
-
-
-
-
-
-
-
-

-
+
+

+



-


+
















-
-
-







        mov     [ecx+lnx_sigevent.notify], SIGEV_SIGNAL
        mov     [ecx+lnx_sigevent.signo], SIGALRM
        mov     [ecx+lnx_sigevent.value], 0             ; not used but must be set - the function fails without it...
        mov     edx, __InternalTimerID

        int $80

;        DebugMsg 'Interval timer created.'
        DebugMsg 'Interval timer created.'

; then start a thread that will process timer expiration events.

        stdcall ThreadCreate, __TimerHandler, 0

;        DebugMsg 'Timer thread created'
        OutputValue 'Timer thread created. ID=$', eax, 16, 8

        mov     [__InternalTimerThread], eax

; start the timer
        mov     ebx, [__InternalTimerID]
        mov     eax, sys_timer_settime
        lea     edx, [.time]
        mov     [edx+lnx_itimerspec.it_interval.tv_sec], 0
        mov     [edx+lnx_itimerspec.it_interval.tv_nsec], __sys_time_slice*1000000
        mov     [edx+lnx_itimerspec.it_value.tv_sec], 0
        mov     [edx+lnx_itimerspec.it_value.tv_nsec], __sys_time_slice*1000000
        xor     esi, esi
        int $80

;        DebugMsg 'Timer started'
        DebugMsg 'Timer started'

        return
endp




finalize FreeLinuxTimers
begin

; stop the timer
        mov     eax, sys_timer_delete
        mov     ebx, [__InternalTimerID]
        int $80

;        DebugMsg 'Timer stopped.'
        DebugMsg 'Timer stopped.'


        mov     [__FlagTimerTerminate], 1

; signal the thread (because it is probably in waiting state.
match =native, LinuxThreads {
        mov     eax, sys_tkill
        mov     ebx, [__InternalTimerThread]
        mov     ecx, SIGRTMAX
        int     $80
}

match =posix, LinuxThreads {
        cinvoke pthread_kill, [__InternalTimerThread], SIGRTMAX
}

        cmp     [__InternalTimerThread], 0
        je      .finish

; then stop the handling thread
        mov     [__FlagTimerTerminate], 1

match =native, LinuxCode {
        mov     eax, sys_kill
        mov     ebx, [__InternalTimerThread]
        mov     ecx, SIGRTMAX
}

match =posix, LinuxCode {
        cinvoke pthread_kill, [__InternalTimerThread], SIGRTMAX
}

; waiting to timer thread to finish. This is bad implementation,
;here should be timer wait with signal terminate on timeout.
; here should be timer wait with signal terminate on timeout.

@@:
        stdcall Sleep, 10
        cmp     [__InternalTimerThread], 0
        jne     @b

;        DebugMsg 'Timer thread terminated.'

.finish:
        DebugMsg 'Timer thread terminated.'
        return
endp
  end if
end if




; This procedure is called by the system on every time quantum.
; It is Linux signal handler, so the actions this procedure can
; perform are limited.

proc __TimerProc, .signal
begin
        push    ebx edi

        cmp     [fGlobalTerminate], 0
        jne     .exit

        lea     eax, [__ptrFirstTimer]
        xor     edi, edi

.loop:
        mov     eax, [eax+TTimer.next]
        test    eax, eax
        jz      .end_timers
168
169
170
171
172
173
174


175
176
177
178
179
180
181
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185







+
+







        jge     @b
        jmp     .loop


.end_timers:
        test    edi, edi
        jz      .exit

; signal the timers thread is some timer is changed.

match =native, LinuxThreads {
        mov     eax, sys_tkill
        mov     ebx, [__InternalTimerThread]
        mov     ecx, SIGRTMAX
        int     $80
}
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
262
263
264
265
266
267
268

269
270
271
272
273
274
275
276







-
+









.end_list:
        cmp     [.remain], 0
        jne     .from_begin

; wait for signal
        mov     eax, sys_pause
        mov eax, sys_pause
        int $80
        jmp     .from_begin

.quit:
        mov     [__InternalTimerThread], 0

        stdcall Terminate, 0
Changes to freshlib/system/Win32/timers.asm.
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36







-
+







    __InternalTimerID     dd ?
    __InternalTimerThread dd ?
  end if
endg



if used TimerCreate
if used TimerCreate & ~ ( defined options.DebugMode.NoTimers & options.DebugMode.NoTimers )

initialize InitWin32Timers
begin
        invoke  SetTimer, 0, 0, __sys_time_slice, __TimerProc
        mov     [__InternalTimerID], eax

        return
Changes to freshlib/test_code/I18nTest.asm.
101
102
103
104
105
106
107
108
109
110
101
102
103
104
105
106
107


108







-
-



Istring5 itext <EN:'3. Translation tool (part of Fresh IDE) that allows to edit all such strings from one place.'>,       \
               <DE:'3. Translation-Tool (Teil von Fresh IDE), die alle diese Strings von einem Ort bearbeiten konnen.'>,      \
               <SP:'3. Herramienta de traducción (parte de Fresh IDE) que permite editar todas esas cadenas de un lugar.'>,  \
               <BG:'3. ИнÑтрумент за превод (чаÑÑ‚ от Fresh IDE) който позволÑва да Ñе редактират Ñтринговете за различни езици от едно мÑÑто.'>

@AllImportEmbeded       ; or @AllImportSection
@AllDataEmbeded         ; or @AllDataSection

Changes to freshlib/test_code/I18nTest.fpr.

cannot compute difference between binary files

Changes to freshlib/test_code/test_real_obj.fpr.

cannot compute difference between binary files

Changes to freshlib/test_code0/TestGround.asm.
19
20
21
22
23
24
25
26
27
28
29
30
31






32
33
34
35
36
37
38
39
40
41








42
43
44
45
46
47
48
19
20
21
22
23
24
25






26
27
28
29
30
31
32
33








34
35
36
37
38
39
40
41
42
43
44
45
46
47
48







-
-
-
-
-
-
+
+
+
+
+
+


-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+







iglobal

__TestData:

frmMainForm:
  if used frmMainForm
        ObjTemplate  tfParent or tfEnd, TForm, frmMain, \
                     x, 300,        \
                     y, 250,        \
                     width, 360,    \
                     height, 240,   \
                     Visible, TRUE, \
                     Caption, 'FreshLib minimal application test.'
                     x = 300,        \
                     y = 250,        \
                     width = 360,    \
                     height = 240,   \
                     Visible = TRUE, \
                     Caption = 'FreshLib minimal application test.'

           ObjTemplate tfChild or tfEnd, TButton, btnOpenModal,                      \
                       x, 50,                                                       \
                       y, 50,                                                       \
                       width, 120,                                                  \
                       height, 75,                                                  \
                       Visible, TRUE,                                               \
                       TextAlign, dtfAlignCenter or dtfAlignMiddle or dtfWordWrap , \
                       Caption, 'Click to check your assembly skills.',             \
                       OnClick, OpenModalForm
                       x = 50,                                                       \
                       y = 50,                                                       \
                       width = 120,                                                  \
                       height = 75,                                                  \
                       Visible = TRUE,                                               \
                       TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfWordWrap , \
                       Caption = 'Click to check your assembly skills.',             \
                       OnClick = OpenModalForm
  end if

__TestDataSize = $ - __TestData
endg



Changes to freshlib/test_code0/TestLib.asm.
38
39
40
41
42
43
44
45
46


47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71

72
73
74
75
76
77
78
38
39
40
41
42
43
44


45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

66
67
68
69
70

71
72
73
74
75
76
77
78







-
-
+
+


-
+
















-
+




-
+









include '%lib%/freshlib.asm'

; use one and only one of the following files.
;
;include 'TestGroundSplitGrid.asm'
;include 'TestGroundNull.asm'
;include  'TestGround.asm'
;include 'TestGroundNull.asm'                   ; in order to check whether for compilation of dead code.
include  'TestGround.asm'
;include 'TestGroundComplex.asm'
;include 'TestGroundKeyboard.asm'
include 'TestGroundFreshEdit.asm'
;include 'TestGroundFreshEdit.asm'
;include 'TestGroundConfig.asm'
;include 'TestGroundDirFunctions.asm'
;include  'TestGrids.asm'
;include 'TestTreeView.asm'
;include 'TestResizeEvents.asm'




if TargetOS eq Linux
;  rb 343       ; this bytes simply make ELF file to be loadable.
              ; there is a bug somewhere in the ELF generator (FASM or possibly ELF macros)
              ; that makes some sizes of the ELF executable not loadable. (the Linux loader crashes with SEGFAULT)
end if

uglobal
  buffer rb 256
;  buffer rb 256
endg

iglobal
  ; The example from RFC-1951
  TestArray dw 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 2, 0, 4, 0, 4, 0
;  TestArray dw 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 2, 0, 4, 0, 4, 0
endg

; Main Program
start:

DebugMsg 'Before initializing.'
        InitializeAll
Added freshlib/test_code0/TestMenu.asm.

















































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..:: Fresh IDE ::..  template project.                                                |
;|_______________________________________________________________________________________|
;
;  Description: FreshLib portable console application.
;
;  Target OS: Any, supported by FreshLib
;
;  Dependencies: FreshLib
;
;  Notes:
;_________________________________________________________________________________________

include "%lib%/freshlib.inc"

@BinaryType GUI, compact

options.DebugMode = 1
  options.DebugMode.NoTimers = 0
  options.DebugMode.XSync = 0
  options.DebugMode.XErrors =0

options.ShowSizes = 1
options.SkipZeroSizes = 0

ThemeGUI equ win_gui

include "%lib%/freshlib.asm"


iglobal
TemplateMainForm:
        ObjTemplate  tfParent or tfEnd, TForm, frmMain, \
                     x = 200,          \
                     y = 200,          \
                     width = 320,    \
                     height = 240,   \
                     OnCreate = FormOnCreate,    \
                     OnClose = MainFormOnClose,  \
                     OnDestroy = FormOnDestroy,  \
                     Caption = 'Popup menu test'

          ObjTemplate tfChild, TEdit, editTest,                 \
                     x = 10, y = 200, width = 300, height = 24, \
                     Text = "This is test TEdit control",       \
                     Visible = TRUE

          ObjTemplate tfParent, TActionList, ActionList1,    \
                     ImgIcons = imgMenuList

             ObjTemplate tfChild, TAction, actCheck,                \
                         Caption = "Check it", HintText = "Action that can be checked and unchecked.",         \
                         OnExecute = ActionOnCheck,                                                                \
                         IconIndex = 9

             ObjTemplate tfChild, TAction, actNew,                \
                         Caption = "New", HintText = "Create new file.",         \
                         OnExecute = ActionOnExecute,                                                     \
                         IconIndex = 0

             ObjTemplate tfChild, TAction, actOpen,                \
                         Caption = "Open", HintText = "Open file for editing.",         \
                         OnExecute = ActionOnExecute,                                                     \
                         IconIndex = 1

             ObjTemplate tfChild, TAction, actClean,                                                            \
                         Caption = "Cleanup list", HintText = "Removes not existing files from the list.",      \
                         OnExecute = ActionOnExecute,                                                           \
                         IconIndex = -1

             ObjTemplate tfChild, TAction, actSave,                \
                         Caption = "Save", HintText = "Save edited file to the disk.",         \
                         OnExecute = ActionOnExecute,                                                     \
                         IconIndex = 2

             ObjTemplate tfChild, TAction, actSaveAs,                \
                         Caption = "Save As", HintText = "Save edited file with different name.",         \
                         OnExecute = ActionOnExecute,                                                     \
                         IconIndex = 22

             ObjTemplate tfChild, TAction, actSaveAll,                \
                         Caption = "Save All", HintText = "Save all edited files to the disk.",         \
                         OnExecute = ActionOnExecute,                                                     \
                         IconIndex = 23

             ObjTemplate tfChild, TAction, actClose,                \
                         Caption = "Close", HintText = "Close current edited file.",         \
                         OnExecute = ActionOnExecute,                                                     \
                         IconIndex = 21

             ObjTemplate tfChild, TAction, actCloseAll,                \
                         Caption = "Close All", HintText = "Close all edited files and the project.",         \
                         OnExecute = ActionOnExecute,                                                     \
                         IconIndex = 24

             ObjTemplate tfChild or tfEnd, TAction, actExit,                \
                         Caption = "Exit", HintText = "Exit Fresh IDE.",         \
                         OnExecute = ActionOnExecute,                                                     \
                         IconIndex = -1


          ObjTemplate tfChild, TButton, btnSkinWin,                     \
                     x = 60, y = 10, width = 84, height = 24,           \
                     Caption = "Win skin",                              \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle,      \
                     Visible = TRUE,                                    \
                     OnClick = SetWinSkin

          ObjTemplate tfChild, TButton, btnSkinFlat,                    \
                     x = 146, y = 10, width = 84, height = 24,          \
                     Caption = "Flat skin",                             \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle,      \
                     Visible = TRUE,                                    \
                     OnClick = SetFlatSkin

          ObjTemplate  tfChild, TButton, btnOpenMenu,         \
                     x = 10,         \
                     y = 10,         \
                     width = 32,     \
                     height = 32,    \
                     Icon = [iconMenu],         \
                     IconPosition = iposCenter, \
                     Visible = TRUE,            \
                     OnClick = OpenMenuClick,   \
                     OnKeyPressed = ButtonKeyPressed

          ObjTemplate tfChild, TButton, btnChangeAction1,               \
                     x = 146, y = 52, width = 84, height = 24,          \
                     Caption = "Set act. 1",                               \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle,      \
                     Visible = TRUE,                                    \
                     OnClick = SetAction1

          ObjTemplate tfChild, TButton, btnChangeAction1,               \
                     x = 146, y = 78, width = 84, height = 24,          \
                     Caption = "Set act. 2",                               \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle,      \
                     Visible = TRUE,                                    \
                     OnClick = SetAction2

          ObjTemplate tfChild, TButton, btnWithAction2,         \
                     x = 10, y = 78, width = 100, height = 24,           \
                     IconPosition = iposLeft, TextAlign = dtfAlignLeft or dtfAlignMiddle, \
                     Action = [actExit],                                \
                     Visible = TRUE

          ObjTemplate tfChild, TButton, btnWithAction1,                 \
                     x = 10, y = 52, width = 100, height = 24,           \
                     IconPosition = iposLeft, TextAlign = dtfAlignLeft or dtfAlignMiddle, \
                     Action = [actCheck],                                \
                     Visible = TRUE

          ObjTemplate tfChild, TCheckbox, cbEnableDisable3,              \
                     x = 10, y = 130, width = 130, height = 24,          \
                     Caption = "Enable action",                          \
                     OnClick = EnableActionClick,                        \
                     Visible = TRUE

          ObjTemplate tfChild, TCheckbox, cbEnableDisable2,     \
                     x = 146, y = 130, width = 100, height = 24,         \
                     Action = [actCheck],                                \
                     Visible = TRUE

          ObjTemplate tfChild or tfEnd, TCheckbox, cbEnableDisable,     \
                     x = 146, y = 104, width = 100, height = 24,         \
                     Action = [actCheck],                                \
                     Visible = TRUE


TemplateMainMenu:
      ObjTemplate  tfEnd, TMenu, mainMenu,              \
        Visible = FALSE

TemplateSubMenu:
     ObjTemplate tfEnd, TMenu, subMenu, \
        Enabled = TRUE,                \
        Caption = "Reopen",             \
        Visible = FALSE



  getfile imgMenu, "_test_images/menu.png"

          dd imgMenuList.size
  getfile imgMenuList, "_test_images/img_list.png"

  getfile cfgFlat, "theme_flat.cfg"
          dd 0

  getfile cfgWin,  "theme_win.cfg"
          dd 0

endg


uglobal
  iconMenu dd ?
endg


;rb 423


start:
        InitializeAll


        create  [pApplication], TApplication

        call    GUI.Init

        stdcall CreateFromTemplate, TemplateMainForm, 0
        set     [pApplication], TApplication:MainWindow, frmMain

        set     [frmMain], TWindow:Visible, TRUE                ; must be set visible after creation, because it loads
                                                                ; needed images in OnCreate event handler.


        stdcall CreateFromTemplate, TemplateMainMenu, 0
        stdcall CreateFromTemplate, TemplateSubMenu, 0

        exec    [mainMenu], TMenu:AddItem, mitAction, [actCheck]
        exec    [mainMenu], TMenu:AddItem, mitAction, [actNew]
        exec    [mainMenu], TMenu:AddItem, mitSubmenu, [subMenu]
        exec    [mainMenu], TMenu:AddItem, mitAction, [actOpen]
        exec    [mainMenu], TMenu:AddItem, mitSeparator,
        exec    [mainMenu], TMenu:AddItem, mitAction, [actSave]
        exec    [mainMenu], TMenu:AddItem, mitAction, [actSaveAs]
        exec    [mainMenu], TMenu:AddItem, mitAction, [actSaveAll]
        exec    [mainMenu], TMenu:AddItem, mitSeparator, 0
        exec    [mainMenu], TMenu:AddItem, mitAction, [actClose]
        exec    [mainMenu], TMenu:AddItem, mitAction, [actCloseAll]
        exec    [mainMenu], TMenu:AddItem, mitSeparator, 0
        exec    [mainMenu], TMenu:AddItem, mitAction, [actExit]


        exec    [actCheck],   TAction:SetAccelerator, Ctrl+Shift, "N"
        exec    [actNew],     TAction:SetAccelerator, Ctrl, "N"
        exec    [actOpen],    TAction:SetAccelerator, Ctrl, "O"
        exec    [actSave],    TAction:SetAccelerator, Ctrl, "S"
        exec    [actSaveAll], TAction:SetAccelerator, Ctrl+Shift, "S"
        exec    [actClose],   TAction:SetAccelerator, Ctrl+fkScancode, keyF4
        exec    [actExit],    TAction:SetAccelerator, Alt, "X"

        set     [actCheck], TAction:Checked, 1
        set     [actCheck], TAction:Enabled, 0

;        set     [cbEnableDisable2], TCheckbox:Enabled, 0


        exec    [subMenu], TMenu:AddItem, mitAction, [actClean]
        exec    [subMenu], TMenu:AddItem, mitSeparator, 0
        exec    [subMenu], TMenu:AddItem, mitString, "/home/johnfound/Fresh/source/Fresh.fpr"
        exec    [subMenu], TMenu:AddItem, mitString, "/home/johnfound/Fresh/source/Fresh.asm"
        exec    [subMenu], TMenu:AddItem, mitString, "/home/johnfound/Fresh/freshlib/freshlib.inc"

        stdcall Run

        FinalizeAll
        stdcall TerminateAll, 0



; Sample event handlers. They work with other objects on the form.

proc FormOnCreate as TObject.OnCreate
begin
        DebugMsg "Form OnCreate event handler."

        stdcall CreateImagePNG, imgMenu, imgMenu.size
        mov     [iconMenu], eax

        return
endp



proc FormOnDestroy as TObject.OnDestroy
begin
        DebugMsg "MainForm destroy event handler."
        return
endp



proc MainFormOnClose as TForm.OnClose
begin
        DebugMsg "Main form OnClose event handler"
        clc
        return
endp




proc OpenMenuClick as TButton.OnClick
begin
        exec    [mainMenu], TMenu:Show, [btnOpenMenu], 0, 32
        return
endp


proc ButtonKeyPressed as TWindow.OnKeyPressed
begin
        stdcall CreateKeyName, [.utf8], [.scancode], [.kbdState]
        push    eax

        stdcall StrPtr, eax
        OutputLn  eax

        OutputValue "    UTF-8: $", [.utf8], 16, 8
        OutputValue "Scan code: $", [.scancode], 16, 8
        OutputValue "    State: $", [.kbdState], 16, 8
        DebugMsg "     "

        stdcall StrDel
        return
endp


proc SetWinSkin as TButton.OnClick
begin
        stdcall StringToNamedArray, GUI.meta, cfgWin
        exec    [frmMain], TWindow:RefreshAll
        return
endp


proc SetFlatSkin as TButton.OnClick
begin
        stdcall StringToNamedArray, GUI.meta, cfgFlat
        exec    [frmMain], TWindow:RefreshAll
        return
endp



proc ActionOnExecute as TAction.OnExecute
begin
        mov     esi, [.Action]

        stdcall StrDupMem, 'Action "'
        mov     ebx, eax

        get     eax, [.Action], TAction:Caption

        stdcall StrCat, ebx, eax

        stdcall StrCat, ebx, '" executed from control $'

        stdcall NumToStr, [.Ctrl], ntsHex or ntsFixedWidth + 8
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax

        stdcall ShowMessage, [frmMain], smiInformation, "Action execution", ebx, smbOK

        stdcall StrDel, ebx
        return
endp




proc ActionOnCheck as TAction.OnExecute
begin
        get     eax, [.Action], TAction:Checked
        xor     eax, 1
        set     [.Action], TAction:Checked, eax
        return
endp



proc SetAction1 as TButton.OnClick
begin
        set     [btnWithAction1], TButton:Action, [actOpen]
        set     [btnWithAction2], TButton:Action, [actSaveAll]
        return
endp


proc SetAction2 as TButton.OnClick
begin
        set     [btnWithAction1], TButton:Action, [actCheck]
        set     [btnWithAction2], TButton:Action, [actClose]
        return
endp



proc EnableActionClick as TButton.OnClick
begin
        get     eax, [.self], TCheckbox:Checked

        set     [actCheck], TAction:Enabled, eax

        return
endp


Added freshlib/test_code0/TestMenu.fpr.

cannot compute difference between binary files

Added freshlib/test_code0/TestNewGUI.asm.












































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..:: Fresh IDE ::..  template project.                                                |
;|_______________________________________________________________________________________|
;
;  Description: FreshLib portable console application.
;
;  Target OS: Any, supported by FreshLib
;
;  Dependencies: FreshLib
;
;  Notes:
;_________________________________________________________________________________________

include "%lib%/freshlib.inc"

@BinaryType GUI, compact

options.DebugMode = 0
  options.DebugMode.NoTimers = 0
  options.DebugMode.XSync = 0
  options.DebugMode.XErrors =0

options.ShowSizes = 1
options.SkipZeroSizes = 0

ThemeGUI equ flat_gui

include "%lib%/freshlib.asm"


iglobal
TemplateMainForm:
        ObjTemplate  tfParent or tfEnd, TForm, frmMain, \
                     x = 100,        \
                     y = 50,         \
                     width = 600,    \
                     height = 520,   \
                     OnCreate = FormOnCreate,    \
                     OnClose = MainFormOnClose,  \
                     OnDestroy = FormOnDestroy,  \
                     Caption = 'The new GUI toolkit test form.'

          ObjTemplate  tfChild, TLabel, NONE,           \
                     x = 10, y = 10, width = 200, height = 24,  \
                     Caption = "Progress bar test:",            \
                     Visible = TRUE


          ObjTemplate  tfChild, TProgress, Progress1,           \
                     x = 38, y = 32, width = 200, height = 24,  \
                     Max = 100, Pos = 70,                       \
                     Visible = TRUE

          ObjTemplate  tfChild, TButton, btnArrowLeft,          \
                     x = 10,         \
                     y = 32,         \
                     width = 24,     \
                     height = 24,    \
                     Icon = [iconArrowLeft],            \
                     IconPosition = iposCenter,         \
                     Visible = TRUE, \
                     OnClick = ArrowLeftClick

          ObjTemplate  tfChild, TButton, btnArrowRight,          \
                     x = 242,         \
                     y = 32,         \
                     width = 24,     \
                     height = 24,    \
                     Icon = [iconArrowRight],      \
                     IconPosition = iposCenter,         \
                     Visible = TRUE, \
                     OnClick = ArrowRightClick


          ObjTemplate  tfChild, TLabel, NONE,                   \
                     x = 10, y = 75, width = 200, height = 24,  \
                     Caption = "Buttons test:",                 \
                     Visible = TRUE

          ObjTemplate  tfChild, TButton, btnDisabled,          \
                     x = 448,         \
                     y = 100,         \
                     width = 128,     \
                     height = 48,    \
                     TextAlign = dtfAlignJustify or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = "Disabled",        \
                     Icon = [iconTest1],      \
                     IconPosition = iposLeft,   \
                     Enabled = FALSE,         \
                     Visible = TRUE

          ObjTemplate  tfChild, TButton, btnChild1,          \
                     x = 10,         \
                     y = 100,         \
                     width = 407,     \
                     height = 242,    \
                     TextAlign = dtfAlignJustify or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = utf8_long,        \
                     Icon = [iconTest1],      \
                     IconPosition = iposLeft,   \
                     Visible = TRUE, \
                     OnClick = Button1Click

          ObjTemplate  tfChild, TButton, btnChild2,          \
                     x = 448,         \
                     y = 160,         \
                     width = 128,     \
                     height = 48,    \
                     TextAlign = dtfAlignJustify or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = utf8_string,           \
                     Icon = [iconTest2],         \
                     IconPosition = iposRight,   \
                     Enabled = TRUE,            \
                     Visible = TRUE, \
                     OnClick = Button2Click

          ObjTemplate  tfChild, TButton, btnChild3,          \
                     x = 448,         \
                     y = 220,         \
                     width = 128,     \
                     height = 122,    \
                     TextAlign = dtfAlignCenter or dtfAlignBottom or dtfCRLF or dtfWordWrap,\
                     Caption = "Workers of the world, unite!",           \
                     Icon = [iconTest3],         \
                     IconPosition = iposCenter,   \
                     Enabled = TRUE,            \
                     Visible = TRUE

          ObjTemplate  tfChild, TButton, btnAlignLeft,          \
                     x = 10,         \
                     y = 350,         \
                     width = 64,     \
                     height = 32,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Left',        \
                     Visible = TRUE, \
                     OnClick = LeftClick

          ObjTemplate  tfChild, TButton, btnAlignRight,          \
                     x = 84,         \
                     y = 350,        \
                     width = 64,     \
                     height = 32,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Right',        \
                     Visible = TRUE, \
                     OnClick = RightClick

          ObjTemplate  tfChild, TButton, btnAlignCenter,          \
                     x = 158,         \
                     y = 350,         \
                     width = 64,     \
                     height = 32,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Center',        \
                     Visible = TRUE, \
                     OnClick = CenterClick

          ObjTemplate  tfChild, TButton, btnAlignJust,          \
                     x = 232,        \
                     y = 350,        \
                     width = 64,     \
                     height = 32,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Justify',     \
                     Visible = TRUE,          \
                     OnClick = JustifyClick

          ObjTemplate  tfChild, TButton, btnAlignTop,          \
                     x = 306,        \
                     y = 350,        \
                     width = 64,     \
                     height = 32,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Top',           \
                     Visible = TRUE,            \
                     OnClick = TopClick

          ObjTemplate  tfChild, TButton, btnAlignMiddle,          \
                     x = 380,        \
                     y = 350,        \
                     width = 64,     \
                     height = 32,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Middle',     \
                     Visible = TRUE, \
                     OnClick = MiddleClick

          ObjTemplate  tfChild, TButton, btnAlignBottom,          \
                     x = 454,        \
                     y = 350,        \
                     width = 64,     \
                     height = 32,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Bottom',     \
                     Visible = TRUE, \
                     OnClick = BottomClick

          ObjTemplate  tfChild, TLabel, NONE,                   \
                     x = 10, y = 390, width = 200, height = 24,  \
                     Caption = "Line editor test:",                 \
                     Visible = TRUE

          ObjTemplate tfChild, TEdit, editTest,                 \
                     Text = "This is simple line editor.",          \
                     x = 10, y=415, width=306, height=24,       \
                     MarginLeft= 2,                            \
                     MarginRight= 2,                           \
                     Visible = TRUE

          ObjTemplate  tfChild, TLabel, NONE,                   \
                     x = 10, y = 445, width = 200, height = 24, \
                     Caption = "Message boxes test:",           \
                     Visible = TRUE

          ObjTemplate  tfChild, TButton, btnMsgError,          \
                     x = 10,         \
                     y = 470,         \
                     width = 72,     \
                     height = 32,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Error',        \
                     Visible = TRUE, \
                     OnClick = ErrorClick

          ObjTemplate  tfChild, TButton, btnMsgWarning,          \
                     x = 88,         \
                     y = 470,        \
                     width = 72,     \
                     height = 32,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Warning',        \
                     Visible = TRUE, \
                     OnClick = WarningClick

          ObjTemplate  tfChild, TButton, btnMsgQuestion,          \
                     x = 166,         \
                     y = 470,         \
                     width = 72,     \
                     height = 32,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Question',        \
                     Visible = TRUE, \
                     OnClick = QuestionClick

          ObjTemplate  tfChild or tfEnd, TButton, btnMsgInfo,          \
                     x = 244,        \
                     y = 470,        \
                     width = 72,     \
                     height = 32,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Info',     \
                     Visible = TRUE,          \
                     OnClick = InfoClick



  getfile imgTestIcon1,  '_test_images/speech.png'
  getfile imgTestIcon2,  '_test_images/globe.png'
  getfile imgTestIcon3,  '_test_images/star.png'

  getfile imgArrowLeft,  '_test_images/left.png'
  getfile imgArrowRight, '_test_images/right.png'

  getfile imgFolder, "_test_images/folder.png"
  getfile imgFile,   "_test_images/document.png"


include "UTF8_examples.asm"


endg


uglobal
  iconTest1      dd ?
  iconTest2      dd ?
  iconTest3      dd ?
  iconArrowLeft  dd ?
  iconArrowRight dd ?

  iconFolder     dd ?
  iconFile       dd ?
endg



;rb 423


start:
        InitializeAll

        create  [pApplication], TApplication

        call    GUI.Init

        stdcall CreateFromTemplate, TemplateMainForm, 0

        set     [pApplication], TApplication:MainWindow, frmMain

        set     [frmMain], TWindow:Visible, TRUE                ; must be set visible after creation, because it loads
                                                                ; needed images in OnCreate event handler.

        stdcall Run

        FinalizeAll
        stdcall TerminateAll, 0



; Sample event handlers. They work with other objects on the form.

proc FormOnCreate as TObject.OnCreate
begin
        DebugMsg "Form OnCreate event handler."

        stdcall CreateImagePNG, imgTestIcon1, imgTestIcon1.size
        mov     [iconTest1], eax

        stdcall CreateImagePNG, imgTestIcon2, imgTestIcon2.size
        mov     [iconTest2], eax

        stdcall CreateImagePNG, imgTestIcon3, imgTestIcon3.size
        mov     [iconTest3], eax

        stdcall CreateImagePNG, imgArrowLeft, imgArrowLeft.size
        mov     [iconArrowLeft], eax

        stdcall CreateImagePNG, imgArrowRight, imgArrowRight.size
        mov     [iconArrowRight], eax

        stdcall CreateImagePNG, imgFolder, imgFolder.size
        mov     [iconFolder], eax

        stdcall CreateImagePNG, imgFile, imgFile.size
        mov     [iconFile], eax

        return
endp


proc FormOnDestroy as TObject.OnDestroy
begin
        DebugMsg "MainForm destroy event handler."
        return
endp




proc LeftClick as TButton.OnClick
begin
        get     eax, [btnChild1], TButton:TextAlign
        and     eax, not dtfHAlignMask
        or      eax, dtfAlignLeft

        set     [btnChild1], TButton:TextAlign, eax
        return
endp


proc RightClick as TButton.OnClick
begin
        get     eax, [btnChild1], TButton:TextAlign
        and     eax, not dtfHAlignMask
        or      eax, dtfAlignRight

        set     [btnChild1], TButton:TextAlign, eax
        return
endp


proc CenterClick as TButton.OnClick
begin
        get     eax, [btnChild1], TButton:TextAlign
        and     eax, not dtfHAlignMask
        or      eax, dtfAlignCenter

        set     [btnChild1], TButton:TextAlign, eax
        return
endp

proc JustifyClick as TButton.OnClick
begin
        get     eax, [btnChild1], TButton:TextAlign
        and     eax, not dtfHAlignMask
        or      eax, dtfAlignJustify

        set     [btnChild1], TButton:TextAlign, eax
        return
endp


proc TopClick as TButton.OnClick
begin
        get     eax, [btnChild1], TButton:TextAlign
        and     eax, not dtfVAlignMask
        or      eax, dtfAlignTop

        set     [btnChild1], TButton:TextAlign, eax
        return
endp

proc MiddleClick as TButton.OnClick
begin
        get     eax, [btnChild1], TButton:TextAlign
        and     eax, not dtfVAlignMask
        or      eax, dtfAlignMiddle

        set     [btnChild1], TButton:TextAlign, eax
        return
endp

proc BottomClick as TButton.OnClick
begin
        get     eax, [btnChild1], TButton:TextAlign
        and     eax, not dtfVAlignMask
        or      eax, dtfAlignBottom

        set     [btnChild1], TButton:TextAlign, eax
        return
endp


proc Button1Click as TButton.OnClick
begin
        DebugMsg 'Button1 clicked'
        return
endp



proc Button2Click as TButton.OnClick
begin
        DebugMsg 'Button2 clicked'
        return
endp



proc MainFormOnClose as TForm.OnClose
begin
        DebugMsg "Main form OnClose event handler"
        clc
        return
endp



;proc PaintMainFormBG as TWindow.OnPaint
;begin
;
;; tile test background
;        mov     esi, [.self]
;        mov     edi, [.canvas]
;        mov     ebx, [imgTest]
;        xor     edx, edx
;
;        test    ebx, ebx
;        jz      .finish
;
;.yloop:
;
;        xor     ecx, ecx
;
;.xloop:
;        stdcall BlendImage, edi, ecx, edx, ebx, 0, 0, [ebx+TImage.width], [ebx+TImage.height]
;
;        add     ecx, [ebx+TImage.width]
;        cmp     ecx, [edi+TImage.width]
;        jb      .xloop
;
;        add     edx, [ebx+TImage.height]
;        cmp     edx, [edi+TImage.height]
;        jb      .yloop
;
;.finish:
;        return
;endp



proc ButtonPaint as TWindow.OnPaint
begin
        stdcall DrawSolidRect, [.canvas], 40, 40, 140, 140, 0
        return
endp


proc ArrowLeftClick as TButton.OnClick
begin
        get     eax, [Progress1], TProgress:Pos

        dec     eax
        jns     @f

        mov     eax, 100

@@:
        set     [Progress1], TProgress:Pos, eax
        return
endp


proc ArrowRightClick as TButton.OnClick
begin
        get     eax, [Progress1], TProgress:Pos

        inc     eax
        cmp     eax, 100
        jbe     @f

        xor     eax, eax

@@:
        set     [Progress1], TProgress:Pos, eax
        return
endp




proc ErrorClick as TButton.OnClick
begin
        stdcall ShowMessage, [frmMain], smiError, "Dialog box test.", "This is test of common dialog boxes.", smbOK
        return
endp



proc WarningClick as TButton.OnClick
begin
        stdcall ShowMessage, [frmMain], smiWarning, "Dialog box test.", "This is test of common dialog boxes.", smbOK
        return
endp



proc QuestionClick as TButton.OnClick
begin
        stdcall ShowMessage, [frmMain], smiQuestion, "Dialog box test.", "This is test of common dialog boxes.", smbYes or smbNo or smbMaybe
        return
endp



proc InfoClick as TButton.OnClick
begin
        stdcall ShowMessage, [frmMain], smiInformation, "Dialog box test.", "This is test of common dialog boxes.", smbOK or smbCancel
        return
endp



Added freshlib/test_code0/TestNewGUI.fpr.

cannot compute difference between binary files

Changes to freshlib/test_code0/TestPNG.asm.
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26







-
+







;  Notes:
;_________________________________________________________________________________________

include "%lib%/freshlib.inc"

@BinaryType GUI, compact

options.DebugMode = 0
options.DebugMode = 1
options.ShowSizes = 1
options.SkipZeroSizes = 1
options.DebugMode.XSync = 0
options.DebugMode.XErrors =0


include "%lib%/freshlib.asm"
65
66
67
68
69
70
71

72



73
74
75
76
77
78
79
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83







+

+
+
+







uglobal
  ignore dd ?
endg


start:
        InitializeAll

        create  [pApplication], TApplication

        stdcall TestBackground


        stdcall CreateFromTemplate, TemplateMainForm, 0
        set     [pApplication], TApplication:MainWindow, frmMain

        stdcall Run

        FinalizeAll
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
144
145
146
147
148
149
150








151
152
153
154
155
156
157







-
-
-
-
-
-
-
-








proc Button1Click as TButton.OnClick
.img dd ?
begin
        pushad

        DebugMsg 'Button1 clicked'

        mov     eax, [frmMain]
        stdcall AllocateContext, [eax+TWindow.handle]
        jc      .end

        mov     ebx, eax
        stdcall SetDrawMode, eax, cmCopy


        stdcall CreateImagePNG, pngBackground, sizeof.pngBackground
        mov     [.img], eax

        mov     edi, PngFiles
        mov     ecx, xStart
        mov     edx, yStart
179
180
181
182
183
184
185
186
187












188
189
190
191
192
193
194
175
176
177
178
179
180
181


182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200







-
-
+
+
+
+
+
+
+
+
+
+
+
+







        jb      .loop

        mov     ecx, xStart
        add     edx, yStep
        jmp     .loop

.finish_demo:
        stdcall DrawImage, ebx, [.img], 0, 0
        stdcall ReleaseContext, ebx

        get     ebx, [frmMain], TWindow:Canvas
        mov     esi, [.img]

        stdcall BlendImage, ebx, 0, 0, esi, 0, 0, [esi+TImage.width], [esi+TImage.height]

;        exec    [frmMain], TWindow:Refresh

        mov     eax, [frmMain]
        stdcall _RefreshWindow, [eax+TWindow.handle]

        DebugMsg "Draw on window"
.end:
        popad
        return
endp



205
206
207
208
209
210
211
212

213
214
215

216
217
218
219
220
221
222
211
212
213
214
215
216
217

218
219
220

221
222
223
224
225
226
227
228







-
+


-
+








        DebugMsg 'Button2 clicked'

        stdcall FontCreate4, 'DejaVu', 20, 1000, 0
        mov     [.font], eax

        mov     eax, [frmMain]
        stdcall AllocateContext, [eax+TWindow.handle]
        stdcall __AllocateContext, [eax+TWindow.handle]
        mov     [.context], eax

        stdcall SetDrawMode, eax, cmCopy
        stdcall __SetDrawMode, eax, cmCopy

        stdcall CreateImagePNG, pngBackground, sizeof.pngBackground
        mov     [.bkgnd], eax

        stdcall CreateImagePNG, pngBackground, sizeof.pngBackground
        mov     [.work], eax

391
392
393
394
395
396
397
398

399
400
401
402
403
404
405
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411







-
+








        stdcall DrawImage, [.context], [.bkgnd], 0, 0

        stdcall DestroyImage, [.bkgnd]
        stdcall DestroyImage, [.work]
        stdcall DestroyImage, [.art]

        stdcall ReleaseContext, [.context]
        stdcall __ReleaseContext, [.context]
        stdcall FontDestroy2, [.font]

        popad
        return

.terminate:
        pop     eax
Added freshlib/test_code0/TestSplitGrid.asm.
























































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..:: Fresh IDE ::..  template project.                                                |
;|_______________________________________________________________________________________|
;
;  Description: FreshLib portable console application.
;
;  Target OS: Any, supported by FreshLib
;
;  Dependencies: FreshLib
;
;  Notes:
;_________________________________________________________________________________________

include "%lib%/freshlib.inc"

@BinaryType GUI, compact

options.DebugMode = 1
  options.DebugMode.NoTimers = 0
  options.DebugMode.XSync = 0
  options.DebugMode.XErrors =0

options.ShowSizes = 1
options.SkipZeroSizes = 1

ThemeGUI equ flat_gui

include "%lib%/freshlib.asm"


iglobal

TemplateMainForm:
        ObjTemplate  tfParent or tfEnd, TForm, frmMain, \
                     x = 100,        \
                     y = 50,         \
                     width = 640,    \
                     height = 480,   \
                     OnCreate = FormOnCreate,    \
                     OnClose = MainFormOnClose,  \
                     OnDestroy = FormOnDestroy,  \
                     SplitGrid = SplitTest,      \
                     Caption = 'Split grids test form'


          ObjTemplate tfChild, TEdit, editDir,                 \
                     Text = "/home",          \
                     x = 10, y=10, width=370, height=24,       \
                     MarginLeft= 2,                            \
                     MarginRight= 2,                           \
                     OnCreate = EditOnCreate,                  \
                     SplitCell = SplitTest.cellEdit,           \
                     Visible = TRUE

          ObjTemplate  tfChild, TButton, btnArrowRight,          \
                     x = 384,        \
                     y = 10,         \
                     width = 24,     \
                     height = 24,    \
                     Icon = [iconArrowRight],      \
                     IconPosition = iposCenter,         \
                     SplitCell = SplitTest.cellButton,           \
                     Visible = TRUE, \
                     OnClick = ReadFolderClick

          ObjTemplate tfChild, TLabel, lblEmpty,                        \
                     SplitCell = SplitTest.cellEmpty,                   \
                     Caption = utf8_long,                                \
                     TextAlign = dtfAlignJustify or dtfAlignTop or dtfCRLF or dtfWordWrap,         \
                     Visible = TRUE

          ObjTemplate  tfChild or tfEnd, TTreeView, tvFolders,               \
                     x = 10, y = 40, width = 200, height = 200,              \
                     SplitCell = SplitTest.cellTree,                         \
\;                     OnFocusItem = TreeFocusItem,                            \
                     Visible = TRUE


include "UTF8_examples.asm"



SplitStart SplitTest

  Split stVert, 6, 24, 16, 48
    Split stHoriz or stOriginBR or stJustGap, 6, 64, 48, 200
      Cell cellEdit
      Cell cellButton

    Split stHoriz or stRelative, 6, 16384, 3000, 29000
      Cell cellTree
      Cell cellEmpty

SplitEnd


if ThemeGUI eq win_gui
  getfile imgArrowRight, '_test_images/right2.png'
  getfile imgFolder, "_test_images/folder2.png"
  getfile imgFile,   "_test_images/document2.png"
end if


if ThemeGUI eq flat_gui
  getfile imgArrowRight, '_test_images/right.png'

  getfile imgFolder, "_test_images/folder.png"
  getfile imgFile,   "_test_images/document.png"
end if


endg


uglobal
  iconArrowRight dd ?

  iconFolder dd ?
  iconFile   dd ?
endg


;rb 423


start:
        InitializeAll

        create  [pApplication], TApplication

        stdcall GUI.Init

        stdcall CreateFromTemplate, TemplateMainForm, 0

        set     [pApplication], TApplication:MainWindow, frmMain

        set     [frmMain], TWindow:Visible, TRUE                ; must be set visible after creation, because it loads
                                                                ; needed images in OnCreate event handler.

        stdcall Run

        FinalizeAll
        stdcall TerminateAll, 0



; Sample event handlers. They work with other objects on the form.

proc FormOnCreate as TObject.OnCreate
begin
        DebugMsg "Form OnCreate event handler."

        stdcall CreateImagePNG, imgArrowRight, imgArrowRight.size
        mov     [iconArrowRight], eax

        stdcall CreateImagePNG, imgFolder, imgFolder.size
        mov     [iconFolder], eax

        stdcall CreateImagePNG, imgFile, imgFile.size
        mov     [iconFile], eax

        return
endp


proc EditOnCreate as TObject.OnCreate
begin

      if TargetOS eq Win32

        set     [editDir], TEdit:Text, txt "c:\"

      else

        set     [editDir], TEdit:Text, txt "/home"

      end if

        return
endp


proc FormOnDestroy as TObject.OnDestroy
begin
        DebugMsg "MainForm destroy event handler."
        return
endp


proc MainFormOnClose as TForm.OnClose
begin
        DebugMsg "Main form OnClose event handler"
        clc
        return
endp





proc TreeFocusItem as TTreeView.OnFocusItem
begin
        mov     ebx, [.pItem]

        stdcall FileWriteString, [STDOUT], [ebx+TTreeViewItem.UserData]
        stdcall FileWriteString, [STDOUT], <txt 13, 10>

;        stdcall StrExtractExt, [ebx+TTreeViewItem.UserData]
;        jc      .finish
;
;        stdcall StrCompNoCase, eax, txt ".txt"
;        stdcall StrDel, eax
;        jnc     .finish


        stdcall LoadBinaryFile, [ebx+TTreeViewItem.UserData]
        jc      .finish

        push    eax

        set     [lblEmpty], TLabel:Caption, eax

        stdcall FreeMem ; from the stack

.finish:
        return
endp





proc ReadFolderClick as TButton.OnClick
begin
        pushad

        get     edi, [frmMain], TWindow:Cursor

        stdcall GetStockCursor, mcWait
        push    eax

        mov     eax, [frmMain]
        stdcall SetMouseCursor, [eax+TWindow.handle]

        stdcall ProcessSystemEvents

        mov     esi, [tvFolders]
        get     ebx, [editDir], TEdit:Text
        mov     edx, [esi+TTreeView._items]

        stdcall DeleteArrayItems, edx, 0, [edx+TArray.count]

        stdcall ___DoReadDir, ebx, edx, -1
        mov     [esi+TTreeView._items], edx
        jc      .error

.finish:
        stdcall StrDel, ebx

        OutputValue "Files tree items:", [edx+TArray.count], 10, 8

        exec    [tvFolders], TTreeView:__RebuildIndex
        exec    [tvFolders], TWindow:Refresh

        set     [frmMain], TWindow:Cursor, edi

        popad
        return

.error:
        stdcall GetErrorString, eax
        push    eax

        stdcall ShowMessage, [frmMain], smiError, "File error", eax, smbOK

        stdcall FreeErrorString ; from the stack
        jmp     .finish

endp




proc ___DoReadDir, .hDir, .pArray, .Level
begin
        pushad

        mov     edx, [.pArray]
        mov     ebx, [.Level]
        inc     ebx

        stdcall DirectoryRead, [.hDir]
        jc      .finish

        mov     esi, eax
        xor     ecx, ecx

        stdcall SortDirArray, esi, fdsByType

.loop:
        cmp     ecx, [esi+TArray.count]
        jae     .end_loop

        stdcall StrPtr, [esi+TArray.array + 8*ecx + TDirItem.hFilename]

        cmp     byte [eax], "."
        je      .next

;        Output  eax
;        DebugMsg ""

        stdcall StrDup, [.hDir]
        stdcall StrCharCat, eax, "/"
        stdcall StrCat, eax, [esi+TArray.array+8*ecx+TDirItem.hFilename]
        push    eax

        stdcall AddArrayItems, edx, 1

        push    [esi+TArray.array + 8*ecx + TDirItem.hFilename]         ; name
        pop     [eax+TTreeViewItem.caption]
        pop     [eax+TTreeViewItem.UserData]                            ; the full filename
        mov     [eax+TTreeViewItem.level], ebx
        mov     [eax+TTreeViewItem.state], tvisExpanded

        push    edx

        mov     edx, [iconFolder]
        cmp     [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory
        je      @f

        mov     edx, [iconFile]
        cmp     [esi+TArray.array + 8*ecx + TDirItem.Type], ftFile
        je      @f

        xor     edx, edx

@@:
        mov     [eax+TTreeViewItem.imgNormal], edx

        pop     edx

        cmp     [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory
        jne     .next

        stdcall StrDup, [.hDir]
        push    eax

        stdcall StrCharCat, eax, "/"
        stdcall StrCat, eax, [esi+TArray.array + 8*ecx + TDirItem.hFilename]

        stdcall ___DoReadDir, eax, edx, ebx

        stdcall StrDel ; from the stack

.next:
        inc     ecx
        jmp     .loop

.end_loop:
        stdcall FreeMem, esi

        clc
        xor     eax, eax

.finish:
        mov     [esp+regEAX*4], eax
        mov     [esp+regEDX*4], edx
        popad
        return
endp





Added freshlib/test_code0/TestSplitGrid.fpr.

cannot compute difference between binary files

Added freshlib/test_code0/TestTV.fpr.

cannot compute difference between binary files

Added freshlib/test_code0/TestTVmain.asm.























































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..:: Fresh IDE ::..  template project.                                                |
;|_______________________________________________________________________________________|
;
;  Description: FreshLib portable console application.
;
;  Target OS: Any, supported by FreshLib
;
;  Dependencies: FreshLib
;
;  Notes:
;_________________________________________________________________________________________

include "%lib%/freshlib.inc"

@BinaryType GUI, compact

options.DebugMode = 0
  options.DebugMode.NoTimers = 0
  options.DebugMode.XSync = 0
  options.DebugMode.XErrors =0

options.ShowSizes = 1
options.SkipZeroSizes = 1

ThemeGUI equ flat_gui

include "%lib%/freshlib.asm"


iglobal

TemplateMainForm:
        ObjTemplate  tfParent or tfEnd, TForm, frmMain, \
                     x = 100,        \
                     y = 50,         \
                     width = 418,    \
                     height = 510,   \
                     OnCreate = FormOnCreate,    \
                     OnClose = MainFormOnClose,  \
                     OnDestroy = FormOnDestroy,  \
                     Caption = 'The new GUI toolkit test form.'


          ObjTemplate tfChild, TEdit, editDir,                 \
                     Text = "/home",          \
                     x = 10, y=10, width=370, height=24,       \
                     MarginLeft= 2,                            \
                     MarginRight= 2,                           \
                     OnCreate = EditOnCreate,                  \
                     Visible = TRUE

          ObjTemplate  tfChild, TButton, btnArrowRight,          \
                     x = 384,        \
                     y = 10,         \
                     width = 24,     \
                     height = 24,    \
                     Icon = [iconArrowRight],      \
                     IconPosition = iposCenter,         \
                     Visible = TRUE, \
                     OnClick = ReadFolderClick

          ObjTemplate  tfChild or tfEnd, TTreeView, tvFolders,               \
                     x = 10, y = 40, width = 400, height = 460,              \
                     Visible = TRUE


if ThemeGUI eq win_gui
  getfile imgArrowRight, '_test_images/right2.png'
  getfile imgFolder, "_test_images/folder2.png"
  getfile imgFile,   "_test_images/document2.png"
end if


if ThemeGUI eq flat_gui
  getfile imgArrowRight, '_test_images/right.png'

  getfile imgFolder, "_test_images/folder.png"
  getfile imgFile,   "_test_images/document.png"
end if


endg


uglobal
  iconArrowRight dd ?

  iconFolder dd ?
  iconFile   dd ?
endg


;rb 423


start:
        InitializeAll

        create  [pApplication], TApplication

        stdcall GUI.Init

        stdcall CreateFromTemplate, TemplateMainForm, 0

        set     [pApplication], TApplication:MainWindow, frmMain

        set     [frmMain], TWindow:Visible, TRUE                ; must be set visible after creation, because it loads
                                                                ; needed images in OnCreate event handler.

        stdcall Run

        FinalizeAll
        stdcall TerminateAll, 0



; Sample event handlers. They work with other objects on the form.

proc FormOnCreate as TObject.OnCreate
begin
        DebugMsg "Form OnCreate event handler."

        stdcall CreateImagePNG, imgArrowRight, imgArrowRight.size
        mov     [iconArrowRight], eax

        stdcall CreateImagePNG, imgFolder, imgFolder.size
        mov     [iconFolder], eax

        stdcall CreateImagePNG, imgFile, imgFile.size
        mov     [iconFile], eax

        return
endp


proc EditOnCreate as TObject.OnCreate
begin

      if TargetOS eq Win32

        set     [editDir], TEdit:Text, txt "c:\"

      else

        set     [editDir], TEdit:Text, txt "/home"

      end if

        return
endp


proc FormOnDestroy as TObject.OnDestroy
begin
        DebugMsg "MainForm destroy event handler."
        return
endp


proc MainFormOnClose as TForm.OnClose
begin
        DebugMsg "Main form OnClose event handler"
        clc
        return
endp







proc ReadFolderClick as TButton.OnClick
begin
        pushad

        get     edi, [frmMain], TWindow:Cursor

        stdcall GetStockCursor, mcWait
        push    eax

        mov     eax, [frmMain]
        stdcall SetMouseCursor, [eax+TWindow.handle]

        stdcall ProcessSystemEvents

        mov     esi, [tvFolders]
        get     ebx, [editDir], TEdit:Text
        mov     edx, [esi+TTreeView._items]

        stdcall DeleteArrayItems, edx, 0, [edx+TArray.count]

        stdcall ___DoReadDir, ebx, edx, -1
        mov     [esi+TTreeView._items], edx
        jc      .error

.finish:
        stdcall StrDel, ebx

        OutputValue "Files tree items:", [edx+TArray.count], 10, 8

        exec    [tvFolders], TTreeView:__RebuildIndex
        exec    [tvFolders], TWindow:Refresh

        set     [frmMain], TWindow:Cursor, edi

        popad
        return

.error:
        stdcall GetErrorString, eax
        push    eax

        stdcall ShowMessage, [frmMain], smiError, "File error", eax, smbOK

        stdcall FreeErrorString ; from the stack
        jmp     .finish

endp




proc ___DoReadDir, .hDir, .pArray, .Level
begin
        pushad

        mov     edx, [.pArray]
        mov     ebx, [.Level]
        inc     ebx

        stdcall DirectoryRead, [.hDir]
        jc      .finish

        mov     esi, eax
        xor     ecx, ecx


        stdcall SortDirArray, esi, fdsByType

.loop:
        cmp     ecx, [esi+TArray.count]
        jae     .end_loop

        stdcall StrPtr, [esi+TArray.array + 8*ecx + TDirItem.hFilename]

        cmp     byte [eax], "."
        je      .next

;        Output  eax
;        DebugMsg ""

        stdcall AddArrayItems, edx, 1

        push    [esi+TArray.array + 8*ecx + TDirItem.hFilename]         ; name
        pop     [eax+TTreeViewItem.caption]
        mov     [eax+TTreeViewItem.level], ebx
        mov     [eax+TTreeViewItem.state], tvisExpanded

        push    edx

        mov     edx, [iconFolder]
        cmp     [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory
        je      @f

        mov     edx, [iconFile]
        cmp     [esi+TArray.array + 8*ecx + TDirItem.Type], ftFile
        je      @f

        xor     edx, edx

@@:
        mov     [eax+TTreeViewItem.imgNormal], edx

        pop     edx

        cmp     [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory
        jne     .next

        stdcall StrDup, [.hDir]
        push    eax

        stdcall StrCharCat, eax, "/"
        stdcall StrCat, eax, [esi+TArray.array + 8*ecx + TDirItem.hFilename]

        stdcall ___DoReadDir, eax, edx, ebx

        stdcall StrDel ; from the stack

.next:
        inc     ecx
        jmp     .loop

.end_loop:
        stdcall FreeMem, esi

        clc
        xor     eax, eax

.finish:
        mov     [esp+regEAX*4], eax
        mov     [esp+regEDX*4], edx
        popad
        return
endp




Changes to freshlib/test_code0/TestText.asm.
58
59
60
61
62
63
64

65
66
67
68
69
70
71
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72







+







                     OnClick, Button2Click
endg


rb 423




start:
        InitializeAll
        create  [pApplication], TApplication

        stdcall CreateFromTemplate, TemplateMainForm, 0
        set     [pApplication], TApplication:MainWindow, frmMain
100
101
102
103
104
105
106

107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122

123
124




125
126

127
128
129
130
131
132
133
134
135


136
137
138

139

140
141

142
143
144







145

146

147
148
149
150
151
152

153
154
155
156

157

158
159
160

161
162

163

164
165
166
167
168
169

170

171
172
173
174
175
176
177
178
179
180
181
182
183
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131

132
133
134
135
136





137
138
139
140
141
142

143
144

145
146


147
148
149
150
151
152
153
154
155

156
157
158
159
160
161

162
163
164
165
166
167

168
169
170

171
172
173
174

175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
193
194
195
196







+





-
+









-
+


+
+
+
+

-
+




-
-
-
-
-
+
+



+
-
+

-
+

-
-
+
+
+
+
+
+
+

+
-
+





-
+




+
-
+


-
+


+
-
+






+
-
+















proc Button2Click as TButton.OnClick
.font dd ?
.width dd ?
.height dd ?
.y      dd ?
.start  dd ?
begin
        pushad

        DebugMsg 'Button2 clicked'

        stdcall FontCreate4, 'Fixedsys Excelsior 3.01', 16, 600, ffItalic
        stdcall FontCreate4, 'Ubuntu', 16, 900, ffUnderline
        mov     [.font], eax

        stdcall CreateImage, 1024, 600
        mov     esi, eax

        mov     edi, [frmMain]
        stdcall AllocateContext, [edi+TWindow.handle]
        mov     edi, eax

        stdcall DrawSolidRect, esi, 0, 0, 1024, 600,  $d0d0d8
        stdcall DrawSolidRect, esi, 0, 0, 1024, 600,  $ffd0d0d8
        stdcall DrawSolidRect, esi, 320, 0, 320, 480, $ff0000ff

        stdcall GetFontMetrics, [.font]
        mov     [.height], eax


        stdcall GetTimestamp
        mov     ebx, eax
        mov     [.start], eax

        mov     edx, 7
        mov     ecx, -100

;TestStr text 'X'
;        stdcall DrawString2, esi, TestStr, 440, 280, [.font], $ff000000

        mov     ecx, 100
        mov     [.y], 0
        mov     ecx, 1000
        mov     [.y], 5

.loop:
; 85 characters text
;        stdcall DrawString2, esi, 'uon ravo s s smpe ex, spaye y reeype rary usng reeype cace.', -1, 150, [.y], [.font], $ff000000
        stdcall DrawString2, esi, 'Button BRAVO This is simple text, displayed by FreeType library using FreeType cache.', 0, [.y], [.font], $ffff0000
        stdcall DrawString2, esi, 'Button BRAVO This is simple text, displayed by FreeType library using FreeType cache.', -1, 150, [.y], [.font], $ff000000

;        stdcall GetTextBounds2, 'Button BRAVO This is simple text, displayed by FreeType library using FreeType cache.', [.font]
        mov     [.width], eax

        mov     [.width], eax
        mov     [.height], edx
        mov     edx, ebx
        add     ebx, [.y]
        neg     edx
;        stdcall DrawSolidRect, esi, 150, ebx, eax, 1, $ffff0000
;        stdcall DrawSolidRect, esi, 150, [.y], eax, 1, $ffff0000

;        stdcall GetTextBounds2, 'Button BRAVO This is simple text, displayed by FreeType library using FreeType cache.', -1, [.font]

        mov     eax, [.height]
        add     [.y], edx
        add     [.y], eax

        dec     ecx
        jnz     .loop

        stdcall GetTimestamp
        sub     eax, ebx
        sub     eax, [.start]

        stdcall NumToStr, eax, ntsUnsigned or ntsDec
        push    eax

        stdcall StrPtr, eax
        stdcall DrawString2, esi, eax, 40, 500, [.font], $ff000000
        stdcall DrawString2, esi, eax, -1, 40, 500, [.font], $ff000000
        stdcall StrDel ; from the stack

        stdcall NumToStr, [.width], ntsDec or ntsUnsigned
        stdcall NumToStr, [.width], ntsDec or ntsSigned
        push    eax

        stdcall StrPtr, eax
        stdcall DrawString2, esi, eax, 40, 520, [.font], $ff000000
        stdcall DrawString2, esi, eax, -1, 40, 520, [.font], $ff000000
        stdcall StrDel ; from the stack


        stdcall NumToStr, [.height], ntsDec or ntsUnsigned
        push    eax

        stdcall StrPtr, eax
        stdcall DrawString2, esi, eax, 40, 540, [.font], $ff000000
        stdcall DrawString2, esi, eax, -1, 40, 540, [.font], $ff000000
        stdcall StrDel ; from the stack




        stdcall DrawImage, edi, esi, 0, 0

        stdcall FontDestroy2, [.font]

        popad
        return
endp

Changes to freshlib/test_code0/TestText.fpr.

cannot compute difference between binary files

Added freshlib/test_code0/TestThemes.asm.




























































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..:: Fresh IDE ::..  template project.                                                |
;|_______________________________________________________________________________________|
;
;  Description: FreshLib portable console application.
;
;  Target OS: Any, supported by FreshLib
;
;  Dependencies: FreshLib
;
;  Notes:
;_________________________________________________________________________________________

include "%lib%/freshlib.inc"

@BinaryType GUI, compact

options.DebugMode = 0
  options.DebugMode.NoTimers = 1
  options.DebugMode.XSync = 0
  options.DebugMode.XErrors =0

options.ShowSizes = 1
options.SkipZeroSizes = 0

options.WholeTheme = 1

ThemeGUI equ win_gui

include "%lib%/freshlib.asm"


iglobal
TemplateMainForm:
        ObjTemplate  tfParent or tfEnd, TForm, frmMain, \
                     x = 100,        \
                     y = 50,         \
                     width = 320,    \
                     height = 520,   \
                     OnCreate = FormOnCreate,    \
                     OnClose = MainFormOnClose,  \
                     OnDestroy = FormOnDestroy,  \
                     Caption = 'The new GUI toolkit test form.'

          ObjTemplate  tfChild, TLabel, NONE,                   \
                     x = 10, y = 10, width=400, height = 19,    \
                     Caption = "Load theme from file:",        \
                     Visible = TRUE


          ObjTemplate  tfChild, TButton, btnTheme1,         \
                     x = 10,         \
                     y = 32,         \
                     width = 90,     \
                     height = 24,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = "Theme Win",       \
                     Visible = TRUE, \
                     OnClick = LoadTheme1Click

          ObjTemplate  tfChild, TButton, btnTheme2,         \
                     x = 102,         \
                     y = 32,         \
                     width = 90,     \
                     height = 24,    \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = "Theme Flat",       \
                     Visible = TRUE, \
                     OnClick = LoadTheme2Click


          ObjTemplate  tfChild, TLabel, NONE,                   \
                     x = 10, y = 393, width=400, height = 19,    \
                     Caption = "Load/Save custom theme:",        \
                     Visible = TRUE


          ObjTemplate tfChild, TEdit, editTest,                 \
                     Text = "Theme.cfg",                        \
                     x = 10, y=415, width=168, height=24,       \
                     MarginLeft= 2,                            \
                     MarginRight= 2,                           \
                     Visible = TRUE

          ObjTemplate  tfChild, TButton, btnThemeSave,                                      \
                     x = 180, y = 415, width = 64, height = 24,                             \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Save',                                                      \
                     Visible = TRUE,                                                        \
                     OnClick = SaveThemeClick


          ObjTemplate  tfChild, TButton, btnThemeLoad,                                      \
                     x = 246, y = 415, width = 64, height = 24,                             \
                     TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption = 'Load',                                                      \
                     Visible = TRUE,                                                        \
                     OnClick = LoadThemeClick

          ObjTemplate tfChild, TProgress, NONE,                         \
                     x = 10, y = 490, width = 300, height = 19,         \
                     Max = 100, Pos = 30,                               \
                     Visible = TRUE


          ObjTemplate tfChild or tfEnd, TTreeView, tvPreview,            \
                     x = 10, y = 64, width = 300, height = 300,          \
                     OnCreate = TreeOnCreate,                            \
                     Visible = TRUE





  getfile imgFolder1, "_test_images/folder2.png"
  getfile imgFile1,   "_test_images/document2.png"

  getfile imgFolder2, "_test_images/folder.png"
  getfile imgFile2,   "_test_images/document.png"

endg




uglobal
  iconFolder dd ?
  iconFile   dd ?
endg


;rb 423


start:
        InitializeAll


        create  [pApplication], TApplication

        call    GUI.Init

        stdcall CreateFromTemplate, TemplateMainForm, 0

        set     [pApplication], TApplication:MainWindow, frmMain

        set     [frmMain], TWindow:Visible, TRUE                ; must be set visible after creation, because it loads
                                                                ; needed images in OnCreate event handler.

        stdcall Run

        FinalizeAll
        stdcall TerminateAll, 0



; Sample event handlers. They work with other objects on the form.

proc FormOnCreate as TObject.OnCreate
begin
        DebugMsg "Form OnCreate event handler."

        if ThemeGUI eq win_gui

          stdcall  CreateIconSet1

        else

          stdcall  CreateIconSet2

        end if

        return
endp


proc FreeIconSet
begin
        xor     ecx, ecx

        cmp     [iconFolder], ecx
        je      @f
        stdcall DestroyImage, [iconFolder]
        mov     [iconFolder], ecx
@@:
        cmp     [iconFile], ecx
        je      @f
        stdcall DestroyImage, [iconFile]
        mov     [iconFile], ecx
@@:

        return
endp


proc CreateIconSet1
begin
        stdcall FreeIconSet

        stdcall CreateImagePNG, imgFolder1, imgFolder1.size
        mov     [iconFolder], eax

        stdcall CreateImagePNG, imgFile1, imgFile1.size
        mov     [iconFile], eax

        return
endp



proc CreateIconSet2
begin
        stdcall FreeIconSet

        stdcall CreateImagePNG, imgFolder2, imgFolder2.size
        mov     [iconFolder], eax

        stdcall CreateImagePNG, imgFile2, imgFile2.size
        mov     [iconFile], eax

        return
endp


proc TreeOnCreate as TObject.OnCreate
begin
        stdcall LoadExampleTreeContent, [.self]

        return
endp




proc FormOnDestroy as TObject.OnDestroy
begin
        DebugMsg "MainForm destroy event handler."
        return
endp



proc MainFormOnClose as TForm.OnClose
begin
        DebugMsg "Main form OnClose event handler"
        clc
        return
endp




proc LoadTheme1Click as TButton.OnClick
begin
        pushad

        stdcall LoadBinaryFile, "./theme_win.cfg"
        jc      .finish

        push    eax

        stdcall StringToNamedArray, GUI.meta, eax

        stdcall FreeMem ; from the stack.

        stdcall  CreateIconSet1
        stdcall LoadExampleTreeContent, [tvPreview]

        exec    [frmMain], TWindow:RefreshAll

.finish:
        popad
        return
endp


proc LoadTheme2Click as TButton.OnClick
begin
        pushad

        stdcall LoadBinaryFile, "./theme_flat.cfg"
        jc      .finish

        push    eax

        stdcall StringToNamedArray, GUI.meta, eax

        stdcall FreeMem ; from the stack.

        stdcall  CreateIconSet2
        stdcall LoadExampleTreeContent, [tvPreview]

        exec    [frmMain], TWindow:RefreshAll

.finish:
        popad
        return
endp


proc SaveThemeClick as TButton.OnClick
begin
        pushad

        get     ebx, [editTest], TEdit:Text

        stdcall NamedArrayToString, GUI.meta
        mov     edi, eax

        stdcall StrPtr, eax
        mov     esi, eax

        stdcall StrPtr, ebx

        stdcall SaveBinaryFile, eax, esi, [esi+string.len]

        stdcall StrDel, ebx
        stdcall StrDel, edi

        popad
        return
endp




proc LoadThemeClick as TButton.OnClick
begin
        pushad

        get     ebx, [editTest], TEdit:Text

        stdcall LoadBinaryFile, ebx
        jc      .finish

        push    eax

        stdcall StringToNamedArray, GUI.meta, eax

        stdcall FreeMem ; from the stack.

        exec    [frmMain], TWindow:RefreshAll

.finish:
        stdcall StrDel, ebx
        popad
        return
endp




proc LoadExampleTreeContent, .pTreeView
begin
        pushad

        mov     esi, [.pTreeView]
        mov     edx, [esi+TTreeView._items]

        stdcall DeleteArrayItems, edx, 0, [edx+TArray.count]

        stdcall ___DoReadDir, txt ".", edx, -1
        mov     [esi+TTreeView._items], edx
        jc      .error

.finish:

        OutputValue "Files tree items:", [edx+TArray.count], 10, 8

        exec    [.pTreeView], TTreeView:__RebuildIndex
        exec    [.pTreeView], TWindow:Refresh

        set     [frmMain], TWindow:Cursor, edi

        popad
        return

.error:
        stdcall GetErrorString, eax
        push    eax

        stdcall ShowMessage, [frmMain], smiError, "File error", eax, smbOK

        stdcall FreeErrorString ; from the stack
        jmp     .finish

endp




proc ___DoReadDir, .hDir, .pArray, .Level
begin
        pushad

        mov     edx, [.pArray]
        mov     ebx, [.Level]
        inc     ebx

        stdcall DirectoryRead, [.hDir]
        jc      .finish

        mov     esi, eax
        xor     ecx, ecx


        stdcall SortDirArray, esi, fdsByType

.loop:
        cmp     ecx, [esi+TArray.count]
        jae     .end_loop

        stdcall StrPtr, [esi+TArray.array + 8*ecx + TDirItem.hFilename]

        cmp     byte [eax], "."
        je      .next

;        Output  eax
;        DebugMsg ""

        stdcall AddArrayItems, edx, 1

        push    [esi+TArray.array + 8*ecx + TDirItem.hFilename]         ; name
        pop     [eax+TTreeViewItem.caption]
        mov     [eax+TTreeViewItem.level], ebx
        mov     [eax+TTreeViewItem.state], tvisExpanded

        push    edx

        mov     edx, [iconFolder]
        cmp     [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory
        je      @f

        mov     edx, [iconFile]
        cmp     [esi+TArray.array + 8*ecx + TDirItem.Type], ftFile
        je      @f

        xor     edx, edx

@@:
        mov     [eax+TTreeViewItem.imgNormal], edx

        pop     edx

        cmp     [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory
        jne     .next

        stdcall StrDup, [.hDir]
        push    eax

        stdcall StrCharCat, eax, "/"
        stdcall StrCat, eax, [esi+TArray.array + 8*ecx + TDirItem.hFilename]

        stdcall ___DoReadDir, eax, edx, ebx

        stdcall StrDel ; from the stack

.next:
        inc     ecx
        jmp     .loop

.end_loop:
        stdcall FreeMem, esi

        clc
        xor     eax, eax

.finish:
        mov     [esp+regEAX*4], eax
        mov     [esp+regEDX*4], edx
        popad
        return
endp


Added freshlib/test_code0/TestThemes.fpr.

cannot compute difference between binary files

Added freshlib/test_code0/ThemesConfigBuild.asm.






















































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; _______________________________________________________________________________________
;|                                                                                       |
;| ..:: Fresh IDE ::..  template project.                                                |
;|_______________________________________________________________________________________|
;
;  Description: FreshLib portable console application.
;
;  Target OS: Any, supported by FreshLib
;
;  Dependencies: FreshLib
;
;  Notes:
;_________________________________________________________________________________________

include "%lib%/freshlib.inc"

@BinaryType GUI, compact

options.DebugMode = 0
  options.DebugMode.NoTimers = 1
  options.DebugMode.XSync = 0
  options.DebugMode.XErrors =0

options.ShowSizes = 1
options.SkipZeroSizes = 0

options.WholeTheme = 1

ThemeGUI equ

include "%lib%/freshlib.asm"


GUI fix ThemeFlat

include "%lib%/gui/themes/flat_gui.asm"

GUI fix ThemeWin

include "%lib%/gui/themes/win_gui.asm"


;rb 423


start:
        InitializeAll

        create  [pApplication], TApplication, 0

        call    ThemeFlat.Init
        call    ThemeWin.Init


; Save flat theme

        stdcall NamedArrayToString, ThemeFlat.meta
        push    eax

        stdcall StrPtr, eax
        mov     esi, eax

        stdcall SaveBinaryFile, "theme_flat.cfg", esi, [esi+string.len]

        stdcall StrDel ; from the stack


; Save win theme

        stdcall NamedArrayToString, ThemeWin.meta
        push    eax

        stdcall StrPtr, eax
        mov     esi, eax

        stdcall SaveBinaryFile, "theme_win.cfg", esi, [esi+string.len]

        stdcall StrDel ; from the stack


        destroy [pApplication]

        FinalizeAll
        stdcall TerminateAll, 0



; Sample event handlers. They work with other objects on the form.

proc FormOnCreate as TObject.OnCreate
begin
        DebugMsg "Form OnCreate event handler."

        if ThemeGUI eq win_gui

          stdcall  CreateIconSet1

        else

          stdcall  CreateIconSet2

        end if

        return
endp


proc FreeIconSet
begin
        xor     ecx, ecx

        cmp     [iconFolder], ecx
        je      @f
        stdcall DestroyImage, [iconFolder]
        mov     [iconFolder], ecx
@@:
        cmp     [iconFile], ecx
        je      @f
        stdcall DestroyImage, [iconFile]
        mov     [iconFile], ecx
@@:

        return
endp


proc CreateIconSet1
begin
        stdcall FreeIconSet

        stdcall CreateImagePNG, imgFolder1, imgFolder1.size
        mov     [iconFolder], eax

        stdcall CreateImagePNG, imgFile1, imgFile1.size
        mov     [iconFile], eax

        return
endp



proc CreateIconSet2
begin
        stdcall FreeIconSet

        stdcall CreateImagePNG, imgFolder2, imgFolder2.size
        mov     [iconFolder], eax

        stdcall CreateImagePNG, imgFile2, imgFile2.size
        mov     [iconFile], eax

        return
endp


proc TreeOnCreate as TObject.OnCreate
begin
        stdcall LoadExampleTreeContent, [.self]

        return
endp




proc FormOnDestroy as TObject.OnDestroy
begin
        DebugMsg "MainForm destroy event handler."
        return
endp



proc MainFormOnClose as TForm.OnClose
begin
        DebugMsg "Main form OnClose event handler"
        clc
        return
endp




proc LoadTheme1Click as TButton.OnClick
begin
        pushad

        stdcall LoadBinaryFile, "./theme_win.cfg"
        jc      .finish

        push    eax

        stdcall StringToNamedArray, GUI.meta, eax

        stdcall FreeMem ; from the stack.

        stdcall  CreateIconSet1
        stdcall LoadExampleTreeContent, [tvPreview]

        exec    [frmMain], TWindow:RefreshAll

.finish:
        popad
        return
endp


proc LoadTheme2Click as TButton.OnClick
begin
        pushad

        stdcall LoadBinaryFile, "./theme_flat.cfg"
        jc      .finish

        push    eax

        stdcall StringToNamedArray, GUI.meta, eax

        stdcall FreeMem ; from the stack.

        stdcall  CreateIconSet2
        stdcall LoadExampleTreeContent, [tvPreview]

        exec    [frmMain], TWindow:RefreshAll

.finish:
        popad
        return
endp


proc SaveThemeClick as TButton.OnClick
begin
        pushad

        get     ebx, [editTest], TEdit:Text

        stdcall NamedArrayToString, GUI.meta
        mov     edi, eax

        stdcall StrPtr, eax
        mov     esi, eax

        stdcall StrPtr, ebx

        stdcall SaveBinaryFile, eax, esi, [esi+string.len]

        stdcall StrDel, ebx
        stdcall StrDel, edi

        popad
        return
endp




proc LoadThemeClick as TButton.OnClick
begin
        pushad

        get     ebx, [editTest], TEdit:Text

        stdcall LoadBinaryFile, ebx
        jc      .finish

        push    eax

        stdcall StringToNamedArray, GUI.meta, eax

        stdcall FreeMem ; from the stack.

        exec    [frmMain], TWindow:RefreshAll

.finish:
        stdcall StrDel, ebx
        popad
        return
endp




proc LoadExampleTreeContent, .pTreeView
begin
        pushad

        mov     esi, [.pTreeView]
        mov     edx, [esi+TTreeView._items]

        stdcall DeleteArrayItems, edx, 0, [edx+TArray.count]

        stdcall ___DoReadDir, txt ".", edx, -1
        mov     [esi+TTreeView._items], edx
        jc      .error

.finish:

        OutputValue "Files tree items:", [edx+TArray.count], 10, 8

        exec    [.pTreeView], TTreeView:__RebuildIndex
        exec    [.pTreeView], TWindow:Refresh

        set     [frmMain], TWindow:Cursor, edi

        popad
        return

.error:
        stdcall GetErrorString, eax
        push    eax

        stdcall ShowMessage, [frmMain], smiError, "File error", eax, smbOK

        stdcall FreeErrorString ; from the stack
        jmp     .finish

endp




proc ___DoReadDir, .hDir, .pArray, .Level
begin
        pushad

        mov     edx, [.pArray]
        mov     ebx, [.Level]
        inc     ebx

        stdcall DirectoryRead, [.hDir]
        jc      .finish

        mov     esi, eax
        xor     ecx, ecx


        stdcall SortDirArray, esi, fdsByType

.loop:
        cmp     ecx, [esi+TArray.count]
        jae     .end_loop

        stdcall StrPtr, [esi+TArray.array + 8*ecx + TDirItem.hFilename]

        cmp     byte [eax], "."
        je      .next

;        Output  eax
;        DebugMsg ""

        stdcall AddArrayItems, edx, 1

        push    [esi+TArray.array + 8*ecx + TDirItem.hFilename]         ; name
        pop     [eax+TTreeViewItem.caption]
        mov     [eax+TTreeViewItem.level], ebx
        mov     [eax+TTreeViewItem.state], tvisExpanded

        push    edx

        mov     edx, [iconFolder]
        cmp     [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory
        je      @f

        mov     edx, [iconFile]
        cmp     [esi+TArray.array + 8*ecx + TDirItem.Type], ftFile
        je      @f

        xor     edx, edx

@@:
        mov     [eax+TTreeViewItem.imgNormal], edx

        pop     edx

        cmp     [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory
        jne     .next

        stdcall StrDup, [.hDir]
        push    eax

        stdcall StrCharCat, eax, "/"
        stdcall StrCat, eax, [esi+TArray.array + 8*ecx + TDirItem.hFilename]

        stdcall ___DoReadDir, eax, edx, ebx

        stdcall StrDel ; from the stack

.next:
        inc     ecx
        jmp     .loop

.end_loop:
        stdcall FreeMem, esi

        clc
        xor     eax, eax

.finish:
        mov     [esp+regEAX*4], eax
        mov     [esp+regEDX*4], edx
        popad
        return
endp


Added freshlib/test_code0/ThemesConfigBuild.fpr.

cannot compute difference between binary files

Changes to freshlib/test_code0/UTF8_examples.asm.
1
2
3
4

5
1
2
3

4
5



-
+

  utf8_string db $49, $C3, $B1, $74, $C3, $AB, $72, $6E, $C3, $A2, $74, $69, $C3, $B4, $6E, $C3, $A0, $6C, $69, $7A, $C3, $A6, $74, $69, $C3, $B8, $6E, $00 ; the word "Internationalization" written with different languages chars

; greek, cyrillic and latin in one text.
  utf8_long   file 'UnicodeSample.txt':3
  utf8_long   file 'UnicodeSample.txt'
              dd 0
Changes to freshlib/test_code0/UnicodeSample.txt.
1

2
3

4
5
6





1
2

3
4


5
6
7
8
-
+

-
+

-
-
+
+
+
+
Russian: Я могу еÑть Ñтекло, оно мне не вредит. 
Russian: Я могу еÑть Ñтекло, оно мне не вредит.
Yoruba: Mo lè je̩ dígí, kò ní pa mí lára.
Chinese: 我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“。 
Chinese: 我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“。
Greek: ΜποÏÏŽ να φάω σπασμένα γυαλιά χωÏίς να πάθω τίποτα.
Québécois: J'peux manger d'la vitre, ça m'fa pas mal. 
Ukrainian: Я можу Ñ—Ñти Ñкло, Ñ– воно мені не зашкодить. 
Québécois: J'peux manger d'la vitre, ça m'fa pas mal.
Ukrainian: Я можу Ñ—Ñти Ñкло, Ñ– воно мені не зашкодить.

Това е един много дълъг параграф, в който Ñе говори за това, че мога да конÑумирам неорганични Ñиликатни аморфни материали без вреда за здравето или материалното ми положение.
Added freshlib/test_code0/_test_images/document.png.

cannot compute difference between binary files

Added freshlib/test_code0/_test_images/document2.png.

cannot compute difference between binary files

Added freshlib/test_code0/_test_images/folder.png.

cannot compute difference between binary files

Added freshlib/test_code0/_test_images/folder2.png.

cannot compute difference between binary files

Added freshlib/test_code0/_test_images/globe.png.

cannot compute difference between binary files

Deleted freshlib/test_code0/_test_images/icon.gif.

cannot compute difference between binary files

Added freshlib/test_code0/_test_images/img_list.png.

cannot compute difference between binary files

Added freshlib/test_code0/_test_images/left.png.

cannot compute difference between binary files

Added freshlib/test_code0/_test_images/menu.png.

cannot compute difference between binary files

Added freshlib/test_code0/_test_images/right.png.

cannot compute difference between binary files

Added freshlib/test_code0/_test_images/right2.png.

cannot compute difference between binary files

Added freshlib/test_code0/_test_images/speech.png.

cannot compute difference between binary files

Added freshlib/test_code0/_test_images/star.png.

cannot compute difference between binary files

Added freshlib/test_code0/_test_images/svg/document.svg.









































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="46.259px"
   height="46.259px"
   viewBox="0 0 46.259 46.259"
   style="enable-background:new 0 0 46.259 46.259;"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="document.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/test_code0/_test_images/document.png"
   inkscape:export-xdpi="31"
   inkscape:export-ydpi="31"><metadata
     id="metadata45"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
     id="defs43" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview41"
     showgrid="false"
     inkscape:zoom="12.12737"
     inkscape:cx="10.059889"
     inkscape:cy="23.129499"
     inkscape:current-layer="Capa_1" /><g
     id="g3"
     transform="matrix(0.9,0,0,0.9,2.3129,2.31295)"
     style="fill:#9b59b6;fill-opacity:1"><g
       id="g5"
       style="fill:#9b59b6;fill-opacity:1"><path
         d="m 35.043,13.514 c -3.405,0 -6.164,-2.749 -6.164,-6.153 l 0,-6.564 C 28.879,0.357 28.523,0 28.082,0 L 8.278,0 C 5.738,0 3.671,2.06 3.671,4.6 l 0,37.059 c 0,2.54 2.067,4.6 4.607,4.6 l 29.7,0 c 2.541,0 4.609,-2.06 4.609,-4.6 l 0,-27.348 c 0,-0.44 -0.355,-0.797 -0.797,-0.797 l -6.747,0 z"
         id="path7"
         inkscape:connector-curvature="0"
         style="fill:#9b59b6;fill-opacity:1" /><path
         d="m 35.043,10.395 5.519,0 c 0.321,0 0.612,-0.194 0.735,-0.493 C 41.42,9.604 41.351,9.261 41.122,9.034 39.106,7.03 35.36,3.31 33.352,1.327 33.123,1.101 32.782,1.035 32.485,1.159 32.19,1.282 31.997,1.572 31.997,1.893 l 0,5.468 c 0.001,1.665 1.38,3.034 3.046,3.034 z"
         id="path9"
         inkscape:connector-curvature="0"
         style="fill:#9b59b6;fill-opacity:1" /></g></g><g
     id="g11" /><g
     id="g13" /><g
     id="g15" /><g
     id="g17" /><g
     id="g19" /><g
     id="g21" /><g
     id="g23" /><g
     id="g25" /><g
     id="g27" /><g
     id="g29" /><g
     id="g31" /><g
     id="g33" /><g
     id="g35" /><g
     id="g37" /><g
     id="g39" /></svg>
Added freshlib/test_code0/_test_images/svg/folder.svg.






































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="841.5px"
   height="841.5px"
   viewBox="0 0 841.5 841.5"
   style="enable-background:new 0 0 841.5 841.5;"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="folder.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/test_code0/_test_images/folder.png"
   inkscape:export-xdpi="1.7112299"
   inkscape:export-ydpi="1.7112299"><metadata
     id="metadata45"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
     id="defs43" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview41"
     showgrid="false"
     inkscape:zoom="0.66666667"
     inkscape:cx="183"
     inkscape:cy="420.75"
     inkscape:current-layer="Capa_1" /><g
     id="g3"
     style="fill:#f39c12;fill-opacity:1;fill-rule:nonzero"><g
       id="g5"
       style="fill:#f39c12;fill-opacity:1;fill-rule:nonzero"><path
         d="M460.8,143.4c-12.9-24.8-38.6-40.4-66.5-40.4H50c-27.6,0-50,22.4-50,50v26.8h479.7L460.8,143.4z"
         id="path7"
         style="fill:#f39c12;fill-opacity:1;fill-rule:nonzero" /><path
         d="M791.6,224.8H0v463.7c0,27.601,22.4,50,50,50h741.5c27.6,0,50-22.399,50-50V274.8C841.6,247.2,819.2,224.8,791.6,224.8z"
         id="path9"
         style="fill:#f39c12;fill-opacity:1;fill-rule:nonzero" /></g></g><g
     id="g11" /><g
     id="g13" /><g
     id="g15" /><g
     id="g17" /><g
     id="g19" /><g
     id="g21" /><g
     id="g23" /><g
     id="g25" /><g
     id="g27" /><g
     id="g29" /><g
     id="g31" /><g
     id="g33" /><g
     id="g35" /><g
     id="g37" /><g
     id="g39" /></svg>
Added freshlib/test_code0/_test_images/svg/left.svg.











































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 width="493.578px" height="493.578px" viewBox="0 0 493.578 493.578" style="enable-background:new 0 0 493.578 493.578;"
	 xml:space="preserve">
<g>
	<path d="M487.267,225.981c0-17.365-13.999-31.518-31.518-31.518H194.501L305.35,83.615c12.24-12.24,12.24-32.207,0-44.676
		L275.592,9.18c-12.24-12.24-32.207-12.24-44.676,0L15.568,224.527c-6.12,6.12-9.256,14.153-9.256,22.262
		c0,8.032,3.136,16.142,9.256,22.262l215.348,215.348c12.24,12.239,32.207,12.239,44.676,0l29.758-29.759
		c12.24-12.24,12.24-32.207,0-44.676L194.501,299.498h261.094c17.366,0,31.519-14.153,31.519-31.519L487.267,225.981z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>
Added freshlib/test_code0/_test_images/svg/menu.svg.




































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="92.833px"
   height="92.833px"
   viewBox="0 0 92.833 92.833"
   style="enable-background:new 0 0 92.833 92.833;"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="menu.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/test_code0/_test_images/menu.png"
   inkscape:export-xdpi="15.511725"
   inkscape:export-ydpi="15.511725"><metadata
     id="metadata47"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
     id="defs45" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview43"
     showgrid="false"
     inkscape:zoom="8.7314773"
     inkscape:cx="28.263787"
     inkscape:cy="45.62978"
     inkscape:current-layer="Capa_1" /><g
     id="g3"><g
       id="g5"><path
         d="M89.834,1.75H3c-1.654,0-3,1.346-3,3v13.334c0,1.654,1.346,3,3,3h86.833c1.653,0,3-1.346,3-3V4.75    C92.834,3.096,91.488,1.75,89.834,1.75z"
         id="path7" /><path
         d="M89.834,36.75H3c-1.654,0-3,1.346-3,3v13.334c0,1.654,1.346,3,3,3h86.833c1.653,0,3-1.346,3-3V39.75    C92.834,38.096,91.488,36.75,89.834,36.75z"
         id="path9" /><path
         d="M89.834,71.75H3c-1.654,0-3,1.346-3,3v13.334c0,1.654,1.346,3,3,3h86.833c1.653,0,3-1.346,3-3V74.75    C92.834,73.095,91.488,71.75,89.834,71.75z"
         id="path11" /></g></g><g
     id="g13" /><g
     id="g15" /><g
     id="g17" /><g
     id="g19" /><g
     id="g21" /><g
     id="g23" /><g
     id="g25" /><g
     id="g27" /><g
     id="g29" /><g
     id="g31" /><g
     id="g33" /><g
     id="g35" /><g
     id="g37" /><g
     id="g39" /><g
     id="g41" /></svg>
Added freshlib/test_code0/_test_images/svg/right.svg.


















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   width="493.578px"
   height="493.578px"
   viewBox="0 0 493.578 493.578"
   style="enable-background:new 0 0 493.578 493.578;"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="right.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/test_code0/_test_images/right2.png"
   inkscape:export-xdpi="2.9200001"
   inkscape:export-ydpi="2.9200001"><metadata
     id="metadata41"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
     id="defs39" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview37"
     showgrid="false"
     inkscape:zoom="1.6422313"
     inkscape:cx="246.789"
     inkscape:cy="238.42327"
     inkscape:current-layer="Capa_1" /><g
     id="g3"
     transform="matrix(-1,0,0,1,493.579,0)"
     style="fill:#404040;fill-opacity:1"><path
       d="m 487.267,225.981 c 0,-17.365 -13.999,-31.518 -31.518,-31.518 l -261.248,0 L 305.35,83.615 c 12.24,-12.24 12.24,-32.207 0,-44.676 L 275.592,9.18 c -12.24,-12.24 -32.207,-12.24 -44.676,0 L 15.568,224.527 c -6.12,6.12 -9.256,14.153 -9.256,22.262 0,8.032 3.136,16.142 9.256,22.262 l 215.348,215.348 c 12.24,12.239 32.207,12.239 44.676,0 L 305.35,454.64 c 12.24,-12.24 12.24,-32.207 0,-44.676 l -110.849,-110.466 261.094,0 c 17.366,0 31.519,-14.153 31.519,-31.519 l 0.153,-41.998 z"
       id="path5"
       inkscape:connector-curvature="0"
       style="fill:#404040;fill-opacity:1" /></g><g
     id="g7"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g9"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g11"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g13"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g15"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g17"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g19"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g21"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g23"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g25"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g27"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g29"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g31"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g33"
     transform="matrix(-1,0,0,1,493.579,0)" /><g
     id="g35"
     transform="matrix(-1,0,0,1,493.579,0)" /></svg>
Added freshlib/test_code0/_test_images/svg/star.svg.



































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="Capa_1"
   x="0px"
   y="0px"
   viewBox="0 0 88 88"
   style="enable-background:new 0 0 88 88;"
   xml:space="preserve"
   inkscape:version="0.91 r13725"
   sodipodi:docname="star-shape1.svg"
   inkscape:export-filename="/work/asmwork/FreshFs/FreshLibGUI/freshlib/test_code0/_test_images/star.png"
   inkscape:export-xdpi="122.72727"
   inkscape:export-ydpi="122.72727"><metadata
     id="metadata43"><rdf:RDF><cc:Work
         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
     id="defs41" /><sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="640"
     inkscape:window-height="480"
     id="namedview39"
     showgrid="false"
     inkscape:zoom="6.3068182"
     inkscape:cx="43.603604"
     inkscape:cy="44"
     inkscape:current-layer="Capa_1" /><g
     id="g3"
     style="fill:#ffffff;fill-opacity:0.25098041"
     inkscape:export-xdpi="122.73"
     inkscape:export-ydpi="122.73"><g
       id="g5"
       style="fill:#ffffff;fill-opacity:0.25098041"><polygon
         style="fill:#ffffff;fill-opacity:0.25098041"
         points="44,0 55.939,33.612 88,33.612 61.842,53.351 71.193,88 44,67.226 16.809,88 26.158,53.351     0,33.612 32.061,33.612   "
         id="polygon7" /></g></g><g
     id="g9" /><g
     id="g11" /><g
     id="g13" /><g
     id="g15" /><g
     id="g17" /><g
     id="g19" /><g
     id="g21" /><g
     id="g23" /><g
     id="g25" /><g
     id="g27" /><g
     id="g29" /><g
     id="g31" /><g
     id="g33" /><g
     id="g35" /><g
     id="g37" /></svg>
Deleted freshlib/test_code0/_test_images/test.gif.

cannot compute difference between binary files

Added freshlib/test_code0/theme_flat.cfg.































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
clBorderNeutral = $FF1ABC9C
clBorderLight = $FF1ABC9C
clBorderDark = $FF1ABC9C
clBorderNeutralGray = $FF606060
clBorderLightGray = $FF606060
clBorderDarkGray = $FF606060
clBorderFocused = $FFE74C3C
boxBorderWidth = 2
clBtnBk = $FF1ABC9C, $FF48C9B0, $FF16A085, $807B7B7B
clBtnTxt = $FFFFFFFF, $FFFFFFFF, $FFBDC3C7, $80FFFFFF
btnBorder = 0, 0, 0, 0
btnPressedOfsX = 0
btnPressedOfsY = 0
btnMarginX = 8
btnMarginY = 8
clEditBk = $FFECF0F1
clEditBkFocused = $FFECF0F1
clEditTxt = $FF000000
clEditSel = $602980B9
clEditSelTxt = $FFFFFFFF
editBorder = 3
editBorderFocused = 3
clDialogBk = $FFECF0F1
clDialogTxt = $FF000000
clSplitter = $FF34495E
clProgressBk = $FFECF0F1
clProgressBar = $FF1ABC9C
progressBorder = 3
clScrollBk = $3FBDC3C7, $A0BDC3C7
clScrollSlider = $7F7F8C8D, $FF1ABC9C
borderScroll = 0
scrollWidth = 12
minSliderHeight = 12
clLabelBk = $0
clLabelTxt = $FF000000
clTreeViewBack = $FFECF0F1
clTreeViewText = $FF000000
clTreeSelected = $FF2980B9
clTreeSelectedTxt = $FFFFFFFF
clTreeFocused = $FFD35400
clTreeFocusedTxt = $FFFFFFFF
tvBorder = 3
tvIcons = 297:iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAMAAACecocUAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAEJQTFRFAAAAgICAkra2n5+fmaOjkqiolqamlaWllqWllKWnlaWllaSmlqWllaWllqWllaWmlaWmlaWmlaWmlaWmlaWmlaWml3PoaAAAABV0Uk5TAAIHCBkjLkFmbm9zd4Ciu8vM4uj9nlc1ogAAADhJREFUCJlj4OJhZoABXlEhDkY4W1RUkB3BFhXlZ0OwRUX4WOBsUVFhViziCPUC7Jjmc3IzwawFAEAMBLa48vXWAAAAAElFTkSuQmCC, 333:iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADKSURBVBiVhY+7TgJhFIS/+d3QmWDhE/gQhlfgAbb46U00aENMoKCgs5ZIRey49FpbmFhZm9iQ0FFaC2yGQjFcVna6Oec7l1FvMLgATijWV2LrGHFXREo0wmkp6QomBex0WS4/hDRN5xbtQ6Rx66Za/RaAbfWGozegkoO+X8V4Lsnh5x/ZuJm3NUhNSQYI62K9VnsVet5hny5jfPkb3Oxk8i2wXFuL1taVTXMd46fR42+qfj3Gj39hgKNs0QZmibNOXoY93Y/HZ3n1FeLFO3+97VjQAAAAAElFTkSuQmCC
clMenuBack = $FFECF0F1
clMenuText = $FF000000
clMenuTextGray = $90000000
borderMenu = 3
menuIconMargin = 4
menuMinTextDist = 32
menuSubIcon = 206:iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABLSURBVBiVjc+xDYBADATBeSQCIgqgYzJaoARSInqgH5MQvQ6JzezVyT7YMAgUdoxJFA5MSRQuzEkUbiztHXrOz8SvG/Gr2GNF65cP8X4dCPkfyx8AAAAASUVORK5CYII-
menuSubIconSel = 207:iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABMSURBVBiVjc+xDYAwEEPRCxIFFQOwcTpWyAi0VOzAPi8FXTgk3H5Z3w7smGKMJw1zBuDAkgG4sGYAbmwFXuKI87Pxy5GuSn9UlNHeAYWml41HdWNxAAAAAElFTkSuQmCC
menuSubIconGray = 280:iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACVSURBVBiVY5i6dOnEhoYGJgY0wMTAwJgnpqq6YObMmaxoEgwM/xkYY//w8K7tW7WKE0UCCnzZf//ZMXPVKn4GBgYGxqlLl/1HM/4q0x8WdwxLGRgYtP+x/JmPTeIq0x+WRHSJQyysLNaZ8WFPkSU2/2Rl8UgPC/sIdxUjw//FLF8+BxeFhX2HK5u2ZFnX////GdEtAgDKqy21io/rDwAAAABJRU5ErkJggg--
iconMenuChecked = 172:iVBORw0KGgoAAAANSUhEUgAAAAcAAAAQCAYAAADagWXwAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAApSURBVBiVY2CgP2B87mPTgEuShYGBoR6XJBM+YwdCkoWBgaERnwJ6AwCTrAMDeKqy3AAAAABJRU5ErkJggg--
iconMenuCheckedGray = 172:iVBORw0KGgoAAAANSUhEUgAAAAcAAAAQCAYAAADagWXwAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAApSURBVBiVY2CgP2DMy8trwCXJwsDAUI9LkgmfsQMhycLAwNCITwG9AQBg/wLetiFJMAAAAABJRU5ErkJggg--
clCheckboxBack = $FFE0E0E0, $FFFFFFFF, $FFC0C0C0, $80C0C0C0
clCheckboxTxt = $FF000000
clCheckboxTxtGray = $FF606060
cbIconSize = 13
cbMargin = 2
borderCheckbox = 3
iconChecked = 166:iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAjSURBVCiRY2AYfoARXeC5j81/dDHJLUdQ1DGRY9Mg1zQcAQAaUwQKOrN/dgAAAABJRU5ErkJggg--
iconCheckedGray = 166:iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAjSURBVCiRY2AYfoARXSA/P/8/utjEiRNR1DGRY9Mg1zQcAQAXqwQKOqarXQAAAABJRU5ErkJggg--
DefaultFont = 'Liberation Sans' : 13 : 4 : $0
Added freshlib/test_code0/theme_win.cfg.































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
clBorderNeutral = $FFA0A0A0
clBorderLight = $FFFFFFFF
clBorderDark = $FF404040
clBorderNeutralGray = $FF909090
clBorderLightGray = $FFE0E0E0
clBorderDarkGray = $FF808080
clBorderFocused = $FFFF8000
boxBorderWidth = 1
clBtnBk = $FFD4D0C8, $FFE0E0E0, $FFA0A0A0, $80D4D0C8
clBtnTxt = $FF000000, $FF000000, $FF000000, $FF606060
btnBorder = 1, 1, 2
btnPressedOfsX = 1
btnPressedOfsY = 1
btnMarginX = 8
btnMarginY = 8
clEditBk = $FFFFFFFF
clEditBkFocused = $FFFFFFFF
clEditTxt = $FF000000
clEditSel = $600A246C
clEditSelTxt = $FFFFFFFF
editBorder = 2
editBorderFocused = 2
clDialogBk = $FFD4D0C8
clDialogTxt = $FF000000
clSplitter = $FF606060
clProgressBk = $FFD4D0C8
clProgressBar = $FF0A246C
progressBorder = 2
clScrollBk = $3F808080, $A0D4D0C8
clScrollSlider = $7FD4D0C8, $FFD4D0C8
borderScroll = 1
scrollWidth = 16
minSliderHeight = 16
clLabelBk = $FFFFFF
clLabelTxt = $FF000000
clTreeViewBack = $FFFFFFFF
clTreeViewText = $FF000000
clTreeSelected = $FF0A246C
clTreeSelectedTxt = $FFFFFFFF
clTreeFocused = $FF0A246C
clTreeFocusedTxt = $FFFFFF00
tvBorder = 2
tvIcons = 117:iVBORw0KGgoAAAANSUhEUgAAAAsAAAALAQMAAACTYuVlAAAABlBMVEUAAAAAAAClZ7nPAAAAAXRSTlMAQObYZgAAAB1JREFUCNdjYGBgqD/A4ODA4AJG8TAGUAQozsAAAGXeBi6dny4xAAAAAElFTkSuQmCC, 114:iVBORw0KGgoAAAANSUhEUgAAAAsAAAALAQMAAACTYuVlAAAABlBMVEUAAAAAAAClZ7nPAAAAAXRSTlMAQObYZgAAABpJREFUCNdjYGBgqD/A4OAARfEOCDZQnIEBAGTOBh7FK7i2AAAAAElFTkSuQmCC
clMenuBack = $FFD4D0C8
clMenuText = $FF000000
clMenuTextGray = $80000000
borderMenu = 1
menuIconMargin = 4
menuMinTextDist = 32
menuSubIcon = 206:iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABLSURBVBiVjc+xDYBADATBeSQCIgqgYzJaoARSInqgH5MQvQ6JzezVyT7YMAgUdoxJFA5MSRQuzEkUbiztHXrOz8SvG/Gr2GNF65cP8X4dCPkfyx8AAAAASUVORK5CYII-
menuSubIconSel = 207:iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABMSURBVBiVjc+xDYAwEEPRCxIFFQOwcTpWyAi0VOzAPi8FXTgk3H5Z3w7smGKMJw1zBuDAkgG4sGYAbmwFXuKI87Pxy5GuSn9UlNHeAYWml41HdWNxAAAAAElFTkSuQmCC
menuSubIconGray = 280:iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACVSURBVBiVY5i6dOnEhoYGJgY0wMTAwJgnpqq6YObMmaxoEgwM/xkYY//w8K7tW7WKE0UCCnzZf//ZMXPVKn4GBgYGxqlLl/1HM/4q0x8WdwxLGRgYtP+x/JmPTeIq0x+WRHSJQyysLNaZ8WFPkSU2/2Rl8UgPC/sIdxUjw//FLF8+BxeFhX2HK5u2ZFnX////GdEtAgDKqy21io/rDwAAAABJRU5ErkJggg--
iconMenuChecked = 246:iVBORw0KGgoAAAANSUhEUgAAAAgAAAAQCAYAAAArij59AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABzSURBVCiRzc6xDUEBFIXhjxhAp6UUjSEkbwSjmIDEBFaxgNIYKEWhlKO5LxJ5r+aU9z85/+X3GfSjLDDug1NyJ5cuOCInErJBDmRHSpd9wSMZIuc6bElDXuRGJu3kjFyr9KzC6tu7JI/PUvfnc7Iu71/lDbA1NqOlVrCQAAAAAElFTkSuQmCC
iconMenuCheckedGray = 299:iVBORw0KGgoAAAANSUhEUgAAAAgAAAAQCAYAAAArij59AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACoSURBVCiRxY4hjgJBFAXrd2YMiiOsJTgEAvF7xqJJUGQvsQoPIcFhOAEWT7KTTPoCHAEJa1es7LcKNYOmbL3kFbwfeyXquh4Dw95BVVUfkq7AX+iRhaQTMJR0CO5+jDFun3eSNsBM0iWltC/MbApMYowKIaSc8xfwKMvyE8hB0gK4A+uc8xnAzFZN0/wAhJTSzczmwC8wAHZt2353yt195O5LoBP+bv4BnNI5/xB5g9MAAAAASUVORK5CYII-
clCheckboxBack = $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFC0C0C0
clCheckboxTxt = $FF000000
clCheckboxTxtGray = $FF808080
cbIconSize = 13
cbMargin = 2
borderCheckbox = 2
iconChecked = 282:iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACXSURBVCiRzc89DgFhEIDhVy/Z0gEUolFIuIBCotNKFC6goHQdV9BxD41Cp1gVBRF5NRPZbMh+jcR08/NMZuDPwgm4A1upoAveQMF5CqiD+wAHMCs2M3AFdkpoHeAO9ssbF9E8g+2ozaImuPx0RhPMY+AIDsFr5Buw9u3+HngpbBc8gY2qx0fgI8ATHFSANxyDW3CaCH4YL0VGUkYKfrkaAAAAAElFTkSuQmCC
iconCheckedGray = 404:iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAERSURBVCiRvdAhS0NhFIfx57zvhYUJBs0uGMTqB9h2LwMR7KJLbmAQP4FN8EOYBItNEAQx7N67G9UmliHKxbYomOS955iUaZgW/bcD51ce+K/Jb57iON5S1b5zbjfP81H0E0iSZEVVj0WkBqwCIzcNtNvtGVU9BWpm9uS9PwGIADqdzmwIYc97f5Gm6d2EOwKWzOzNe785GAxeABxAVVV94DCEkDebzWWAVqu1DXQBRGQ/y7KbLyGSJFlU1WtgzsyenXM7ZnYG1M3ssiiKdcA+kAPIsuzRzNaAVxFZMLMroA6MoyjqTYJPBFAUxa2IbAABwMxURLppmo6/B/KTR1mWD41G415E5oGD4XB4Pq3u3+8d34hqDI8BY9gAAAAASUVORK5CYII-
DefaultFont = 'Liberation Sans' : 13 : 2 : $0