Fresh IDE . Check-in [b233c364d5]
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.

Overview
Comment:Fixed selection rectangles list creation. Fixed selection delete method. Code cleanup.
Timelines: family | ancestors | descendants | both | NoCanvasGUI
Files: files | file ages | folders
SHA1:b233c364d5e483a57b9bd9550056549181b34dbd
User & Date: johnfound 2019-04-28 14:31:55
Context
2019-04-29
07:13
Deleting characters. check-in: 22f4724e5a user: johnfound tags: NoCanvasGUI
2019-04-28
14:31
Fixed selection rectangles list creation. Fixed selection delete method. Code cleanup. check-in: b233c364d5 user: johnfound tags: NoCanvasGUI
2019-04-27
16:52
TAsmEdit refactored to the TText interface changes. check-in: 59f19b3b5c user: johnfound tags: NoCanvasGUI
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to freshlib/data/buffergap.asm.

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
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
    err
  end if
}


; Converts from buffer offset to the text position.
; Arguments:
;   ESI: points to the TText strucure, eax is the offset
;   EAX: offset in bytes.
;
; if the buffer offset is placed inside the gap, the start of the gap is returned.
;
; See also ofs2pos macro. Very often it is better to use the macro or explicit processing,
; instead of procedure call, because the operation is very simple.

proc TextOffsetToPos, .pText, .offs
................................................................................
local ..skip

  if ofs eqtype eax & text eqtype eax
        cmp     ofs, [text+TText.Length]
        cmova   ofs, [text+TText.Length]

        cmp     ofs, [text+TText.GapBegin]
        jb      .skip

        add     ofs, [text+TText.GapBegin]
        sub     ofs, [text+TText.GapEnd]

        cmp     ofs, [text+TText.GapBegin]
        cmovb   ofs, [text+TText.GapBegin]
..skip:
................................................................................
        mov     edi, edx
        mov     esi, ebx

        add     edi, [edx+TText.GapBegin]
        mov     eax, [ebx+TText.GapBegin]

        mov     ecx, eax
        and     ecx, 3
        shr     eax, 2

        rep movsb
        mov     ecx, eax
        rep movsd

        mov     eax, [ebx+TText.Length]
        mov     esi, ebx

        sub     eax, [ebx+TText.GapEnd]
        add     esi, [ebx+TText.GapEnd]

        mov     ecx, eax
        and     ecx, 3
        shr     eax, 2

        rep movsb
        mov     ecx, eax
        rep movsd

        sub     edi, edx
        mov     [edx+TText.GapBegin], edi

        mov     [esp+4*regEDX], edx
        popad
        return







|
|







 







|







 







|
|

|

|








|
|

|

|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
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
    err
  end if
}


; Converts from buffer offset to the text position.
; Arguments:
;   .pText: points to the TText strucure, eax is the offset
;   .offs: offset in bytes.
;
; if the buffer offset is placed inside the gap, the start of the gap is returned.
;
; See also ofs2pos macro. Very often it is better to use the macro or explicit processing,
; instead of procedure call, because the operation is very simple.

proc TextOffsetToPos, .pText, .offs
................................................................................
local ..skip

  if ofs eqtype eax & text eqtype eax
        cmp     ofs, [text+TText.Length]
        cmova   ofs, [text+TText.Length]

        cmp     ofs, [text+TText.GapBegin]
        jb      ..skip

        add     ofs, [text+TText.GapBegin]
        sub     ofs, [text+TText.GapEnd]

        cmp     ofs, [text+TText.GapBegin]
        cmovb   ofs, [text+TText.GapBegin]
..skip:
................................................................................
        mov     edi, edx
        mov     esi, ebx

        add     edi, [edx+TText.GapBegin]
        mov     eax, [ebx+TText.GapBegin]

        mov     ecx, eax
        and     eax, 3
        shr     ecx, 2

        rep movsd
        mov     ecx, eax
        rep movsb

        mov     eax, [ebx+TText.Length]
        mov     esi, ebx

        sub     eax, [ebx+TText.GapEnd]
        add     esi, [ebx+TText.GapEnd]

        mov     ecx, eax
        and     eax, 3
        shr     ecx, 2

        rep movsd
        mov     ecx, eax
        rep movsb

        sub     edi, edx
        mov     [edx+TText.GapBegin], edi

        mov     [esp+4*regEDX], edx
        popad
        return

Changes to freshlib/gui/TAsmEdit.asm.

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
...
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
...
247
248
249
250
251
252
253


254
255
256
257
258
259
260
...
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
....
1237
1238
1239
1240
1241
1242
1243

1244
1245
1246
1247
1248
1249
1250
....
1345
1346
1347
1348
1349
1350
1351
1352
1353



1354
















1355
1356
1357
1358
1359
1360
1361
....
1367
1368
1369
1370
1371
1372
1373








1374



1375
1376
1377
1378
1379
1380
1381
....
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
....
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
....
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
....
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
....
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
....
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
....
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
....
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
....
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
....
3300
3301
3302
3303
3304
3305
3306







































































3307
3308
3309
3310
3311
3312
3313
....
3314
3315
3316
3317
3318
3319
3320


3321
3322


3323
3324
3325


3326
3327


3328
3329
3330





3331
3332
3333
3334
3335
3336
3337
3338

3339
3340
3341
3342
3343
3344
3345
3346

3347


3348
3349
3350
3351
3352
3353

3354
3355
3356
3357
3358
3359
3360







3361
3362
3363
3364

3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
....
3392
3393
3394
3395
3396
3397
3398










3399
3400
3401
3402
3403
3404
3405
  .pText       dd ?       ; pointer to the previous TTextLine of the affected line for chopChanged and chopDeleted
ends



rstruct TTextLine
  .flags        dd  ?   ; line flags
  .line_width   dd  ?   ; the latest computed line width in characters. For the wrapped lines is the width of the longest subline.
  .length       dd  ?   ; the length of the text in characters.
                        ;
  .debugdata    dd  ?   ; pointer to debug data, associated to this line
                        ;
  .syn_array    dd  ?   ; TArray of TTextChunk items for syntax colorization.
                        ; Should be updated by calling the syntax highlighting proc.
                        ;
  .syn_context  dd  ?   ; Syntax context after the line
                        ;
  .fold_level   dd  ?   ; the level of folding.

                dd  ?
                        ;
  .             TText
ends



struct TTextChunk
................................................................................
  ._font_width    dd    ?

  ._numfont_width dd    ?

  ._left_margin   dd    ?
  ._num_margin    dd    ?

  ._wrap_width    dd    ?       ; the word wrap width for the word wrapped lines.

  ._caretPos      POINT

  ._selStart      POINT         ; The selection start point
  ._selEnd        POINT         ;
  ._selAreaUpdate dd ?

  ._selCmd        dd    ?       ; ==0 if the shift key wasn't pressed on the last keyboard interaction.
................................................................................
  method .EventScroll, .direction, .command, .value
  method .EventKeyPress, .utf8, .scancode, .kbdState
  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventButtonRelease, .button, .kbdState, .x, .y
  method .EventMouseMove, .x, .y, .kbdState

endobj




method TAsmEdit.EventMouseMove   ;, .x, .y, .kbdState
begin
        pushad
        mov     esi, [.self]

................................................................................




; returns in EDX the rectangle list.

method TAsmEdit._AddSelRectanglesAbs      ;, .pRectList
.rect1 RECT
.rect2 RECT
.rect3 RECT
begin
        pushad

        xor     eax, eax
        lea     edi, [.rect1]
        mov     ecx, sizeof.RECT * 3 / 4

        rep stosd

        mov     esi, [.self]
        mov     edx, [.pRectList]

        test    edx, edx
        jnz     .array_ok

        stdcall CreateArray, sizeof.RECT
        mov     edx, eax

.array_ok:

        mov     eax, [esi+TAsmEdit._selStart.x]
        mov     ecx, [esi+TAsmEdit._selStart.y]
        mov     ebx, [esi+TAsmEdit._selEnd.x]
        mov     edi, [esi+TAsmEdit._selEnd.y]

        test    [esi+TAsmEdit._options], aeoBlockSelection
        jz      .add_char

; block selection






        mov     [.rect1.left], eax
        mov     [.rect1.right], ebx
        mov     [.rect1.top], ecx

        mov     [.rect1.bottom], edi
        lea     eax, [.rect1]
        stdcall RectSort, eax
        inc     [.rect1.bottom]
        jmp     .add_rectangles


.add_char:
        cmp     ecx, edi        ; caret_y and selection_y
        jl      .order_ok
        jg      .reverse

        cmp     eax, ebx        ; caret_x and caret_y
        je      .finish
        jl      .order_ok

.reverse:
        xchg    eax, ebx
        xchg    ecx, edi

; now eax,ecx is the begining of the selection and ebx, edi the end of the selection.
.order_ok:
        mov     [.rect1.left], eax
        mov     [.rect1.top], ecx
        mov     [.rect1.right], $7fffffff
        inc     ecx
        mov     [.rect1.bottom], ecx

        cmp     ecx, edi        ; begin_y and end_y
        jl      .first_ok
        je      .middle_ok

; there is only one line selection

        mov     [.rect1.right], ebx
        jmp     .add_rectangles

.first_ok:
;        mov     [.rect2.left], 0  ; already 0
        mov     [.rect2.top], ecx
        mov     [.rect2.right], $7fffffff
        mov     [.rect2.bottom], edi

.middle_ok:
;        mov     [.rect3.left], 0       ; already 0
        mov     [.rect3.top], edi
        mov     [.rect3.right], ebx
        inc     edi
        mov     [.rect3.bottom], edi

.add_rectangles:
        lea     eax, [.rect1]
        stdcall RectListAdd, edx, eax

        lea     eax, [.rect2]
        stdcall RectListAdd, edx, eax

        lea     eax, [.rect3]
        stdcall RectListAdd, edx, eax

.finish:













        mov     [esp+4*regEDX], edx
        popad
        return
endp



................................................................................



method TAsmEdit._RenderTxt ; .pImage, .pRect
.rectr RECT  ; relative to the upper left corner of the window
.recta RECT  ; absolute in the document coordinates.
.rects RECT

begin
        pushad

;if defined options.DebugMode & options.DebugMode
;        mov     eax, [.pRect]
;        mov     ecx, [eax+RECT.right]
;        mov     edx, [eax+RECT.bottom]
................................................................................

        mov     eax, [.rectr.left]
        sub     [.rectr.right], eax     ; .rectr.right == width

        stdcall LockImg, [.pImage]

        mov     ebx, [.recta.top]

.line_loop:




















        mov     edx, [.rectr.top]
        sub     edx, [esi+TAsmEdit._font_asc]   ; needed for the background and the left margin.

        xor     ecx, ecx
        test    [esi+TAsmEdit._options], aeoStripedBackground
        cmovnz  ecx, ebx
        and     ecx, 1
................................................................................
        jb      @f
        add     eax, [edi+TText.GapEnd]
        sub     eax, [edi+TText.GapBegin]
@@:
        cmp     eax, [edi+TText.Length]
        jae     .text_ok









        stdcall __RenderOneLine, [.pImage], [edi+eax], [.recta.left], [.recta.right], [.rectr.left], [.rectr.top]




.text_ok:

        mov     eax, [esi+TAsmEdit._font_height]
        add     [.rectr.top], eax

        inc     ebx
................................................................................

        OutputValue "    Font width:", eax, 10, -1

        stdcall GetTextBounds, "99999999", 8, [ASM.NumFont]
        sar     eax, 3
        mov     [edi+TAsmEdit._numfont_width], eax

        mov     [edi+TAsmEdit._wrap_width], 80

        mov     [edi+TAsmEdit._syntax_proc], SyntaxFASM


; test only!

;        set     edi, TAsmEdit:Text, 0
        set     edi, TAsmEdit:Text, utf8_long    ; 0   ; set the needed text structures, but empty.
................................................................................
        dec     ebx
        cmp     ebx, [edi+RECT.top]
        jl      .next_rect

        exec    [.self], TAsmEdit:TextLine, ebx
        mov     esi, eax

        mov     eax, [esi+TTextLine.length]
        cmp     eax, [edi+RECT.right]
        cmova   eax, [edi+RECT.right]

        stdcall TextIndexToPos, esi, eax   ; move the gap after the rectangle right bound.
        push    eax

        stdcall TextMoveGap, esi, eax
................................................................................
        xor     eax, $0d xor $0a
        cmp     [edi], al
        jne     .cr_ok
        inc     edi
.cr_ok:

        mov     esi, [esi]
        mov     [esi+TTextLine.line_width], ecx
        mov     [esi+TTextLine.length], ecx
        stdcall IncCount, [ebx+TAsmEdit._line_widths], ecx
        mov     [ebx+TAsmEdit._line_widths], edx

        stdcall SyntaxFASM, esi, [.context]
        mov     [.context], eax
        jmp     .text_loop


.end_text:

        exec    ebx, TAsmEdit:ComputeLeftMarginWidth
................................................................................
        cmovz   edi, ecx
        cmovnz  edi, eax        ; scroll more than needed.

        get     edx, esi, TAsmEdit:PosY

        mov     eax, [esi+TAsmEdit._caretPos.y]
        sub     eax, edx                       ; offset from the screen home.
        jz      .finish1                        ; no need to scroll
        js      .do_scroll

        sub     eax, ebx
        jle     .finish2

        neg     edi

.do_scroll:
        DebugMsg "Do scroll."

        sub     eax, edi
................................................................................

        inc     dword [esp+4*regEAX]

.finish:
        exec    esi, TAsmEdit:UpdateCaretPos
        popad
        return

.finish1:
        DebugMsg "Finish 1"
        jmp      .finish

.finish2:
        OutputValue "Finish 2 = ", eax, 10, -1
        OutputValue "Height = ", [esi+TAsmEdit._height], 10, -1

        jmp      .finish

endp






................................................................................
        test    [esi+TAsmEdit._options], aeoNavXCaretWrap
        jz      .set_pos

        exec    esi, TAsmEdit:TextLine, [esi+TAsmEdit._caretPos.y]
        cmovc   ebx, edx
        jc      .set_pos

        cmp     ebx, [eax+TTextLine.length]
        jbe     .set_pos

        exec    esi, TAsmEdit:CaretUpDown, 1, FALSE
        exec    esi, TAsmEdit:CaretHome
        jmp     .finish

.set_pos:
................................................................................
begin
        push    esi
        mov     esi, [.self]

        exec    esi, TAsmEdit:TextLine, [esi+TAsmEdit._caretPos.y]      ; returns CF=1 and eax=0 on error.
        jc      .set_pos

        mov     eax, [eax+TTextLine.length]

.set_pos:
        mov     [esi+TAsmEdit._caretPos.x], eax
        exec    esi, TAsmEdit:ScrollToCaretX

.finish:
        pop     esi
................................................................................

        pushd   [edi+TUndoInfo.pText] [ebx+eax]
        popd    [edi+TUndoInfo.pText] [ebx+eax]      ; xchg TTextLine structures of the line.

; fix the horizontal scrollbar size.

        mov     ecx, [ebx+eax]
        stdcall IncCount, [esi+TAsmEdit._line_widths], [ecx+TTextLine.line_width]
        mov     [esi+TAsmEdit._line_widths], edx

        mov     ecx, [edi+TUndoInfo.pText]
        stdcall DecCount, [esi+TAsmEdit._line_widths], [ecx+TTextLine.line_width]
        mov     [esi+TAsmEdit._line_widths], edx


        exec    esi, TAsmEdit:ScrollToCaretY
        exec    esi, TAsmEdit:UpdateScrollBar
;        exec    esi, TAsmEdit:Refresh

................................................................................
        jc      .finish

        mov     [ebx], eax
        mov     [esp+4*regEAX], ebx                     ; return value in EAX is the pointer to the new inserted TText.

        add     [edx+TText.GapBegin], 4

;        stdcall IncCount, [esi+TAsmEdit._line_widths], 0       ; ???????????
;        mov     [esi+TAsmEdit._line_widths], edx

        clc

.finish:
        popad
        return
endp
................................................................................
begin
        return
endp


method TAsmEdit.JoinNextLine    ;, .LineNum
begin







































































        return
endp



method TAsmEdit.DeleteSelection
.rect RECT
................................................................................
.list dd ?
begin
        pushad

        exec    [.self], TAsmEdit:_AddSelRectanglesAbs, 0
        mov     [.list], edx



        lea     edi, [edx+TArray.array]
        mov     ecx, [edx+TArray.count]



        mov     edx, [.self]
        mov     edx, [edx+TAsmEdit._line_widths]



.rect_loop:


        dec     ecx
        js      .finish






        mov     ebx, [edi+RECT.bottom]

.y_loop:
        dec     ebx
        cmp     ebx, [edi+RECT.top]
        jl      .next_rect

        exec    [.self], TAsmEdit:TextLine, ebx

        mov     esi, eax

        stdcall TextIndexToPos, esi, [edi+RECT.left]
        stdcall TextMoveGap, esi, eax

        mov     eax, [esi+TTextLine.length]
        cmp     eax, [edi+RECT.right]
        cmova   eax, [edi+RECT.right]                   ; delete up to the min(length, RECT.right) utf-8 character position!

        push    eax



        stdcall TextIndexToPos, esi, eax
        sub     eax, [esi+TTextLine.GapBegin]
        add     [esi+TTextLine.GapEnd], eax             ; delete eax bytes!

        stdcall DecCount, edx, [esi+TTextLine.length]

        pop     eax
        sub     eax, [edi+RECT.left]    ; deleted characters!

        sub     [esi+TTextLine.length], eax
        sub     [esi+TTextLine.line_width], eax

        stdcall IncCount, edx, [esi+TTextLine.length]







        jmp     .y_loop

.next_rect:
        add     edi, sizeof.RECT

        jmp     .rect_loop

.finish:
        stdcall FreeMem, [.list]
        mov     esi, [.self]

        mov     [esi+TAsmEdit._line_widths], edx

        get     eax, esi, TAsmEdit:SelStartX
        get     ecx, esi, TAsmEdit:SelEndX
        cmp     eax, ecx
        cmovg   eax, ecx

        get     edx, esi, TAsmEdit:SelStartY
        get     ecx, esi, TAsmEdit:SelEndY
................................................................................
        mov     [.rect.right], ecx
        mov     [.rect.bottom], edx
        lea     eax, [.rect]
        exec    esi, TAsmEdit:_RenderTxt, [esi+TAsmEdit._imgText], eax
        exec    esi, TAsmEdit:_RenderLM, [esi+TAsmEdit._imgMargin], [.rect.top], [.rect.bottom]
        exec    esi, TAsmEdit:RectChanged2, 0
        exec    esi, TAsmEdit:UpdateCaretPos










        popad
        return
endp


method TAsmEdit.InsertString    ;, .text
begin







<
|










|







 







<
<







 







>
>







 







<
<
<



<
<
<
<
<
<





>


>











>
>
>
>
>
>
|
|
<
>
|
<
|
|
|
<







|






|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>







 








|
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
|
>
>
>







 







<
<







 







|







 







<
|



|







 







|



|







 







<
<
<
<
<
<
<
<
<
<
<







 







|







 







|







 







|



|







 







|
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>


>
>

|
<
>
>


>
>



>
>
>
>
>





|


>





|


>
|
>
>





|
>


<
|
<

|
>
>
>
>
>
>
>
|

<
<
>
|


<


<
<







 







>
>
>
>
>
>
>
>
>
>







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
...
109
110
111
112
113
114
115


116
117
118
119
120
121
122
...
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
...
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
....
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
....
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
....
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
....
2074
2075
2076
2077
2078
2079
2080


2081
2082
2083
2084
2085
2086
2087
....
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
....
2624
2625
2626
2627
2628
2629
2630

2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
....
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
....
2784
2785
2786
2787
2788
2789
2790











2791
2792
2793
2794
2795
2796
2797
....
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
....
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
....
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
....
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
....
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
....
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425

3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469

3470

3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481


3482
3483
3484
3485

3486
3487


3488
3489
3490
3491
3492
3493
3494
....
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
  .pText       dd ?       ; pointer to the previous TTextLine of the affected line for chopChanged and chopDeleted
ends



rstruct TTextLine
  .flags        dd  ?   ; line flags

  .ch_len       dd  ?   ; the length of the text in utf-8 characters.
                        ;
  .debugdata    dd  ?   ; pointer to debug data, associated to this line
                        ;
  .syn_array    dd  ?   ; TArray of TTextChunk items for syntax colorization.
                        ; Should be updated by calling the syntax highlighting proc.
                        ;
  .syn_context  dd  ?   ; Syntax context after the line
                        ;
  .fold_level   dd  ?   ; the level of folding.

                rd  2
                        ;
  .             TText
ends



struct TTextChunk
................................................................................
  ._font_width    dd    ?

  ._numfont_width dd    ?

  ._left_margin   dd    ?
  ._num_margin    dd    ?



  ._caretPos      POINT

  ._selStart      POINT         ; The selection start point
  ._selEnd        POINT         ;
  ._selAreaUpdate dd ?

  ._selCmd        dd    ?       ; ==0 if the shift key wasn't pressed on the last keyboard interaction.
................................................................................
  method .EventScroll, .direction, .command, .value
  method .EventKeyPress, .utf8, .scancode, .kbdState
  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventButtonRelease, .button, .kbdState, .x, .y
  method .EventMouseMove, .x, .y, .kbdState

endobj




method TAsmEdit.EventMouseMove   ;, .x, .y, .kbdState
begin
        pushad
        mov     esi, [.self]

................................................................................




; returns in EDX the rectangle list.

method TAsmEdit._AddSelRectanglesAbs      ;, .pRectList



begin
        pushad







        mov     esi, [.self]
        mov     edx, [.pRectList]

        test    edx, edx
        jnz     .array_ok

        stdcall CreateArray, sizeof.RECT
        mov     edx, eax

.array_ok:

        mov     eax, [esi+TAsmEdit._selStart.x]
        mov     ecx, [esi+TAsmEdit._selStart.y]
        mov     ebx, [esi+TAsmEdit._selEnd.x]
        mov     edi, [esi+TAsmEdit._selEnd.y]

        test    [esi+TAsmEdit._options], aeoBlockSelection
        jz      .add_char

; block selection

        push    eax
        stdcall AddArrayItems, edx, 1
        mov     esi, eax
        pop     eax

        mov     [esi+RECT.left], eax
        mov     [esi+RECT.right], ebx

        mov     [esi+RECT.top], ecx
        mov     [esi+RECT.bottom], edi

        stdcall RectSort, esi
        inc     [esi+RECT.bottom]
        jmp     .end_sel


.add_char:
        cmp     ecx, edi        ; caret_y and selection_y
        jl      .order_ok
        jg      .reverse

        cmp     eax, ebx        ; caret_x and caret_y
        je      .end_sel
        jl      .order_ok

.reverse:
        xchg    eax, ebx
        xchg    ecx, edi

; now eax,ecx are the begining of the selection and ebx, edi the end of the selection.
.order_ok:
        test    eax, eax
        jz      .more_than_one

        push    eax
        stdcall AddArrayItems, edx, 1
        mov     esi, eax
        pop     eax

        mov     [esi+RECT.left], eax
        mov     [esi+RECT.top], ecx
        inc     ecx
        mov     [esi+RECT.bottom], ecx
        mov     [esi+RECT.right], $7fffffff

        cmp     ecx, edi
        je      .maybe_one
        jb      .more_than_one

; one line selection.
        mov     [esi+RECT.right], ebx
        jmp     .end_sel

.maybe_one:
        test    ebx, ebx
        jz      .end_sel

.more_than_one:
        cmp     ecx, edi
        je      .final_rect

        stdcall AddArrayItems, edx, 1
        mov     esi, eax

        mov     [esi+RECT.left], 0
        mov     [esi+RECT.top], ecx
        mov     [esi+RECT.right], $7fffffff
        mov     [esi+RECT.bottom], edi

.final_rect:
        test    ebx, ebx
        jz      .end_sel

        stdcall AddArrayItems, edx, 1
        mov     esi, eax

        mov     [esi+RECT.left], 0
        mov     [esi+RECT.top], edi
        inc     edi
        mov     [esi+RECT.right], ebx
        mov     [esi+RECT.bottom], edi

.end_sel:
        mov     [esp+4*regEDX], edx
        popad
        return
endp



................................................................................



method TAsmEdit._RenderTxt ; .pImage, .pRect
.rectr RECT  ; relative to the upper left corner of the window
.recta RECT  ; absolute in the document coordinates.
.rects RECT
.context dd ?
begin
        pushad

;if defined options.DebugMode & options.DebugMode
;        mov     eax, [.pRect]
;        mov     ecx, [eax+RECT.right]
;        mov     edx, [eax+RECT.bottom]
................................................................................

        mov     eax, [.rectr.left]
        sub     [.rectr.right], eax     ; .rectr.right == width

        stdcall LockImg, [.pImage]

        mov     ebx, [.recta.top]

        xor     edx, edx
        lea     eax, [4*ebx]                  ; the previous line for the syntax context
        sub     eax, 4
        js      .context_ok

        cmp     eax, [edi+TText.GapBegin]
        jb      @f
        add     eax, [edi+TText.GapEnd]
        sub     eax, [edi+TText.GapBegin]
@@:
        cmp     eax, [edi+TText.Length]
        jae     .context_ok

        mov     edx, [edi+eax]
        mov     edx, [edx+TTextLine.syn_context]

.context_ok:
        mov     [.context], edx


.line_loop:
        mov     edx, [.rectr.top]
        sub     edx, [esi+TAsmEdit._font_asc]   ; needed for the background and the left margin.

        xor     ecx, ecx
        test    [esi+TAsmEdit._options], aeoStripedBackground
        cmovnz  ecx, ebx
        and     ecx, 1
................................................................................
        jb      @f
        add     eax, [edi+TText.GapEnd]
        sub     eax, [edi+TText.GapBegin]
@@:
        cmp     eax, [edi+TText.Length]
        jae     .text_ok

        mov     edx, [edi+eax]
        cmp     [edx+TTextLine.syn_array], 0
        jne     .syn_ok

        stdcall [esi+TAsmEdit._syntax_proc], edx, [.context]
        mov     [.context], eax

.syn_ok:
        stdcall __RenderOneLine, [.pImage], edx, [.recta.left], [.recta.right], [.rectr.left], [.rectr.top]

        mov     eax, [edx+TTextLine.syn_context]
        mov     [.context], eax

.text_ok:

        mov     eax, [esi+TAsmEdit._font_height]
        add     [.rectr.top], eax

        inc     ebx
................................................................................

        OutputValue "    Font width:", eax, 10, -1

        stdcall GetTextBounds, "99999999", 8, [ASM.NumFont]
        sar     eax, 3
        mov     [edi+TAsmEdit._numfont_width], eax



        mov     [edi+TAsmEdit._syntax_proc], SyntaxFASM


; test only!

;        set     edi, TAsmEdit:Text, 0
        set     edi, TAsmEdit:Text, utf8_long    ; 0   ; set the needed text structures, but empty.
................................................................................
        dec     ebx
        cmp     ebx, [edi+RECT.top]
        jl      .next_rect

        exec    [.self], TAsmEdit:TextLine, ebx
        mov     esi, eax

        mov     eax, [esi+TTextLine.ch_len]
        cmp     eax, [edi+RECT.right]
        cmova   eax, [edi+RECT.right]

        stdcall TextIndexToPos, esi, eax   ; move the gap after the rectangle right bound.
        push    eax

        stdcall TextMoveGap, esi, eax
................................................................................
        xor     eax, $0d xor $0a
        cmp     [edi], al
        jne     .cr_ok
        inc     edi
.cr_ok:

        mov     esi, [esi]

        mov     [esi+TTextLine.ch_len], ecx
        stdcall IncCount, [ebx+TAsmEdit._line_widths], ecx
        mov     [ebx+TAsmEdit._line_widths], edx

        stdcall [ebx+TAsmEdit._syntax_proc], esi, [.context]
        mov     [.context], eax
        jmp     .text_loop


.end_text:

        exec    ebx, TAsmEdit:ComputeLeftMarginWidth
................................................................................
        cmovz   edi, ecx
        cmovnz  edi, eax        ; scroll more than needed.

        get     edx, esi, TAsmEdit:PosY

        mov     eax, [esi+TAsmEdit._caretPos.y]
        sub     eax, edx                       ; offset from the screen home.
        jz      .finish                        ; no need to scroll
        js      .do_scroll

        sub     eax, ebx
        jle     .finish

        neg     edi

.do_scroll:
        DebugMsg "Do scroll."

        sub     eax, edi
................................................................................

        inc     dword [esp+4*regEAX]

.finish:
        exec    esi, TAsmEdit:UpdateCaretPos
        popad
        return











endp






................................................................................
        test    [esi+TAsmEdit._options], aeoNavXCaretWrap
        jz      .set_pos

        exec    esi, TAsmEdit:TextLine, [esi+TAsmEdit._caretPos.y]
        cmovc   ebx, edx
        jc      .set_pos

        cmp     ebx, [eax+TTextLine.ch_len]
        jbe     .set_pos

        exec    esi, TAsmEdit:CaretUpDown, 1, FALSE
        exec    esi, TAsmEdit:CaretHome
        jmp     .finish

.set_pos:
................................................................................
begin
        push    esi
        mov     esi, [.self]

        exec    esi, TAsmEdit:TextLine, [esi+TAsmEdit._caretPos.y]      ; returns CF=1 and eax=0 on error.
        jc      .set_pos

        mov     eax, [eax+TTextLine.ch_len]

.set_pos:
        mov     [esi+TAsmEdit._caretPos.x], eax
        exec    esi, TAsmEdit:ScrollToCaretX

.finish:
        pop     esi
................................................................................

        pushd   [edi+TUndoInfo.pText] [ebx+eax]
        popd    [edi+TUndoInfo.pText] [ebx+eax]      ; xchg TTextLine structures of the line.

; fix the horizontal scrollbar size.

        mov     ecx, [ebx+eax]
        stdcall IncCount, [esi+TAsmEdit._line_widths], [ecx+TTextLine.ch_len]
        mov     [esi+TAsmEdit._line_widths], edx

        mov     ecx, [edi+TUndoInfo.pText]
        stdcall DecCount, [esi+TAsmEdit._line_widths], [ecx+TTextLine.ch_len]
        mov     [esi+TAsmEdit._line_widths], edx


        exec    esi, TAsmEdit:ScrollToCaretY
        exec    esi, TAsmEdit:UpdateScrollBar
;        exec    esi, TAsmEdit:Refresh

................................................................................
        jc      .finish

        mov     [ebx], eax
        mov     [esp+4*regEAX], ebx                     ; return value in EAX is the pointer to the new inserted TText.

        add     [edx+TText.GapBegin], 4

        stdcall IncCount, [esi+TAsmEdit._line_widths], 0
        mov     [esi+TAsmEdit._line_widths], edx

        clc

.finish:
        popad
        return
endp
................................................................................
begin
        return
endp


method TAsmEdit.JoinNextLine    ;, .LineNum
begin
        pushad

        mov     esi, [.self]
        mov     edi, [esi+TAsmEdit._lines]
        mov     ebx, [.LineNum]

        shl     ebx, 2
        lea     ecx, [ebx+4]

        cmp     ebx, [edi+TText.GapBegin]
        jb      .skip1
        add     ebx, [edi+TText.GapEnd]
        sub     ebx, [edi+TText.GapBegin]
.skip1:

        cmp     ecx, [edi+TText.GapBegin]
        jb      .skip2
        add     ecx, [edi+TText.GapEnd]
        sub     ecx, [edi+TText.GapBegin]
.skip2:
        cmp     ecx, [edi+TText.Length]
        jae     .finish ; nothing to join

        cmp     ebx, [edi+TText.Length]
        jae     .finish

; first fix the new line widths...

        mov     edx, [esi+TAsmEdit._line_widths]

        mov     eax, [edi+ebx]
        push    [eax+TTextLine.ch_len]
        stdcall DecCount, edx, [eax+TTextLine.ch_len]

        mov     eax, [edi+ecx]
        push    [eax+TTextLine.ch_len]
        stdcall DecCount, edx, [eax+TTextLine.ch_len]

        mov     [esi+TAsmEdit._line_widths], edx

        pop     eax edx
        add     eax, edx
        mov     edx, [edi+ebx]
        mov     [edx+TTextLine.ch_len], eax

        stdcall IncCount, [esi+TAsmEdit._line_widths], eax
        mov     [esi+TAsmEdit._line_widths], edx

; then join the texts

        stdcall TextAddText, [edi+ebx], -1, [edi+ecx]
        mov     [edi+ebx], edx

; then delete the next line

        mov     eax, [edi+ecx]
        stdcall FreeMem, [eax+TTextLine.syn_array]
        stdcall TextFree, eax     ; delete the next line... but what about the debug info and other attributes?

; reset the syntax coloring of the new line
        mov     eax, [edi+ebx]
        stdcall FreeMem, [eax+TTextLine.syn_array]
        and     [eax+TTextLine.syn_array], 0

        mov     eax, [.LineNum]
        lea     eax, [4*eax+4]
        stdcall TextMoveGap, edi, eax
        add     [edi+TText.GapEnd], 4

.finish:
        popad
        return
endp



method TAsmEdit.DeleteSelection
.rect RECT
................................................................................
.list dd ?
begin
        pushad

        exec    [.self], TAsmEdit:_AddSelRectanglesAbs, 0
        mov     [.list], edx

        OutputValue "Selection array count: ", [edx+TArray.count], 10, -1

        lea     edi, [edx+TArray.array]
        mov     ecx, [edx+TArray.count]
        test    ecx, ecx
        jz      .exit_empty

        mov     eax, ecx

        shl     eax, 4  ; sizeof.RECT
        add     edi, eax

.rect_loop:

        sub     edi, sizeof.RECT
        dec     ecx
        js      .finish

        OutputValue "RECT.left =", [edi+RECT.left], 10, -1
        OutputValue "RECT.top =", [edi+RECT.top], 10, -1
        OutputValue "RECT.right =", [edi+RECT.right], 10, -1
        OutputValue "RECT.bottom =", [edi+RECT.bottom], 10, -1

        mov     ebx, [edi+RECT.bottom]

.y_loop:
        dec     ebx
        cmp     ebx, [edi+RECT.top]
        jl      .rect_loop

        exec    [.self], TAsmEdit:TextLine, ebx
        jc      .y_loop
        mov     esi, eax

        stdcall TextIndexToPos, esi, [edi+RECT.left]
        stdcall TextMoveGap, esi, eax

        mov     eax, [esi+TTextLine.ch_len]
        cmp     eax, [edi+RECT.right]
        cmova   eax, [edi+RECT.right]                   ; delete up to the min(length, RECT.right) utf-8 character position!

        push    ecx
        push    eax             ; char count
        mov     ecx, [.self]

        stdcall TextIndexToPos, esi, eax
        sub     eax, [esi+TTextLine.GapBegin]
        add     [esi+TTextLine.GapEnd], eax             ; delete eax bytes!

        stdcall DecCount, [ecx+TAsmEdit._line_widths], [esi+TTextLine.ch_len]

        pop     eax
        sub     eax, [edi+RECT.left]    ; deleted characters!

        sub     [esi+TTextLine.ch_len], eax


        stdcall IncCount, edx, [esi+TTextLine.ch_len]
        mov     [ecx+TAsmEdit._line_widths], edx

        pop     ecx

; join the lines, if the selection is right to infinity:

        cmp     [edi+RECT.right], $7fffffff
        jne     .y_loop



        exec    [.self], TAsmEdit:JoinNextLine, ebx
        jmp     .y_loop

.finish:

        mov     esi, [.self]



        get     eax, esi, TAsmEdit:SelStartX
        get     ecx, esi, TAsmEdit:SelEndX
        cmp     eax, ecx
        cmovg   eax, ecx

        get     edx, esi, TAsmEdit:SelStartY
        get     ecx, esi, TAsmEdit:SelEndY
................................................................................
        mov     [.rect.right], ecx
        mov     [.rect.bottom], edx
        lea     eax, [.rect]
        exec    esi, TAsmEdit:_RenderTxt, [esi+TAsmEdit._imgText], eax
        exec    esi, TAsmEdit:_RenderLM, [esi+TAsmEdit._imgMargin], [.rect.top], [.rect.bottom]
        exec    esi, TAsmEdit:RectChanged2, 0
        exec    esi, TAsmEdit:UpdateCaretPos

.exit:
        stdcall FreeMem, [.list]
        clc
        popad
        return

.exit_empty:
        stdcall FreeMem, [.list]
        stc
        popad
        return
endp


method TAsmEdit.InsertString    ;, .text
begin