Subversion Repositories Kolibri OS

Rev

Rev 6097 | 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-2016. 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. draw_channel_text:
  179.  
  180.         mov     edi, [window_active]
  181.         and     [edi + window.flags], not FLAG_UPDATED  ; clear the 'window is updated' flag
  182.  
  183. ; Scan new text for newlines
  184.         mov     esi, [edi + window.text_scanned]
  185.         call    text_insert_newlines
  186.         add     [edi + window.text_lines], edx
  187.         mov     [edi + window.text_scanned], esi
  188.  
  189. ; Is scrollbar at lowest position?
  190.         test    [edi + window.flags], FLAG_SCROLL_LOW
  191.         jnz     .yesscroll                              ; Yes
  192.         cmp     [scroll2.all_redraw], 1                 ; No
  193.         jnz      .noscroll
  194.         mov     edx, [textbox_height]
  195.         add     edx, [edi + window.text_line_print]
  196.     cmp edx, [edi + window.text_lines]
  197.         jl      .noscroll
  198.   .yesscroll:
  199. ; Scrollbar was at lowest position, scroll down automatically when new text arrived.
  200.         mov     edx, [edi + window.text_lines]
  201.         sub     edx, [textbox_height]
  202.         jg      @f
  203.         mov     [edi + window.text_line_print], 0
  204.         jmp     .noscroll                               ; There are less lines of text than fit into the window, dont scroll..
  205.   @@:
  206.         sub     edx, [edi + window.text_line_print]
  207.         je      .noscroll                               ; We are already at the bottom pos, dont scroll..
  208.   .scroll_to_pos:               ; edx = number of lines to go up/down (flags must indicate direction)
  209.         pushf
  210.         add     [edi + window.text_line_print], edx
  211.         mov     esi, [edi + window.text_print]
  212.         popf
  213.         jg      .loop_forward
  214.         std                     ; set direction flag so we can scan backwards
  215.         dec     esi
  216.         dec     esi             ; move our cursor just in front of newline, for scanning backwards
  217.   .loop_backward:
  218.         call    text_nextline
  219.         inc     edx
  220.         jnz     .loop_backward
  221.         inc     esi
  222.         inc     esi             ; move the cursor just after last newline
  223.         cld
  224.         jmp     .ok
  225.  
  226.   .loop_forward:
  227.         call    text_nextline
  228.         dec     edx
  229.         jnz     .loop_forward
  230.   .ok:
  231.         mov     [edi + window.text_print], esi
  232.   .noscroll:
  233.  
  234. ; Update and draw scrollbar when nescessary
  235.         mov     edx, [edi + window.text_lines]
  236.         cmp     edx, [textbox_height]
  237.         jbe     .scroll_done
  238.  
  239.         mov     [scroll2.max_area], edx
  240.         mov     eax, [edi + window.text_line_print]
  241.         mov     [scroll2.position], eax
  242.  
  243.         push    dword scroll2                   ; redraw scrollbar
  244.         call    [scrollbar_draw]
  245.         mov     [scroll2.all_redraw], 0         ; next time, dont redraw it completely
  246.   .scroll_done:
  247.  
  248. ; Calculate start offset coordinates (align text to bottom)
  249.         mov     ebx, [textbox_height]
  250.         sub     ebx, [edi + window.text_lines]
  251.         jb      .no_offset
  252.         imul    ebx, FONT_HEIGHT
  253.         push    [edi + window.text_start]
  254.         pop     [edi + window.text_print]
  255.         jmp     .draw_text
  256.   .no_offset:
  257.         xor     ebx, ebx
  258.   .draw_text:
  259.  
  260. ; Prepare to actually draw some text
  261.         add     ebx, TEXT_X shl 16 + TEXT_Y     ; text coordinates
  262.         mov     ecx, [colors.work_text]         ; default text color
  263.         or      ecx, 0x30000000
  264.         mov     edx, [edi + window.text_print]  ; start of text to print
  265.  
  266. ; Scan backwards on line for color escape codes
  267.         mov     esi, edx
  268.         push    edx
  269.         std
  270.   @@:
  271.         lodsb
  272.         cmp     al, 0           ; end of text
  273.         je      @f
  274.         cmp     al, 10          ; hard newline
  275.         je      @f
  276.         cmp     al, 3           ; mIRC escape code
  277.         jne     @b
  278.  
  279.         cld
  280.         lea     edx, [esi+2]
  281.         call    dec_to_esi
  282.         jz      @f
  283.         mov     ecx, [irc_colors + 4*esi]
  284.         or      ecx, 0x30000000                 ; UTF-8 text
  285.  
  286.         cmp     byte[edx], ','                  ; background color?
  287.         jne     @f
  288.         inc     edx
  289.         call    dec_to_esi
  290.         jz      @f
  291.         mov     edi, [irc_colors + 4*esi]
  292.         or      ecx, 0x40000000                 ; enable background color
  293.   @@:
  294.         cld
  295.  
  296.         pop     edx
  297.         mov     eax, [textbox_height]           ; max number of lines to draw
  298.   .drawloop:
  299.         cmp     byte[edx], 0
  300.         je      .end_of_text
  301.  
  302. ; Clear one row of characters
  303.         pusha
  304.         mov     cx, bx
  305.         shl     ecx, 16
  306.         mov     cx, FONT_HEIGHT
  307.         mov     ebx, TEXT_X shl 16
  308.         mov     bx, word[textbox_width]
  309.         imul    bx, FONT_WIDTH
  310.         mov     edx, [colors.work]
  311.         mcall   13                              ; draw rectangle
  312.         popa
  313.  
  314.         push    eax
  315.         mov     esi, [textbox_width]
  316.   .line:
  317.         cmp     byte[edx], 0
  318.         je      .end_of_text
  319.         cmp     byte[edx], 13
  320.         je      .newline_soft
  321.         cmp     byte[edx], 10
  322.         je      .newline_hard
  323.  
  324.         push    esi
  325.         cmp     byte[edx], 3                    ; escape code for mIRC colors
  326.         jne     .no_colors
  327.         inc     edx
  328.         call    dec_to_esi
  329.         jz      .no_colors
  330.         mov     ecx, [irc_colors + 4*esi]
  331.         or      ecx, 0x30000000
  332.  
  333.         cmp     byte[edx], ','                  ; background color?
  334.         jne     .no_colors
  335.         inc     edx
  336.         call    dec_to_esi
  337.         jz      .no_colors
  338.         mov     edi, [irc_colors + 4*esi]
  339.         or      ecx, 0x40000000
  340.   .no_colors:
  341.  
  342.         mov     esi, 1
  343.         mcall   4                               ; draw text
  344.  
  345.         mov     esi, 1
  346.         mov     al, byte[edx]
  347.         test    al, 10000000b
  348.         jz      @f
  349.         mov     esi, 4
  350.         and     al, 11111000b
  351.         cmp     al, 11110000b
  352.         je      @f
  353.         dec     esi
  354.         and     al, 11110000b
  355.         cmp     al, 11100000b
  356.         je      @f
  357.         dec     esi
  358.   @@:
  359.  
  360.         add     ebx, FONT_WIDTH shl 16
  361.         add     edx, esi
  362.         pop     esi
  363.         dec     esi
  364.         jnz     .line
  365.         jmp     .line_full
  366.  
  367.   .newline_hard:
  368.         mov     ecx, [colors.work_text]
  369.         or      ecx, 0x30000000
  370.   .newline_soft:
  371.         inc     edx
  372.   .line_full:
  373.         and     ebx, 0x0000ffff
  374.         add     ebx, TEXT_X shl 16 + FONT_HEIGHT
  375.         pop     eax
  376.         dec     eax
  377.         jnz     .drawloop
  378.   .end_of_text:
  379.  
  380.         ret
  381.  
  382.  
  383.  
  384.  
  385. dec_to_esi:
  386.  
  387.         xor     esi, esi
  388.   .loop:
  389.         movzx   eax, byte[edx]
  390.         sub     al, '0'
  391.         jb      .done
  392.         cmp     al, 9
  393.         ja      .done
  394.         inc     edx
  395.         lea     esi, [esi*4 + esi]      ; esi * 5
  396.         lea     esi, [esi*2 + eax]      ; esi * 2 + eax
  397.         jmp     .loop
  398.   .done:
  399.         cmp     esi, 16
  400.         jae     .fail
  401.         ret
  402.  
  403.   .fail:
  404.         xor     esi, esi
  405.         ret
  406.  
  407.  
  408.  
  409. if TIMESTAMP
  410. print_timestamp:
  411.  
  412.         pusha
  413.         mcall   3                       ; get system time
  414.         mov     ebx, eax
  415.  
  416.         mov     al, '['
  417.         call    print_char
  418.         mov     ecx, TIMESTAMP
  419.   .loop:
  420.         mov     al, bl
  421.         shr     al, 4
  422.         add     al, '0'
  423.         call    print_char
  424.  
  425.         mov     al, bl
  426.         and     al, 0x0f
  427.         add     al, '0'
  428.         call    print_char
  429.  
  430.         dec     ecx
  431.         jz      .done
  432.  
  433.         mov     al, ':'
  434.         call    print_char
  435.         shr     ebx, 8
  436.         jmp     .loop
  437.   .done:
  438.         mov     al, ']'
  439.         call    print_char
  440.         mov     al, ' '
  441.         call    print_char
  442.  
  443.         popa
  444.         ret
  445. end if