Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2021. 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], 0
  323.         je      .end_of_text
  324.         cmp     byte[edx], 13
  325.         je      .newline_soft
  326.         cmp     byte[edx], 10
  327.         je      .newline_hard
  328.  
  329.         cmp     byte[edx], 3                    ; escape code for mIRC colors
  330.         jne     .no_colors
  331.         inc     edx
  332.         call    dec_to_esi
  333.         jz      .no_colors
  334.         mov     ecx, [irc_colors + 4*esi]
  335.         or      ecx, 0x30000000
  336.  
  337.         cmp     byte[edx], ','                  ; background color?
  338.         jne     .no_colors
  339.         inc     edx
  340.         call    dec_to_esi
  341.         jz      .no_colors
  342.         mov     edi, [irc_colors + 4*esi]
  343.         or      ecx, 0x40000000
  344.   .no_colors:
  345.  
  346. ;-------------------------------------------
  347. ; Count characters until 0, 10, 13 or 3 byte
  348.  
  349.         push    edx
  350.         xor     esi, esi
  351.         dec     esi
  352.   .next_char:
  353.         inc     esi
  354.         cmp     esi, [textbox_width]
  355.         je      .cnt_done
  356.         mov     al, byte[edx]
  357.         cmp     al, 13
  358.         jbe     .cnt_done
  359.  
  360.         inc     edx
  361.         test    al, 10000000b
  362.         jz      .next_char              ; 1 byte wide
  363.  
  364.         add     edx, 4
  365.         and     al, 11111000b
  366.         cmp     al, 11110000b
  367.         je      .next_char              ; 4 bytes wide
  368.  
  369.         dec     edx
  370.         and     al, 11110000b
  371.         cmp     al, 11100000b
  372.         je      .next_char              ; 3 bytes wide
  373.         dec     edx                     ; 2 bytes wide
  374.         jmp     .next_char
  375.   .cnt_done:
  376.         mov     eax, edx
  377.         pop     edx
  378.         push    eax
  379.         mcall   4                       ; draw text
  380.         pop     edx                     ; next start ptr
  381.  
  382.         cmp     esi, [textbox_width]
  383.         je      .line_full
  384.         imul    esi, FONT_WIDTH shl 16
  385.         add     ebx, esi
  386.         jmp     .line
  387.  
  388.   .newline_hard:
  389.         mov     ecx, [colors.work_text]
  390.         or      ecx, 0x30000000
  391.   .newline_soft:
  392.         inc     edx
  393.   .line_full:
  394.         and     ebx, 0x0000ffff
  395.         add     ebx, TEXT_X shl 16 + FONT_HEIGHT
  396.         pop     eax
  397.         dec     eax
  398.         jnz     .drawloop
  399.   .end_of_text:
  400.  
  401.         ret
  402.  
  403.  
  404.  
  405.  
  406. dec_to_esi:
  407.  
  408.         xor     esi, esi
  409.   .loop:
  410.         movzx   eax, byte[edx]
  411.         sub     al, '0'
  412.         jb      .done
  413.         cmp     al, 9
  414.         ja      .done
  415.         inc     edx
  416.         lea     esi, [esi*4 + esi]      ; esi * 5
  417.         lea     esi, [esi*2 + eax]      ; esi * 2 + eax
  418.         jmp     .loop
  419.   .done:
  420.         cmp     esi, 16
  421.         jae     .fail
  422.         ret
  423.  
  424.   .fail:
  425.         xor     esi, esi
  426.         ret
  427.  
  428.  
  429.  
  430. if TIMESTAMP
  431. print_timestamp:
  432.  
  433.         pusha
  434.         mcall   3                       ; get system time
  435.         mov     ebx, eax
  436.  
  437.         mov     al, '['
  438.         call    print_char
  439.         mov     ecx, TIMESTAMP
  440.   .loop:
  441.         mov     al, bl
  442.         shr     al, 4
  443.         add     al, '0'
  444.         call    print_char
  445.  
  446.         mov     al, bl
  447.         and     al, 0x0f
  448.         add     al, '0'
  449.         call    print_char
  450.  
  451.         dec     ecx
  452.         jz      .done
  453.  
  454.         mov     al, ':'
  455.         call    print_char
  456.         shr     ebx, 8
  457.         jmp     .loop
  458.   .done:
  459.         mov     al, ']'
  460.         call    print_char
  461.         mov     al, ' '
  462.         call    print_char
  463.  
  464.         popa
  465.         ret
  466. end if