files
kterm/textview.inc

271 lines
7.2 KiB
PHP

BUF_SIZE = 4096
FRM_WIDTH = 1
MARGIN = 1
struct TEXT_VIEW
left dd ?
top dd ?
width dd ?
height dd ?
bg_color dd ?
fg_color dd ?
buf_data dd ?
buf_size dd ?
data_size dd ?
total_lines dd ?
curr_line dd ?
max_length dd ? ; length of the longest string
rows dd ?
cols dd ?
ends
proc text_view_init stdcall, text_view:dword
mov ecx, [text_view]
xor eax, eax
mov [ecx + TEXT_VIEW.buf_data], eax
mov [ecx + TEXT_VIEW.buf_size], eax
mov [ecx + TEXT_VIEW.data_size], eax
mov [ecx + TEXT_VIEW.total_lines], eax
mov [ecx + TEXT_VIEW.curr_line], eax
mov [ecx + TEXT_VIEW.max_length], eax
ret
endp
proc text_view_deinit stdcall uses ebx, text_view:dword
mov ebx, [text_view]
mov ecx, [ebx + TEXT_VIEW.buf_data]
test ecx, ecx
jz .exit
mcall SF_SYS_MISC, SSF_MEM_FREE
.exit
ret
endp
proc text_view_draw stdcall uses ebx esi edi, text_view:dword
mov esi, [text_view]
call tv.draw_frame_and_bg
call tv.calc_rows_and_cols
DEBUGF 0, "text_view rows=%d cols=%d\n", [esi + TEXT_VIEW.rows], [esi + TEXT_VIEW.cols]
mov eax, [esi + TEXT_VIEW.curr_line]
mov ebx, [esi + TEXT_VIEW.total_lines]
DEBUGF 0, "text_view curr_line=%d total_lines=%d\n", eax, ebx
sub ebx, eax
cmp ebx, [esi + TEXT_VIEW.rows]
jbe @f
mov ebx, [esi + TEXT_VIEW.rows]
@@:
mov edi, [esi + TEXT_VIEW.buf_data]
call goto_curr_line
mov ecx, ebx ; ecx = count lines
xor eax, eax ; eax = index from 0
mov ebx, [esi + TEXT_VIEW.left]
add ebx, MARGIN + FRM_WIDTH
shl ebx, 16
add ebx, [esi + TEXT_VIEW.top]
add ebx, MARGIN + FRM_WIDTH
.draw_lines:
cmp eax, ecx
jae .draw_lines_end
push eax ecx
call tv.draw_single_line
; move edi pointer to the next string
add edi, eax
inc edi
pop ecx eax
inc eax ; next line num
add ebx, FONT_HEIGHT + MARGIN
jmp .draw_lines
.draw_lines_end:
ret
endp
proc text_view_append_line stdcall uses ebx esi edi, text_view:dword, string:dword
mov esi, [string]
call strlen
inc eax ; include \0
mov esi, [text_view]
mov edi, eax
add eax, [esi + TEXT_VIEW.data_size]
cmp eax, [esi + TEXT_VIEW.buf_size]
jbe .noalloc
and eax, not (BUF_SIZE - 1)
add eax, BUF_SIZE
mov ecx, eax
mov edx, [esi + TEXT_VIEW.buf_data]
mcall SF_SYS_MISC, SSF_MEM_REALLOC
test eax, eax
jz .exit
mov [esi + TEXT_VIEW.buf_data], eax
mov [esi + TEXT_VIEW.buf_size], ecx
.noalloc:
inc [esi + TEXT_VIEW.total_lines]
mov eax, edi
cmp eax, [esi + TEXT_VIEW.max_length]
jbe .short
mov [esi + TEXT_VIEW.max_length], eax
.short:
mov ecx, edi
mov edi, [esi + TEXT_VIEW.buf_data]
add edi, [esi + TEXT_VIEW.data_size]
add [esi + TEXT_VIEW.data_size], ecx
mov esi, [string]
cld
rep movsb
.exit:
ret
endp
proc text_view_clear stdcall uses ebx, text_view:dword
mov edx, [text_view]
mov ecx, [edx + TEXT_VIEW.buf_data]
test ecx, ecx
jz @f
mcall SF_SYS_MISC, SSF_MEM_FREE
@@:
xor eax, eax
mov [edx + TEXT_VIEW.buf_data], eax
mov [edx + TEXT_VIEW.buf_size], eax
mov [edx + TEXT_VIEW.data_size], eax
mov [edx + TEXT_VIEW.total_lines], eax
mov [edx + TEXT_VIEW.curr_line], eax
mov [edx + TEXT_VIEW.max_length], eax
ret
endp
proc text_view_deinit stdcall uses ebx, text_view:dword
mov edx, [text_view]
mov ecx, [edx + TEXT_VIEW.buf_data]
test ecx, ecx
jz @f
mcall SF_SYS_MISC, SSF_MEM_FREE
@@:
ret
endp
proc tv.draw_frame_and_bg
; esi = text_view
mov ebx, [esi + TEXT_VIEW.left]
shl ebx, 16
add ebx, [esi + TEXT_VIEW.width]
mov ecx, [esi + TEXT_VIEW.top]
shl ecx, 16
add ecx, [esi + TEXT_VIEW.height]
mov edx, [esi + TEXT_VIEW.fg_color]
call draw_frame
add ebx, 1 shl 16
sub ebx, 2
add ecx, 1 shl 16
sub ecx, 2
mov edx, [esi + TEXT_VIEW.bg_color]
mcall SF_DRAW_RECT
ret
endp
proc tv.calc_rows_and_cols
; esi = text_view
mov eax, [esi + TEXT_VIEW.width]
sub eax, (FRM_WIDTH + MARGIN) * 2
shr eax, 3 ; assume that font width is 8 px
mov [esi + TEXT_VIEW.cols], eax
xor edx, edx
mov eax, [esi + TEXT_VIEW.height]
sub eax, MARGIN * 2
mov ebx, FONT_HEIGHT + MARGIN
div ebx
mov [esi + TEXT_VIEW.rows], eax
ret
endp
proc tv.draw_single_line uses esi
; esi = text_view
; ebx = coordinates: left << 16 + top
; edi = pointer to the first byte of string in [text_view.buf_data]
; return: eax = length of the string
mov ecx, 0x10000000 ; fixed-length string
or ecx, [esi + TEXT_VIEW.fg_color]
push esi
mov esi, edi
call strlen
pop esi
push eax
cmp eax, [esi + TEXT_VIEW.cols]
jbe .len_ok
mov eax, [esi + TEXT_VIEW.cols]
.len_ok:
mov esi, eax
mov edx, edi
mcall SF_DRAW_TEXT
pop eax
ret
endp
proc goto_curr_line uses ebx esi
; eax = curr line index
; edi = buf
mov ebx, eax
xor ecx, ecx
mov esi, edi
cld
.scan:
cmp ecx, ebx
je .exit
lodsb
test al, al
jnz .scan
inc ecx
jmp .scan
.exit:
mov eax, ebx
mov edi, esi
ret
endp
proc draw_frame
; ebx = left << 16 + width
; ecx = top << 16 + height
; edx = color
push ebx ecx
mov eax, ebx
shr eax, 16
add ebx, eax
dec ebx
mov eax, ecx
shr eax, 16
add ecx, eax
dec ecx
push ecx
push ecx
mov eax, ecx
shr eax, 16
mov cx, ax
mcall SF_DRAW_LINE
pop ecx
mov eax, ecx
shl ecx, 16
mov cx, ax
mcall SF_DRAW_LINE
pop ecx
push ebx
mov eax, ebx
shr eax, 16
mov bx, ax
mcall SF_DRAW_LINE
pop ebx
mov eax, ebx
shl ebx, 16
mov bx, ax
mcall SF_DRAW_LINE
pop ecx ebx
ret
endp