; BGIFONT.INC v1.0 beta ; ; Written in pure assembler by Ivushkin Andrey aka Willow ; ; Created: December 16, 2004 ; ; Last changed: August 27, 2006 ; ; Compile with FASM ; BGI constants BGI_NODRAW equ 0x10000 BGI_ITALIC equ 0x20000 BGI_BOLD equ 0x40000 BGI_HALEFT equ 0x0 BGI_HARIGHT equ 0x1000 BGI_HACENTER equ 0x2000 BGI_VABOTTOM equ 0x0 BGI_VATOP equ 0x4000 BGI_VACENTER equ 0x8000 BGI_FREE equ 0x80000000 BGI_HAMASK equ 0x3000 BGI_VAMASK equ 0xc000 ; Freetext structure struc BGIfree FontName,XY,Angle,ScaleX,ScaleY,StrPtr,StrLen,Color,Align { dd FontName ;0 dd XY ;4 dd Angle ;8 dd ScaleX ;12 dd ScaleY ;16 dd StrPtr ;20 dd StrLen ;24 dd Color ;28 dd Align ;32 } macro BGIfont_GetID { call _BGIfont_GetID } macro BGIfont_Prepare { call _BGIfont_Prepare } macro BGIfont_Freetext { call _BGIfont_Freetext } macro BGIfont_Outtext { call _BGIfont_Outtext } macro _FI name,_size { db name if BGI_LEVEL eq KERNEL dw _size end if } BGIfont_get2head: shr ecx,28 ; font # sub ecx,4 jb .exit2 ; invalid # mov edi,[BGIfont_Ptr] inc edi cmp cl,[edi-1] jae .exit2 ; # too large jecxz .ex .fnext: mov edi,[edi+16] loop .fnext jmp .ex .exit2: xor edi,edi .ex: ret macro dps2 _str { if LOAD_MSG eq 1 dps _str end if } macro dph2 num,x,y { if BGI_LEVEL eq KERNEL pusha mov eax,0x00080100 mov ebx,num mov ecx,x shl 16+y mov edx,0xFF0000 call display_number popa end if } _BGIfont_GetID: ; in: edx-font name; ; out: eax-fontID, edi->BGIrec push ecx edi mov edi,[BGIfont_Ptr] movzx ecx,byte[edi] ; ecx-font count mov eax,ecx inc edi ; edi->FontName jecxz .ex .fnext: cmp edx,[edi] jne .floop sub eax,ecx add eax,4 shl eax,28 jmp .ex .floop: mov edi,[edi+16] loop .fnext .num0: xor eax,eax .ex: pop edi ecx ret _BGIfont_Prepare: ; in: edx-font name, edi->pointer to load fonts (fonts_count) ; out: eax-ID of new font loaded; eax=0 error cmp [BGIfont_Ptr],0 jne .already mov [BGIfont_Ptr],edi .already: pusha mov edi,[BGIfont_Ptr] movzx ecx,byte[edi] ; ecx-font count mov eax,ecx inc edi ; edi->FontName jecxz .fload .fnext: cmp edx,[edi] jne .loop sub eax,ecx inc eax jmp .cr_id .loop: mov edi,[edi+16] loop .fnext .fload: mov dword[.font],edx ; filename mov esi,edi ; esi->FontName mov [.dest],edi ; ptr to load font ; mov eax, 70 ; mov ebx, .fontattr ; mcall ; test eax, eax ; ;jnz .fail ; dps2 '1' ; mov eax, [.fileattr+32] ;mov [.fsize], litt_end-litt_file ;mov ebx,.fontinfo ;mov eax,70 ;mcall ; ebx - file size mov ebx, litt_end-litt_file mov edi, litt_file mov [.dest],litt_file ; ptr to load font cmp dword[edi],0x08084b50 ; 'PK',8,8 jne .fail dps2 '2' inc edi mov eax,26 ; #EOF mov ecx,253 cld repne scasb ; skip Copyright test ecx,ecx jz .fail dps2 '3' cmp edx,[edi+2] ; FontName jne .fail dps2 '4' movzx ecx,word[edi] ; HeaderSize sub ebx,ecx ; Filesize-Headersize movzx eax,word[edi+6] ; FontSize cmp eax,ebx jb .fail ; file truncated add ecx,[.dest] dps2 '5' cmp byte[ecx],'+' ; ParPrefix jne .fail ; font is valid, let's fill parameter table dps2 '>' mov [esi],edx ; FontName mov edx,eax add eax,ecx mov [esi+16],eax ; Font EOF movzx eax,word[ecx+5] add eax,ecx mov [esi+12],eax lea edi,[esi+4] ; edi->CharsCount lea esi,[ecx+1] ; esi->ParPrefix+1 xor eax,eax lodsw stosb ; CharsCount inc esi movsb ; FirstChar add esi,3 lodsw stosb ; UpperMargin movsb ; LowerMargin add esi,5 ; esi->offsets mov eax,[esi] push edi ; edi->Widths ; prepare moving data add edi,12 ; edi->offsets lea ecx,[edx-16] rep movsb pop edi ; edi->Widths mov [edi+8],esi ; EOF ; mov eax,[edi] movzx ecx,byte[edi-4] ; CharsCount lea eax,[edi+12+ecx*2] ; eax->widths stosd ; edi->FirstData add eax,ecx stosd ; edi->EOF mov eax,[esp] ; eax->fonts_count inc byte[eax] ; increase font counter movzx eax,byte[eax] .cr_id: add eax,0x3 ; create unique ID shl eax,28 ; to easy use in color(ecx) jmp .exit .fail: xor eax,eax .exit: mov [esp+28],eax popa ret .fontinfo: dd 0 dd 0 dd 0 .fsize dd 0 .dest dd 0 .fontfullname: db BGIFONT_PATH .font db 'LITT.CHR',0 .fontattr: dd 5 dd 0 dd 0 dd 0 dd .fileattr db 0 dd .fontfullname .fileattr rd 40/4 BGIfont_Coo: ; y->word[txt.y1], x->word[txt.x1] fild [txt.y1] ;y fmul st0,st0; y*y fild [txt.x1] ;x fmul st0,st0; x*x faddp ; x*x+y*y fsqrt ; sqrt, angle fild [txt.y1];y fabs fild [txt.x1] ; x fabs fpatan ; arctg(y/x) .skip: cmp [txt.x1],0 jge .xplus fchs fadd st0,st3 .xplus: cmp [txt.y1],0 jge .yplus fchs .yplus: fadd st0,st2 fsincos fmul st0,st2 fiadd [txt.x0] fistp [txt.x1] ; x=r*cos a fmulp ; y=r*sin a,angle fiadd [txt.y0] fistp [txt.y1] ret _BGIfont_Freetext: ; in: ebx-BGIfree structure ; out: eax-new drawing coords mov edx,[ebx] call _BGIfont_GetID test eax,eax jnz .fexists ret .fexists: pusha fninit fldpi fld [pi180] fimul dword[ebx+8] fst [BGIangle] mov esi,[ebx+28] and esi,0xffffff add esi,eax mov eax,[ebx+32] and [deform],0 test eax,BGI_ITALIC jz .norm mov [deform],dword 0.4 .norm: mov ebp,eax or ebp,BGI_FREE mov eax,[ebx+12] mov [Xscale],eax mov eax,[ebx+16] mov [Yscale],eax mov ecx,[ebx+20] mov edx,ebp and edx,BGI_FREE+BGI_VAMASK+BGI_HAMASK add edx,[ebx+24] mov eax,[ebx+4] mov ebx,esi add ebx,0x6000000 mov [esp+4],edx mov [esp+20],ecx jmp txt pi180 dd 0.017453 _BGIfont_Outtext: ; in: ebx-[x][y], ecx-color, edx-string, esi-length pusha mov ebp,esi if ~ BGI_LEVEL eq KERNEL mov eax,ebx mov ebx,ecx mov ecx,edx mov edx,esi end if ; in: eax-[x][y], ebx-color, ecx-string, edx-length txt: if ~ BGI_LEVEL eq KERNEL if BGI_WINDOW_CLIP eq 1 pusha mov eax,9 mov ebx,BGI_PRC_INFO mov ecx,-1 mcall popa end if end if mov [.y0],ax shr eax,16 mov [.x0],ax mov ecx,ebx ; color and ebx,0xfffffff mov [.color],ebx call BGIfont_get2head test edi,edi jz .exit mov ecx,[esp+4]; str length mov esi,[esp+20]; str ptr movzx eax,byte[edi+5] push ecx and ecx,0xff jnz .lenok add esp,4 jmp .ex2 .lenok: pusha push dword[txt.y0] and dword[txt.y0],0 xor edx,edx mov ebx,[edi+8] .next: call txt.BGIfont_GetChar movzx eax,byte[ebx+eax] add edx,eax loop .next mov ecx,edx ; ecx - x size movzx dx,byte[edi+6] mov [BGIheight],dx mov ebx,[esp+36] and ebx,BGI_HAMASK cmp ebx,BGI_HARIGHT je .nova ja .subv xor ecx,ecx jmp .nova .subv: shr cx,1 .nova: mov ebx,[esp+36] and ebx,BGI_VAMASK cmp ebx,BGI_VATOP je .def ja .subh xor edx,edx jmp .def .subh: shr dx,1 .def: call txt.BGIfont_Deform pop dword[txt.y0] popa pop ebx mov ax,[txt.y1] sub [txt.y0],ax mov ax,[txt.x1] sub [txt.x0],ax xor eax,eax cld .mloop: push [.y0] pop [.y] push [.x0] pop [.x] call .BGIfont_GetChar push esi lea esi,[edi+20] ; offset movzx edx,word[esi+eax*2] ; ofs1 add edx,[edi+12] inc eax cmp al,[edi+4] je .eof movzx eax,word[esi+eax*2]; ofs2 add eax,[edi+12] jmp .prc_vec .eof: mov eax,[edi+16] ; ofs2=eof .prc_vec: ; edx-vec cmd ifs, eax-cmd limit mov [.vec_end],eax push ecx .vec_loop: mov ax,word[edx] push edx mov ecx,eax and eax,0x8080 ; op and ecx,0x7f ; xx mov edx,[edx+1] and edx,0x7f ; yy cmp edx,63 jbe .positive sub edx,128 ; yy-=128 .positive: cmp ecx,63 jbe .positive2 sub ecx,128 ; xx-=128 .positive2: call .BGIfont_Deform cmp eax,0x8080 jne .noline test ebp,BGI_NODRAW jnz .noline ; draw vector if ~ BGI_LEVEL eq KERNEL push eax mov ebx,dword[.x1] mov ecx,dword[.y1] if BGI_WINDOW_CLIP eq 1 movzx eax,[.x] cmp eax,dword[BGI_PRC_INFO+42] ja .nobold movzx eax,[.y] cmp eax,dword[BGI_PRC_INFO+46] ja .nobold xor eax,eax cmp ax,bx jg .nobold cmp ax,cx jg .nobold end if mov edx,[.color] ; \begin{diamond}[18.08.2006] ; starting from K0530 kernel interprets flag 0x1000000 as ; negate existing pixels colors, disregarding passed color ; we do not want this and edx, 0xFFFFFF ; \end{diamond}[18.08.2006] mov eax,38 mcall test ebp,BGI_BOLD jz .nobold test ebp,BGI_FREE jnz .free5 .free5: add ebx,1 shl 16+1 mcall .nobold: pop eax else pusha mov eax,dword[.x1] mov ebx,dword[.y1] mov ecx,[.color] ; call syscall_drawline test dword[esp+8],BGI_BOLD jz .nobold add eax,1 shl 16+1 ; call syscall_drawline .nobold: popa end if .noline: pop edx test eax,eax je .eovecs ; op=0 push [.y1] pop [.y] push [.x1] pop [.x] add edx,2 cmp edx,[.vec_end] jb .vec_loop .eovecs: pop ecx esi push [.y] pop [.y0] push [.x] pop [.x0] loop .mloop1 jmp .exit .mloop1: jmp .mloop .exit: mov eax,dword[.y0] mov [esp+28],eax .ex2: popa ret .BGIfont_Deform: test ebp,BGI_FREE jnz .free0 movzx ebx,byte[.color+3] ;ebx=scale imul ecx,ebx add ecx,2 shr ecx,2 imul edx,ebx add edx,2 shr edx,2 neg edx mov [.x1],cx mov [.y1],dx jmp .add .free0: mov [.x1],cx mov [.y1],dx fild [.y1] fld st0 fmul [Yscale] fchs fistp [.y1] fmul [deform] fiadd [.x1] fmul [Xscale] fistp [.x1] cmp [BGIangle],0 je .add call BGIfont_Coo jmp .eax .add: mov cx,[.x0] add [.x1],cx mov cx,[.y0] add [.y1],cx .eax: ret .BGIfont_GetChar: ; in: esi -> string; edi -> BGIrec ; out: esi -> next char; al - char obtained lodsb ; al - char from str sub al,[edi+5] jb .out cmp al,[edi+4] jb .in .out: xor al,al ; al - 1st symbol available .in: ret .y0 dw ? .x0 dw ? .x1 dw ? .x dw ? .y1 dw ? .y dw ? .color dd ? .vec_end dd ? BGIfont_Ptr dd 0 BGIheight dw ? deform dd ? BGIangle dd ? Xscale dd ? Yscale dd ?