Subversion Repositories Kolibri OS

Rev

Rev 131 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ; BGIFONT.INC v1.0 beta
  2. ;
  3. ; Written in pure assembler by Ivushkin Andrey aka Willow
  4. ;
  5. ; Created: December 16, 2004
  6. ;
  7. ; Last changed: August 27, 2006
  8. ;
  9. ; Compile with FASM
  10.  
  11. ; BGI constants
  12. BGI_NODRAW   equ 0x10000
  13. BGI_ITALIC   equ 0x20000
  14. BGI_BOLD     equ 0x40000
  15. BGI_HALEFT   equ 0x0
  16. BGI_HARIGHT  equ 0x1000
  17. BGI_HACENTER equ 0x2000
  18. BGI_VABOTTOM equ 0x0
  19. BGI_VATOP    equ 0x4000
  20. BGI_VACENTER equ 0x8000
  21.  
  22. BGI_FREE     equ 0x80000000
  23. BGI_HAMASK   equ 0x3000
  24. BGI_VAMASK   equ 0xc000
  25.  
  26. ; Freetext structure
  27. struc BGIfree FontName,XY,Angle,ScaleX,ScaleY,StrPtr,StrLen,Color,Align
  28. {
  29.     dd FontName ;0
  30.     dd XY           ;4
  31.     dd Angle    ;8
  32.     dd ScaleX   ;12
  33.     dd ScaleY   ;16
  34.     dd StrPtr   ;20
  35.     dd StrLen   ;24
  36.     dd Color    ;28
  37.     dd Align    ;32
  38. }
  39.  
  40. ; font options structure
  41. struc BGIrec FontName,CharsCount,FirstChar,UpperMargin,LowerMargin,\
  42.     Widths,FirstData,EOF,font_data
  43. {
  44.  .FontName     dd ?  ; 0
  45.  .CharsCount   db ?  ; 4
  46.  .FirstChar    db ?  ; 5
  47.  .UpperMargin  db ?  ; 6
  48.  .LowerMargin  db ?  ; 7
  49.  .Widths       dd ?  ; 8
  50.  .FirstData    dd ?  ; 12
  51.  .EOF          dd ?    ; 16
  52.  .font_data    dd ?  ; 20 follows (Offsets)
  53. }
  54.  
  55. macro BGIfont_GetID
  56. {
  57.     call _BGIfont_GetID
  58. }
  59.  
  60. macro BGIfont_Prepare
  61. {
  62.     call _BGIfont_Prepare
  63. }
  64.  
  65. macro BGIfont_Freetext
  66. {
  67.     call _BGIfont_Freetext
  68. }
  69.  
  70. macro BGIfont_Outtext
  71. {
  72.     call _BGIfont_Outtext
  73. }
  74.  
  75. macro _FI name,_size
  76. {
  77.     db name
  78. if BGI_LEVEL eq KERNEL
  79.     dw _size
  80. end if
  81. }
  82.  
  83. BGIfont_names:
  84. _FI 'LCOM',11485   ;7
  85. _FI 'EURO',8117    ;5
  86. _FI 'GOTH',13816   ;6
  87. _FI 'LITT',3596    ;8
  88. _FI 'TRIP',11932   ;14
  89. _FI 'SCRI',8490    ;11
  90. _FI 'SMAL',4162    ;13
  91. _FI 'TSCR',12134   ;15
  92. _FI 'SANS',8453    ;10
  93. _FI 'SIMP',9522    ;12
  94. BGIfont_names_end:
  95.  
  96. macro BGIfont_Init
  97. {
  98. ; in:  ecx - number of fonts to load;
  99. ;      esi-> _FI structure
  100. ;      edi-> where to load
  101.     push edi
  102. if  BGI_LEVEL eq KERNEL
  103.     mov  edi,0x40000
  104. end if
  105.   .nfont:
  106.     mov  edx,[esi]
  107. if  BGI_LEVEL eq KERNEL
  108.     movzx ebx,word[esi+4]
  109.     mov  [BGIfont_Prepare.okflag],'N'
  110. end if
  111.     call _BGIfont_Prepare
  112. if ~ BGI_LEVEL eq KERNEL
  113.     add  esi,4
  114. else
  115.     push esi
  116.     test eax,eax
  117.     jz   .fail
  118.     mov  [BGIfont_Prepare.okflag],'*'
  119.   .fail:
  120.     mov  esi,BGIfont_Prepare.font
  121.     call boot_log
  122.     pop  esi
  123.     add  esi,6
  124. end if
  125.     loop .nfont
  126.     dph2 _BGI_BOLD,300,550
  127. ;    movzx edi,byte[0x40000]
  128.     pop  edi
  129. }
  130.  
  131. BGIfont_get2head:
  132.     shr  ecx,28 ; font #
  133.     sub  ecx,4
  134.     jb   .exit2 ; invalid #
  135.     mov  edi,[BGIfont_Ptr]
  136.     inc  edi
  137.     cmp  cl,[edi-1]
  138.     jae  .exit2 ; # too large
  139.     jecxz .ex
  140.   .fnext:
  141.     mov  edi,[edi+16]
  142.     loop .fnext
  143.     jmp  .ex
  144.   .exit2:
  145.     xor  edi,edi
  146.   .ex:
  147.     ret
  148.  
  149. BGIfont_GetName:
  150. ; in: ecx-fontID;
  151. ; out: edx-font name.
  152.     call BGIfont_get2head
  153.     xor  edx,edx
  154.     test edi,edi
  155.     jz   .ex
  156.     mov  edx,[edi]
  157.   .ex:
  158.     ret
  159.  
  160. macro dps2 _str
  161. {
  162. if ~ BGI_LEVEL eq KERNEL
  163.   if LOAD_MSG eq 1
  164.     dps _str
  165.   end if
  166. else
  167.     pusha
  168.     mov  esi,BGIfont_Prepare.okflag
  169.     mov  byte[esi], _str
  170.     call boot_log
  171.     popa
  172. end if
  173. }
  174.  
  175. macro dph2 num,x,y
  176. {
  177. if  BGI_LEVEL eq KERNEL
  178.     pusha
  179.     mov  eax,0x00080100
  180.     mov  ebx,num
  181.     mov  ecx,x shl 16+y
  182.     mov  edx,0xFF0000
  183.     call display_number
  184.     popa
  185. end if
  186. }
  187.  
  188. _BGIfont_GetID:
  189. ; in:  edx-font name;
  190. ; out: eax-fontID, edi->BGIrec
  191.     push ecx edi
  192.     mov  edi,[BGIfont_Ptr]
  193.     movzx ecx,byte[edi] ; ecx-font count
  194.     mov  eax,ecx
  195.     inc  edi ; edi->FontName
  196.     jecxz .ex
  197.   .fnext:
  198.     cmp  edx,[edi]
  199.     jne  .floop
  200.     sub  eax,ecx
  201.     add  eax,4
  202.     shl  eax,28
  203.     jmp  .ex
  204.   .floop:
  205.     mov  edi,[edi+16]
  206.     loop .fnext
  207.   .num0:
  208.     xor  eax,eax
  209.   .ex:
  210.     pop  edi ecx
  211.     ret
  212.  
  213. _BGIfont_Prepare:
  214. ; in:  edx-font name, edi->pointer to load fonts (fonts_count)
  215. ; out: eax-ID of new font loaded; eax=0 error
  216.     cmp  [BGIfont_Ptr],0
  217.     jne  .already
  218.     mov  [BGIfont_Ptr],edi
  219.   .already:
  220.     pusha
  221.     mov  edi,[BGIfont_Ptr]
  222.     movzx ecx,byte[edi] ; ecx-font count
  223.     mov  eax,ecx
  224.     inc  edi ; edi->FontName
  225.     jecxz .fload
  226.   .fnext:
  227.     cmp  edx,[edi]
  228.     jne  .loop
  229.     sub  eax,ecx
  230.     inc  eax
  231.     jmp  .cr_id
  232.   .loop:
  233.     mov  edi,[edi+16]
  234.     loop .fnext
  235.   .fload:
  236.     mov  dword[.font],edx ; filename
  237.     mov  esi,edi     ; esi->FontName
  238.     mov  [.dest],edi ; ptr to load font
  239. if ~ BGI_LEVEL eq KERNEL
  240.         mov     eax, 70
  241.         mov     ebx, .fontattr
  242.         int     0x40
  243.         test    eax, eax
  244.         jnz     .fail
  245.         dps2    '1'
  246.         mov     eax, [.fileattr+32]
  247.         mov     [.fsize], eax
  248.     mov  ebx,.fontinfo
  249.     mov  eax,70
  250.     int  0x40        ; ebx - file size
  251. else
  252.     push edi esi edx
  253.     mov  eax,.font
  254.     xor  ebx,ebx
  255.     mov  esi,12
  256.     mov  ecx,ebx
  257.     mov  edx,edi
  258.     call fileread
  259.     pop  edx esi edi
  260.     mov  ebp,edi
  261.     add  ebp,ebx
  262.     cmp  ebp,0x50000
  263.     ja   .fail
  264. end if
  265.     cmp  dword[edi],0x08084b50 ; 'PK',8,8
  266.     jne  .fail
  267.     dps2 '2'
  268.     inc  edi
  269.     mov  eax,26 ; #EOF
  270.     mov  ecx,253
  271.     cld
  272.     repne scasb  ; skip Copyright
  273.     test ecx,ecx
  274.     jz   .fail
  275.     dps2  '3'
  276.     cmp  edx,[edi+2] ; FontName
  277.     jne  .fail
  278.     dps2  '4'
  279.     movzx ecx,word[edi] ; HeaderSize
  280.     sub  ebx,ecx  ; Filesize-Headersize
  281.     movzx eax,word[edi+6] ; FontSize
  282.     cmp  eax,ebx
  283.     jb   .fail    ; file truncated
  284.     add  ecx,[.dest]
  285.     dps2  '5'
  286.     cmp  byte[ecx],'+'  ; ParPrefix
  287.     jne  .fail
  288. ; font is valid, let's fill parameter table
  289.     dps2  '>'
  290.     mov  [esi],edx ; FontName
  291.     mov  edx,eax
  292.     add  eax,ecx
  293.     mov  [esi+16],eax ; Font EOF
  294.     movzx eax,word[ecx+5]
  295.     add  eax,ecx
  296.     mov  [esi+12],eax
  297.     lea  edi,[esi+4]  ; edi->CharsCount
  298.     lea  esi,[ecx+1] ; esi->ParPrefix+1
  299.     xor  eax,eax
  300.     lodsw
  301.     stosb  ; CharsCount
  302.     inc  esi
  303.     movsb  ; FirstChar
  304.     add  esi,3
  305.     lodsw
  306.     stosb  ; UpperMargin
  307.     movsb  ; LowerMargin
  308.     add  esi,5 ; esi->offsets
  309.     mov  eax,[esi]
  310.     push edi ; edi->Widths
  311. ; prepare moving data
  312.     add  edi,12 ; edi->offsets
  313.     lea  ecx,[edx-16]
  314.     rep  movsb
  315.     pop  edi ; edi->Widths
  316.     mov  [edi+8],esi ; EOF
  317. ;    mov  eax,[edi]
  318.     movzx ecx,byte[edi-4] ; CharsCount
  319.     lea  eax,[edi+12+ecx*2] ; eax->widths
  320.     stosd  ; edi->FirstData
  321.     add  eax,ecx
  322.     stosd  ; edi->EOF
  323.     mov  eax,[esp] ; eax->fonts_count
  324.     inc  byte[eax] ; increase font counter
  325.     movzx eax,byte[eax]
  326.   .cr_id:
  327.     add  eax,0x3   ; create unique ID
  328.     shl  eax,28    ; to easy use in color(ecx)
  329.     jmp  .exit
  330.   .fail:
  331.     xor  eax,eax
  332.   .exit:
  333.     mov  [esp+28],eax
  334.     popa
  335.     ret
  336.  
  337. if ~ BGI_LEVEL eq KERNEL
  338. .fontinfo:
  339.         dd 0
  340.         dd 0
  341.         dd 0
  342. .fsize  dd 0
  343. .dest   dd 0
  344. .fontfullname:
  345.         db BGIFONT_PATH
  346. .font   db 'FONT.CHR',0
  347.  
  348. .fontattr:
  349.         dd      5
  350.         dd      0
  351.         dd      0
  352.         dd      0
  353.         dd      .fileattr
  354.         db      0
  355.         dd      .fontfullname
  356. .fileattr rd 40/4
  357. else
  358.   .dest   dd 0
  359.   .font   db 'FONT    CHR'
  360.   .okflag db ' ',0
  361. end if
  362.  
  363. BGIfont_Coo:
  364. ; y->word[txt.y1], x->word[txt.x1]
  365.     fild [txt.y1] ;y
  366.     fmul st0,st0; y*y
  367.     fild [txt.x1] ;x
  368.     fmul st0,st0; x*x
  369.     faddp  ; x*x+y*y
  370.     fsqrt  ; sqrt, angle
  371.     fild [txt.y1];y
  372.     fabs
  373.     fild [txt.x1] ; x
  374.     fabs
  375.     fpatan ; arctg(y/x)
  376.   .skip:
  377.     cmp  [txt.x1],0
  378.     jge  .xplus
  379.     fchs
  380.     fadd st0,st3
  381.   .xplus:
  382.     cmp  [txt.y1],0
  383.     jge  .yplus
  384.     fchs
  385.   .yplus:
  386.     fadd st0,st2
  387.     fsincos
  388.     fmul st0,st2
  389.     fiadd [txt.x0]
  390.     fistp [txt.x1] ; x=r*cos a
  391.     fmulp ; y=r*sin a,angle
  392.     fiadd [txt.y0]
  393.     fistp [txt.y1]
  394.     ret
  395.  
  396. _BGIfont_Freetext:
  397. ; in: ebx-BGIfree structure
  398. ; out: eax-new drawing coords
  399.     mov  edx,[ebx]
  400.     call _BGIfont_GetID
  401.     test eax,eax
  402.     jnz  .fexists
  403.     ret
  404.   .fexists:
  405.     pusha
  406.     fninit
  407.     fldpi
  408.     fld  [pi180]
  409.     fimul dword[ebx+8]
  410.     fst  [BGIangle]
  411.     mov  esi,[ebx+28]
  412.     and  esi,0xffffff
  413.     add  esi,eax
  414.     mov  eax,[ebx+32]
  415.     and  [deform],0
  416.     test eax,BGI_ITALIC
  417.     jz   .norm
  418.     mov  [deform],0.4
  419.   .norm:
  420.     mov  ebp,eax
  421.     or    ebp,BGI_FREE
  422.     mov  eax,[ebx+12]
  423.     mov  [Xscale],eax
  424.     mov  eax,[ebx+16]
  425.     mov  [Yscale],eax
  426.     mov  ecx,[ebx+20]
  427.     mov  edx,ebp
  428.     and  edx,BGI_FREE+BGI_VAMASK+BGI_HAMASK
  429.     add  edx,[ebx+24]
  430.     mov  eax,[ebx+4]
  431.     mov  ebx,esi
  432.     add  ebx,0x6000000
  433.     mov  [esp+4],edx
  434.     mov  [esp+20],ecx
  435.     jmp  txt
  436.  
  437.     pi180 dd 0.017453
  438.  
  439. _BGIfont_Outtext:
  440. ; in: ebx-[x][y], ecx-color, edx-string, esi-length
  441.     pusha
  442.     mov  ebp,esi
  443. if ~ BGI_LEVEL eq KERNEL
  444.     mov  eax,ebx
  445.     mov  ebx,ecx
  446.     mov  ecx,edx
  447.     mov  edx,esi
  448. end if
  449. ; in: eax-[x][y], ebx-color, ecx-string, edx-length
  450. txt:
  451. if  ~ BGI_LEVEL eq KERNEL
  452.   if  BGI_WINDOW_CLIP eq 1
  453.     pusha
  454.     mov  eax,9
  455.     mov  ebx,BGI_PRC_INFO
  456.     mov  ecx,-1
  457.     int  0x40
  458.     popa
  459.   end if
  460. end if
  461.     mov  [.y0],ax
  462.     shr  eax,16
  463.     mov  [.x0],ax
  464.     mov  ecx,ebx ; color
  465.     and  ebx,0xfffffff
  466.     mov  [.color],ebx
  467.     call BGIfont_get2head
  468.     test edi,edi
  469.     jz   .exit
  470.     mov  ecx,[esp+4]; str length
  471.     mov  esi,[esp+20]; str ptr
  472.     movzx eax,byte[edi+5]
  473.     push ecx
  474.     and  ecx,0xff
  475.     jnz  .lenok
  476.     add  esp,4
  477.     jmp  .ex2
  478.   .lenok:
  479.     pusha
  480.     push dword[txt.y0]
  481.     and  dword[txt.y0],0
  482.     xor  edx,edx
  483.     mov  ebx,[edi+8]
  484.    .next:
  485.     call txt.BGIfont_GetChar
  486.     movzx eax,byte[ebx+eax]
  487.     add  edx,eax
  488.     loop .next
  489.     mov  ecx,edx ; ecx - x size
  490.     movzx dx,byte[edi+6]
  491.     mov  [BGIheight],dx
  492.     mov  ebx,[esp+36]
  493.     and  ebx,BGI_HAMASK
  494.     cmp  ebx,BGI_HARIGHT
  495.     je   .nova
  496.     ja   .subv
  497.     xor  ecx,ecx
  498.     jmp  .nova
  499.   .subv:
  500.     shr  cx,1
  501.   .nova:
  502.     mov  ebx,[esp+36]
  503.     and  ebx,BGI_VAMASK
  504.     cmp  ebx,BGI_VATOP
  505.     je   .def
  506.     ja   .subh
  507.     xor  edx,edx
  508.     jmp  .def
  509.   .subh:
  510.     shr  dx,1
  511.   .def:
  512.     call txt.BGIfont_Deform
  513.     pop  dword[txt.y0]
  514.     popa
  515.     pop  ebx
  516.     mov  ax,[txt.y1]
  517.     sub  [txt.y0],ax
  518.     mov  ax,[txt.x1]
  519.     sub  [txt.x0],ax
  520.     xor  eax,eax
  521.     cld
  522. .mloop:
  523.     push [.y0]
  524.     pop  [.y]
  525.     push [.x0]
  526.     pop  [.x]
  527.     call .BGIfont_GetChar
  528.     push esi
  529.     lea  esi,[edi+20] ; offset
  530.     movzx edx,word[esi+eax*2] ; ofs1
  531.     add  edx,[edi+12]
  532.     inc  eax
  533.     cmp  al,[edi+4]
  534.     je   .eof
  535.     movzx eax,word[esi+eax*2]; ofs2
  536.     add   eax,[edi+12]
  537.     jmp   .prc_vec
  538.   .eof:
  539.     mov  eax,[edi+16] ; ofs2=eof
  540.   .prc_vec:  ; edx-vec cmd ifs, eax-cmd limit
  541.     mov  [.vec_end],eax
  542.     push ecx
  543.   .vec_loop:
  544.     mov  ax,word[edx]
  545.     push edx
  546.     mov  ecx,eax
  547.     and  eax,0x8080 ; op
  548.     and  ecx,0x7f ; xx
  549.     mov  edx,[edx+1]
  550.     and  edx,0x7f ; yy
  551.     cmp  edx,63
  552.     jbe  .positive
  553.     sub  edx,128  ; yy-=128
  554.   .positive:
  555.     cmp  ecx,63
  556.     jbe  .positive2
  557.     sub  ecx,128  ; xx-=128
  558.   .positive2:
  559.     call .BGIfont_Deform
  560.     cmp  eax,0x8080
  561.     jne  .noline
  562.     test ebp,BGI_NODRAW
  563.     jnz  .noline
  564. ; draw vector
  565. if ~ BGI_LEVEL eq KERNEL
  566.     push eax
  567.     mov  ebx,dword[.x1]
  568.     mov  ecx,dword[.y1]
  569.   if BGI_WINDOW_CLIP eq 1
  570.     movzx eax,[.x]
  571.     cmp  eax,dword[BGI_PRC_INFO+42]
  572.     ja   .nobold
  573.     movzx eax,[.y]
  574.     cmp  eax,dword[BGI_PRC_INFO+46]
  575.     ja  .nobold
  576.     xor  eax,eax
  577.     cmp  ax,bx
  578.     jg   .nobold
  579.     cmp  ax,cx
  580.     jg   .nobold
  581.   end if
  582.     mov  edx,[.color]
  583. ; \begin{diamond}[18.08.2006]
  584. ; starting from K0530 kernel interprets flag 0x1000000 as
  585. ; negate existing pixels colors, disregarding passed color
  586. ; we do not want this
  587.     and  edx, 0xFFFFFF
  588. ; \end{diamond}[18.08.2006]
  589.     mov  eax,38
  590.     int  0x40
  591.     test ebp,BGI_BOLD
  592.     jz   .nobold
  593.     test ebp,BGI_FREE
  594.     jnz  .free5
  595.   .free5:
  596.     add  ebx,1 shl 16+1
  597.     int  0x40
  598.   .nobold:
  599.     pop  eax
  600. else
  601.     pusha
  602.     mov  eax,dword[.x1]
  603.     mov  ebx,dword[.y1]
  604.     mov  ecx,[.color]
  605. ;    call syscall_drawline
  606.     test dword[esp+8],BGI_BOLD
  607.     jz   .nobold
  608.     add  eax,1 shl 16+1
  609. ;    call syscall_drawline
  610.   .nobold:
  611.     popa
  612. end if
  613.   .noline:
  614.     pop  edx
  615.     test eax,eax
  616.     je   .eovecs  ; op=0
  617.     push [.y1]
  618.     pop  [.y]
  619.     push [.x1]
  620.     pop  [.x]
  621.     add  edx,2
  622.     cmp  edx,[.vec_end]
  623.     jb   .vec_loop
  624.   .eovecs:
  625.     pop  ecx esi
  626.     push [.y]
  627.     pop  [.y0]
  628.     push [.x]
  629.     pop  [.x0]
  630.     loop .mloop1
  631.     jmp  .exit
  632.   .mloop1:
  633.     jmp  .mloop
  634.   .exit:
  635.     mov  eax,dword[.y0]
  636.     mov  [esp+28],eax
  637.   .ex2:
  638.     popa
  639.     ret
  640.  
  641. .BGIfont_Deform:
  642.     test ebp,BGI_FREE
  643.     jnz  .free0
  644.     movzx ebx,byte[.color+3] ;ebx=scale
  645.     imul ecx,ebx
  646.     add  ecx,2
  647.     shr  ecx,2
  648.     imul edx,ebx
  649.     add  edx,2
  650.     shr  edx,2
  651.     neg  edx
  652.     mov  [.x1],cx
  653.     mov  [.y1],dx
  654.     jmp  .add
  655.   .free0:
  656.     mov  [.x1],cx
  657.     mov  [.y1],dx
  658.     fild [.y1]
  659.     fld  st0
  660.     fmul [Yscale]
  661.     fchs
  662.     fistp [.y1]
  663.     fmul [deform]
  664.     fiadd [.x1]
  665.     fmul [Xscale]
  666.     fistp [.x1]
  667.     cmp  [BGIangle],0
  668.     je   .add
  669.     call BGIfont_Coo
  670.     jmp  .eax
  671.   .add:
  672.     mov  cx,[.x0]
  673.     add  [.x1],cx
  674.     mov  cx,[.y0]
  675.     add  [.y1],cx
  676.   .eax:
  677.     ret
  678.  
  679. .BGIfont_GetChar:
  680. ; in:  esi -> string; edi -> BGIrec
  681. ; out: esi -> next char; al - char obtained
  682.     lodsb  ; al - char from str
  683.     sub  al,[edi+5]
  684.     jb   .out
  685.     cmp  al,[edi+4]
  686.     jb   .in
  687.   .out:
  688.     xor  al,al ; al - 1st symbol available
  689.   .in:
  690.     ret
  691.  
  692. .y0      dw ?
  693. .x0      dw ?
  694.  
  695. .x1      dw ?
  696. .x       dw ?
  697. .y1      dw ?
  698. .y       dw ?
  699.  
  700. .color   dd ?
  701. .vec_end dd ?
  702. BGIfont_Ptr  dd 0
  703. BGIheight dw ?
  704. deform dd ?
  705. BGIangle dd ?
  706. Xscale  dd ?
  707. Yscale  dd ?
  708.