kolibrios-fun/programs/develop/libraries/fontRasterWorks(unicode)/RasterWorks.asm

656 lines
9.6 KiB
NASM
Raw Normal View History

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2016. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
format MS COFF
public @EXPORT as 'EXPORTS'
include '../../../macros.inc'
include '../../../proc32.inc'
; calculate string width in pixels
proc stringWidth, charQuantity, charHeight
mov eax,[charHeight]
shr eax,1
mul [charQuantity]
ret
endp
; calculate amount of chars that fits given width
proc charsFit, areaWidth, charHeight
shr [charHeight],1
mov eax,[areaWidth]
xor edx,edx
div [charHeight]
ret
endp
; calculate amount of valid chars in UTF-8 string
; supports zero terminated string (set byteQuantity = -1)
proc countUTF8, string, byteQuantity
push esi
mov edx,[byteQuantity]
inc edx
xor ecx,ecx
dec ecx
mov esi,[string]
@@:
inc ecx
dec edx
jz .done
lodsb
test al,al
jz .done
jns @b
dec ecx
shl al,1
jns @b
.next:
mov ah,[esi]
test ah,ah
jns @b
shl ah,1
js @b
inc esi
dec edx
jz @f
shl al,1
js .next
inc ecx
jmp @b
@@:
inc ecx
.done:
mov eax,ecx
pop esi
ret
endp
; draw text on 24bpp or 32bpp image
; autofits text between 'x' and 'xSize'
proc drawText, canvas, x, y, string, charQuantity, fontColor, params
; [canvas]:
; xSize dd ?
; ySize dd ?
; picture rb xSize * ySize * bpp
; fontColor dd AARRGGBB
; AA = alpha channel ; 0 = transparent, FF = non transparent
; params dd ffeewwhh
; hh = char height
; ww = char width ; 0 = auto (proportional)
; ee = encoding ; 1 = cp866, 2 = UTF-16LE, 3 = UTF-8
; ff = flags ; 0001 = bold, 0010 = italic
; 0100 = underline, 1000 = strike-through
; 00010000 = align right, 00100000 = align center
; 01000000 = set text area between higher and lower halfs of 'x'
; 10000000 = 32bpp canvas insted of 24bpp
; all flags combinable, except align right + align center
; returns: eax = char width (0 = error), ecx = text start X
pusha
movzx eax,byte[params+1]
test eax,eax
jnz @f
mov al ,byte[params]
shr al ,1
mov byte[params+1],al
@@:
cmp al, 22
jc @f
mov al, 21
mov byte[params+1],21
@@:
inc [charQuantity]
mul [charQuantity]
mov ebx,eax
mov esi,[canvas]
mov esi,[esi]
test byte[params+3],64
jz .fit
movzx eax,word[x]
movzx ecx,word[x+2]
cmp eax,ecx
jnc @f
xchg eax,ecx
@@:
mov [x],ecx
cmp esi,eax
jc .fit
mov esi,eax
.fit:
mov eax,esi
sub eax,[x]
jnc @f
popa
xor eax,eax
jmp .exit
@@:
cmp eax,ebx
jnc @f
mov ebx,eax
div [charQuantity]
mov byte[params+1],al
sub ebx,edx
@@:
mov eax,esi
sub eax,ebx
test byte[params+3],32
jz @f
sub eax,[x]
shr eax,1
add [x],eax
jmp .ok
@@:
test byte[params+3],16
jz .ok
mov [x],eax
.ok:
movzx eax,byte[params+1]
lea eax,[eax*2+eax]
shr eax,3
test byte[params+1],7
jz @f
inc eax
@@:
mov ecx,eax
push eax
shl eax,3
mul [charQuantity]
shl ecx,4
push ecx
push eax
mul ecx
push eax
lea ecx,[eax*4+8]
mcall 68,12
pop ecx
popd [eax]
popd [eax+4]
push eax
lea edi,[eax+8]
xor eax,eax
rep stosd
pop edi
pop ecx
shl ecx,4
mov ch, byte[params+2]
shl ecx,22
shr ecx,2
dec ecx
bts ecx,27
mov esi,[charQuantity]
dec esi
xor ebx,ebx
mcall 4,,,[string]
xor eax,eax
mov ebx,[edi]
mov ecx,[edi+4]
push edi
add edi,8
test byte[params+3],1
jnz .bold
movzx esi,byte[params]
@@:
pusha
call verSub
popa
sub esi,16
jg @b
jmp @f
.bold:
imul ecx,ebx
dec eax
movzx ebx,byte[params+1]
.loop:
push edi
push ecx
call horAdd
pop ecx
pop edi
sub ebx,8
jg .loop
@@:
test byte[params+3],2
jz @f
mov edi,[esp]
mov ecx,[edi]
mov ebx,[edi+4]
add edi,8
mov esi,edi
call italic
@@:
mov edi,[esp]
mov eax,[edi]
mov ebx,[edi+4]
add edi,8
mov esi,edi
movzx edx,byte[params]
call verScale
mov eax,[charQuantity]
mul byte[params+1]
mov esi,[esp]
mov edx,[esi]
add esi,8
mov edi,esi
mov ebx,eax
push eax
movzx eax,byte[params]
call ClearType
test byte[params+3],4
jz @f
movzx eax,byte[params]
movzx esi,byte[params+1]
mov ebx,eax
dec eax
call drawLine
@@:
test byte[params+3],8
jz @f
movzx eax,byte[params]
movzx esi,byte[params+1]
mov ebx,eax
shr eax,1
call drawLine
@@:
mov esi,[canvas]
mov eax,[esi]
mul [y]
add eax,[x]
mov edi,eax
mov eax,[esi]
pop ecx
sub eax,ecx
mov ebx,[fontColor]
movzx edx,byte[params]
test byte[params+3],128
mov ebp,3
jnz @f
lea edi,[edi*2+edi+8]
lea eax,[eax*2+eax]
jmp .go
@@:
lea edi,[edi*4+8]
shl eax,2
inc ebp
.go:
add edi,esi
mov esi,[esp]
add esi,8
call putOnPicture
pop ecx
mcall 68,13
popa
movzx eax,byte[params+1]
mov ecx,[x]
.exit:
ret
endp
drawLine:
mov ecx,[esp+4]
lea ecx,[ecx*2+ecx]
mul ecx
lea esi,[esi*2+esi]
sub ecx,esi
add esi,ecx
add esi,ecx
shr ecx,2
add eax,[esp+8]
lea edi,[eax+8]
mov eax,-1
@@:
push ecx
rep stosd
sub edi,esi
pop ecx
sub ebx,16
jg @b
ret
; make horizontal lines thinner
; one color background only
verSub:
; edi -> buffer (32bpp)
; eax = background color
; ebx = width
; ecx = height
push ebp
mov edx,ebx
mov esi,edi
mov ebp,ecx
shl ebx,2
.start:
cmp [edi],eax
jnz @f
.loop:
add edi,ebx
dec ecx
jnz .start
jmp .next
@@:
mov [edi],eax
@@:
add edi,ebx
dec ecx
jz .next
cmp [edi],eax
jnz @b
jmp .loop
.next:
add esi,4
mov edi,esi
mov ecx,ebp
dec edx
jnz .start
pop ebp
ret
; make vertical lines thicker
horAdd:
; edi -> buffer (32bpp)
; eax = font color
; ecx = total number of pixels
repnz scasd
jcxz .end
repz scasd
mov [edi-4],eax
jmp horAdd
.end:
ret
; esi=edi supported (32bpp)
italic:
; esi -> source buffer
; edi -> result buffer
; ebx = height
; ecx = width
shl ecx,2
shr ebx,2
mov eax,ecx
mul ebx
shl eax,2
add esi,eax
add edi,eax
dec ecx
sub esi,8
sub edi,4
push ebx
std
@@:
push ecx
rep movsd
pop ecx
sub esi,4
dec ebx
jnz @b
pop ecx
mov eax,[edi+4]
rep stosd
cld
ret
; vertical downscale
; white-black-gray only
; esi=edi supported (32bpp)
verScale:
; esi -> source buffer
; edi -> result buffer
; eax = width
; ebx = source height
; edx = result height
push ebp
dec eax
shl eax,2
push eax
add eax,4
push edx
push esi
push edi
push eax
mov ecx,edx
.scale:
mov al, [esi]
add esi,[esp]
mul cl
neg ecx
add ecx,ebx
mov ebp,eax
mov al, [esi]
@@:
cmp edx,ecx
jnc @f
add esi,[esp]
mul dl
sub ecx,edx
add ebp,eax
mov al, [esi]
jmp @b
@@:
mul cl
add eax,ebp
div bl
mov [edi],al
mov [edi+1],al
mov [edi+2],al
add edi,[esp]
neg ecx
add ecx,edx
jnz @f
add ecx,edx
add esi,[esp]
@@:
dec dword[esp+12]
jnz .scale
mov edi,[esp+4]
mov esi,[esp+8]
mov [esp+12],edx
add edi,[esp+16]
add esi,[esp+16]
sub dword[esp+16],4
jnc .scale
add esp,20
pop ebp
ret
; horizontal downscale
; minimum <20> x3, maximum <20> x6
; white-black-gray only
; esi=edi supported
ClearType:
; esi -> source buffer (32bpp)
; edi -> result buffer (24bpp)
; eax = height
; edx = source width
; ebx = result width
push ebp
lea ebx,[ebx*2+ebx]
imul eax,ebx
push eax
push edi
push eax
push edx
mov ecx,ebx
.scale:
movzx eax,byte[esi]
add esi,4
mul ecx
neg ecx
add ecx,[esp]
mov ebp,eax
movzx eax,byte[esi]
cmp ebx,ecx
jnc @f
add esi,4
mul ebx
sub ecx,ebx
add ebp,eax
movzx eax,byte[esi]
@@:
mul ecx
add eax,ebp
div dword[esp]
stosb
neg ecx
add ecx,ebx
jnz @f
add ecx,ebx
add esi,4
@@:
dec dword[esp+4]
jnz .scale
pop edi
pop edi
mov edi,[esp]
mov ecx,[esp+4]
movzx ebx,byte[edi]
xor eax,eax
dec ecx
.degradation:
mov al, [edi]
shl eax,1
lea eax,[eax*2+eax]
lea edx,[ebx*4+ebx]
mov bl, [edi+1]
add eax,edx
lea edx,[ebx*4+ebx]
mov bl, [edi]
add eax,edx
shr eax,4
stosb
dec ecx
jnz .degradation
pop edi
pop ecx
.colRev:
mov al,[edi]
xchg al,[edi+2]
mov [edi],al
add edi,3
sub ecx,3
jnz .colRev
pop ebp
ret
; apply color on font, put font on picture
; white font on black background only, smoothing allowed
putOnPicture:
; esi -> font buffer (24bpp)
; edi -> picture buffer
; ebx = font color
; ecx = width
; edx = height
; eax = picture buffer line gap in bytes
; ebp = picture buffer bytes per pixel
push edx
push eax
push ecx
push ebp
xor eax,eax
rol ebx,8
mov ebp,ecx
.start:
cmp byte[esi], 0
jz @f
mov al, [esi]
mul bl
mov al, ah
shr ah, 7
add al, ah
mov cl, 255
sub cl, al
mul bh
mov edx,eax
mov al, [edi]
mul cl
add eax,edx
mov al, ah
shr ah, 7
add al, ah
mov [edi],al
@@:
cmp byte[esi+1], 0
jz @f
mov al, [esi+1]
mul bl
mov al, ah
shr ah, 7
add al, ah
mov cl, 255
sub cl, al
rol ebx,16
mul bl
rol ebx,16
mov edx,eax
mov al, [edi+1]
mul cl
add eax,edx
mov al, ah
shr ah, 7
add al, ah
mov [edi+1],al
@@:
cmp byte[esi+2], 0
jz @f
mov al, [esi+2]
mul bl
mov al, ah
shr ah, 7
add al, ah
mov cl, 255
sub cl, al
rol ebx,16
mul bh
rol ebx,16
mov edx,eax
mov al, [edi+2]
mul cl
add eax,edx
mov al, ah
shr ah, 7
add al, ah
mov [edi+2],al
@@:
add esi,3
add edi,[esp]
dec ebp
jnz .start
mov ebp,[esp+4]
add edi,[esp+8]
dec dword[esp+12]
jnz .start
add esp,16
ret
align 4
@EXPORT:
export drawText, 'drawText', \
countUTF8, 'cntUTF-8', \
charsFit, 'charsFit', \
stringWidth, 'strWidth'