diff --git a/programs/develop/libraries/fontRasterWorks(unicode)/RasterWorks.asm b/programs/develop/libraries/fontRasterWorks(unicode)/RasterWorks.asm new file mode 100644 index 000000000..2b8b43d43 --- /dev/null +++ b/programs/develop/libraries/fontRasterWorks(unicode)/RasterWorks.asm @@ -0,0 +1,655 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 — x3, maximum — 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'