Subversion Repositories Kolibri OS

Rev

Rev 9826 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2024. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;   Written by hidnplayr@kolibrios.org                            ;;
  7. ;;                                                                 ;;
  8. ;;         GNU GENERAL PUBLIC LICENSE                              ;;
  9. ;;          Version 2, June 1991                                   ;;
  10. ;;                                                                 ;;
  11. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  12.  
  13.  
  14. text_insert_newlines:                   ; esi = ASCIIZ string
  15.  
  16.         xor     edx, edx                ; number of lines of text
  17.         cmp     byte[esi], 0
  18.         je      .done
  19.   .next_line:
  20.         xor     ebx, ebx
  21.         mov     ecx, [textbox_width]
  22.         inc     ecx
  23.   .more:
  24.         dec     ecx
  25.         jz      .end_of_line
  26.   .next_byte:
  27.         lodsb                           ; get one character of the string
  28.         test    al, al                  ; end of string?
  29.         jz      .almost_done
  30.         cmp     al, ' '                 ; it's a space! remember its position
  31.         je      .space
  32.         cmp     al, 13                  ; we already inserted a newline once, make it a space again
  33.         je      .soft_nl
  34.         cmp     al, 10                  ; it's a newline, continue onto the next line
  35.         je      .newline
  36.         and     al, 0xc0                ; Is it a multi byte UTF8 char?
  37.         cmp     al, 0x80
  38.         je      .next_byte
  39.         jmp     .more
  40.   .newline:
  41.         inc     edx
  42.         jmp     .next_line
  43.   .soft_nl:
  44.         mov     byte[esi-1], ' '
  45.   .space:
  46.         mov     ebx, esi                ; last detected space
  47.         jmp     .more
  48.   .end_of_line:
  49.         inc     edx
  50.         test    ebx, ebx                ; did we detect any spaces on this line?
  51.         jz      .next_line              ; no:   just continue onto the next line
  52.         mov     byte[ebx-1], 13         ; yes:  replace last space on line with a soft newline
  53.         mov     esi, ebx                ;       and continue parsing just after last space
  54.         jmp     .next_line              ;
  55.   .almost_done:
  56.         dec     esi
  57.   .done:
  58.  
  59.         ret
  60.  
  61.  
  62. ;----------------------------------
  63. ; scan untill next line is reached
  64. ;
  65. ; When you set the direction flag before calling, you can also scan for previous line!
  66. ; IN:   esi
  67. ; OUT:  esi
  68. ;----------------------------------
  69. text_nextline:
  70.  
  71.         mov     ecx, [textbox_width]
  72.   .loop:
  73.         lodsb
  74.         test    al, al
  75.         jz      .done
  76.         cmp     al, 10
  77.         je      .done
  78.         cmp     al, 13
  79.         je      .done
  80.         and     al, 0xc0
  81.         cmp     al, 0x80
  82.         je      .loop           ; This byte is the second, third or fourth byte of a multi-byte UTF8 char
  83.         dec     ecx
  84.         jnz     .loop
  85.   .done:
  86.         ret
  87.  
  88. ;----------------------------------
  89. ; print string
  90. ;
  91. ; IN:   esi = ptr to string
  92. ;       bl = char which marks end of string
  93. ; OUT:  esi = ptr to end of str
  94. ;----------------------------------
  95. print_string:
  96.  
  97.         push    eax
  98.   .loop:
  99.         lodsb
  100.         cmp     al, bl
  101.         je      .done
  102.         cmp     al, 13
  103.         je      .loop
  104.         test    al, al
  105.         jz      .done
  106.         call    print_char
  107.         jmp     .loop
  108.   .done:
  109.         pop     eax
  110.  
  111.         ret
  112.  
  113.  
  114. ;----------------------------------
  115. ; print ASCIIZ string
  116. ;
  117. ; IN:   esi = ptr to ASCIIZ string
  118. ; OUT:  esi = ptr to end of str
  119. ;----------------------------------
  120. print_asciiz:
  121.  
  122.         push    eax
  123.   .loop:
  124.         lodsb
  125.         test    al, al
  126.         jz      .done
  127.         call    print_char
  128.         jmp     .loop
  129.   .done:
  130.         pop     eax
  131.  
  132.         ret
  133.  
  134.  
  135. ;----------------------------------
  136. ; print character
  137. ;
  138. ; IN:   al = char to print
  139. ; OUT:  /
  140. ;----------------------------------
  141. print_char:
  142.  
  143.         push    esi edi
  144.         mov     esi, [window_print]
  145.         mov     edi, [esi + window.text_write]
  146.         stosb
  147.         cmp     edi, [esi + window.text_end]
  148.         jae     .uh_ow
  149.         mov     [esi + window.text_write], edi
  150.   .continue:
  151.         or      [esi + window.flags], FLAG_UPDATED
  152.         pop     edi esi
  153.  
  154.         ret
  155.  
  156.   .uh_ow:
  157.         pusha
  158.         mov     edi, [esi + window.text_start]
  159.         mov     [esi + window.text_print], edi
  160.         lea     esi, [edi + TEXT_BUFFERSIZE/2]
  161.         call    text_nextline
  162.         mov     ecx, TEXT_BUFFERSIZE/8
  163.         rep     movsd
  164.         mov     esi, edi
  165.         call    text_insert_newlines
  166.  
  167.         mov     ebx, [window_print]
  168.         mov     [ebx + window.text_lines], edx
  169.         mov     [ebx + window.text_scanned], esi
  170.         mov     [ebx + window.text_write], esi
  171.         mov     [ebx + window.text_line_print], 0
  172.         popa
  173.  
  174.         jmp     .continue
  175.  
  176.  
  177.  
  178. ;-----------------------------------------------
  179. ; Draw text of the current window to the screen
  180. ;
  181. ; IN:   /
  182. ; OUT:  /
  183. ;-----------------------------------------------
  184. draw_channel_text:
  185.  
  186.         mov     edi, [window_active]
  187.         and     [edi + window.flags], not FLAG_UPDATED  ; clear the 'window is updated' flag
  188.  
  189. ; Scan new text for newlines
  190.         mov     esi, [edi + window.text_scanned]
  191.         call    text_insert_newlines
  192.         add     [edi + window.text_lines], edx
  193.         mov     [edi + window.text_scanned], esi
  194.  
  195. ; Is scrollbar at lowest position?
  196.         test    [edi + window.flags], FLAG_SCROLL_LOW
  197.         jnz     .yesscroll                              ; Yes
  198.         cmp     [scroll2.all_redraw], 1                 ; No
  199.         jnz      .noscroll
  200.         mov     edx, [textbox_height]
  201.         add     edx, [edi + window.text_line_print]
  202.     cmp edx, [edi + window.text_lines]
  203.         jl      .noscroll
  204.   .yesscroll:
  205. ; Scrollbar was at lowest position, scroll down automatically when new text arrived.
  206.         mov     edx, [edi + window.text_lines]
  207.         sub     edx, [textbox_height]
  208.         jg      @f
  209.         mov     [edi + window.text_line_print], 0
  210.         jmp     .noscroll                               ; There are less lines of text than fit into the window, dont scroll..
  211.   @@:
  212.         sub     edx, [edi + window.text_line_print]
  213.         je      .noscroll                               ; We are already at the bottom pos, dont scroll..
  214.   .scroll_to_pos:               ; edx = number of lines to go up/down (flags must indicate direction)
  215.         pushf
  216.         add     [edi + window.text_line_print], edx
  217.         mov     esi, [edi + window.text_print]
  218.         popf
  219.         jg      .loop_forward
  220.         std                     ; set direction flag so we can scan backwards
  221.         dec     esi
  222.         dec     esi             ; move our cursor just in front of newline, for scanning backwards
  223.   .loop_backward:
  224.         call    text_nextline
  225.         inc     edx
  226.         jnz     .loop_backward
  227.         inc     esi
  228.         inc     esi             ; move the cursor just after last newline
  229.         cld
  230.         jmp     .ok
  231.  
  232.   .loop_forward:
  233.         call    text_nextline
  234.         dec     edx
  235.         jnz     .loop_forward
  236.   .ok:
  237.         mov     [edi + window.text_print], esi
  238.   .noscroll:
  239.  
  240. ; Update and draw scrollbar when nescessary
  241.         mov     edx, [edi + window.text_lines]
  242.         cmp     edx, [textbox_height]
  243.         jbe     .scroll_done
  244.  
  245.         mov     [scroll2.max_area], edx
  246.         mov     eax, [edi + window.text_line_print]
  247.         mov     [scroll2.position], eax
  248.  
  249.         push    dword scroll2                   ; redraw scrollbar
  250.         call    [scrollbar_draw]
  251.         mov     [scroll2.all_redraw], 0         ; next time, dont redraw it completely
  252.   .scroll_done:
  253.  
  254. ; Calculate start offset coordinates (align text to bottom)
  255.         mov     ebx, [textbox_height]
  256.         sub     ebx, [edi + window.text_lines]
  257.         jb      .no_offset
  258.         imul    ebx, FONT_HEIGHT
  259.         push    [edi + window.text_start]
  260.         pop     [edi + window.text_print]
  261.         jmp     .draw_text
  262.   .no_offset:
  263.         xor     ebx, ebx
  264.   .draw_text:
  265.  
  266. ; Prepare to actually draw some text
  267.         add     ebx, TEXT_X shl 16 + TEXT_Y     ; text coordinates
  268.         mov     ecx, [colors.work_text]         ; default text color
  269.         or      ecx, 0x30000000
  270.         mov     edx, [edi + window.text_print]  ; start of text to print
  271.  
  272. ; Scan backwards on line for color escape codes
  273.         mov     esi, edx
  274.         push    edx
  275.         std
  276.   @@:
  277.         lodsb
  278.         cmp     al, 0           ; end of text
  279.         je      @f
  280.         cmp     al, 10          ; hard newline
  281.         je      @f
  282.         cmp     al, 3           ; mIRC escape code
  283.         jne     @b
  284.  
  285.         cld
  286.         lea     edx, [esi+2]
  287.         call    dec_to_esi
  288.         jz      @f
  289.         mov     ecx, [irc_colors + 4*esi]
  290.         or      ecx, 0x30000000                 ; UTF-8 text
  291.  
  292.         cmp     byte[edx], ','                  ; background color?
  293.         jne     @f
  294.         inc     edx
  295.         call    dec_to_esi
  296.         jz      @f
  297.         mov     edi, [irc_colors + 4*esi]
  298.         or      ecx, 0x40000000                 ; enable background color
  299.   @@:
  300.         cld
  301.  
  302.         pop     edx
  303.         mov     eax, [textbox_height]           ; max number of lines to draw
  304.   .drawloop:
  305.         cmp     byte[edx], 0
  306.         je      .end_of_text
  307.  
  308. ; Clear one row of characters
  309.         pusha
  310.         mov     cx, bx
  311.         shl     ecx, 16
  312.         mov     cx, FONT_HEIGHT
  313.         mov     ebx, TEXT_X shl 16
  314.         mov     bx, word[textbox_width]
  315.         imul    bx, FONT_WIDTH
  316.         mov     edx, [colors.work]
  317.         mcall   13                              ; draw rectangle
  318.         popa
  319.  
  320.         push    eax
  321.   .line:
  322.         cmp     byte[edx], 0x20
  323.         jae     .printable
  324.         cmp     byte[edx], 0
  325.         je      .end_of_text
  326.         cmp     byte[edx], 13
  327.         je      .newline_soft
  328.         cmp     byte[edx], 10
  329.         je      .newline_hard
  330.  
  331.         cmp     byte[edx], 3                    ; escape code for mIRC colors
  332.         jne     .no_colors
  333.         inc     edx
  334.         call    dec_to_esi
  335.         jz      .line
  336.         mov     ecx, [irc_colors + 4*esi]
  337.         or      ecx, 0x30000000
  338.  
  339.         cmp     byte[edx], ','                  ; background color?
  340.         jne     .line
  341.         inc     edx
  342.         call    dec_to_esi
  343.         jz      .line
  344.         mov     edi, [irc_colors + 4*esi]
  345.         or      ecx, 0x40000000
  346.   .no_colors:
  347.  
  348. ; Some non-printable, just skip it
  349.         inc     edx
  350.         jmp     .line
  351.  
  352. ;-------------------------------------------
  353. ; Count characters until 0, 10, 13 or 3 byte
  354.  
  355.   .printable:
  356.         push    edx
  357.         xor     esi, esi
  358.         dec     esi
  359.   .next_char:
  360.         inc     esi
  361.         cmp     esi, [textbox_width]
  362.         je      .cnt_done
  363.         mov     al, byte[edx]
  364.         cmp     al, 0x20
  365.         jb      .cnt_done
  366.  
  367.         inc     edx
  368.         test    al, 10000000b
  369.         jz      .next_char              ; 1 byte wide
  370.  
  371.         add     edx, 3
  372.         and     al, 11111000b
  373.         cmp     al, 11110000b
  374.         je      .next_char              ; 4 bytes wide
  375.  
  376.         dec     edx
  377.         and     al, 11110000b
  378.         cmp     al, 11100000b
  379.         je      .next_char              ; 3 bytes wide
  380.         dec     edx                     ; 2 bytes wide
  381.         jmp     .next_char
  382.   .cnt_done:
  383.         mov     eax, edx
  384.         pop     edx
  385.         push    eax
  386.         mcall   4                       ; draw text
  387.         pop     edx                     ; next start ptr
  388.  
  389.         cmp     esi, [textbox_width]
  390.         je      .line_full
  391.         imul    esi, FONT_WIDTH shl 16
  392.         add     ebx, esi
  393.         jmp     .line
  394.  
  395.   .newline_hard:
  396.         mov     ecx, [colors.work_text]
  397.         or      ecx, 0x30000000
  398.   .newline_soft:
  399.         inc     edx
  400.   .line_full:
  401.         and     ebx, 0x0000ffff
  402.         add     ebx, TEXT_X shl 16 + FONT_HEIGHT
  403.         pop     eax
  404.         dec     eax
  405.         jnz     .drawloop
  406.   .end_of_text:
  407.  
  408.         ret
  409.  
  410.  
  411.  
  412.  
  413. dec_to_esi:
  414.  
  415.         xor     esi, esi
  416.   .loop:
  417.         movzx   eax, byte[edx]
  418.         sub     al, '0'
  419.         jb      .done
  420.         cmp     al, 9
  421.         ja      .done
  422.         inc     edx
  423.         lea     esi, [esi*4 + esi]      ; esi * 5
  424.         lea     esi, [esi*2 + eax]      ; esi * 2 + eax
  425.         jmp     .loop
  426.   .done:
  427.         cmp     esi, 16
  428.         jae     .fail
  429.         ret
  430.  
  431.   .fail:
  432.         xor     esi, esi
  433.         ret
  434.  
  435.  
  436.  
  437. if TIMESTAMP
  438. print_timestamp:
  439.  
  440.         pusha
  441.         mcall   3                       ; get system time
  442.         mov     ebx, eax
  443.  
  444.         mov     al, '['
  445.         call    print_char
  446.         mov     ecx, TIMESTAMP
  447.   .loop:
  448.         mov     al, bl
  449.         shr     al, 4
  450.         add     al, '0'
  451.         call    print_char
  452.  
  453.         mov     al, bl
  454.         and     al, 0x0f
  455.         add     al, '0'
  456.         call    print_char
  457.  
  458.         dec     ecx
  459.         jz      .done
  460.  
  461.         mov     al, ':'
  462.         call    print_char
  463.         shr     ebx, 8
  464.         jmp     .loop
  465.   .done:
  466.         mov     al, ']'
  467.         call    print_char
  468.         mov     al, ' '
  469.         call    print_char
  470.  
  471.         popa
  472.         ret
  473. end if