freetypefont.bmx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. Strict
  2. Module BRL.FreeTypeFont
  3. ModuleInfo "Version: 1.09"
  4. ModuleInfo "Author: Simon Armstrong, Mark Sibly"
  5. ModuleInfo "License: zlib/libpng"
  6. ModuleInfo "Copyright: Blitz Research Ltd"
  7. ModuleInfo "Modserver: BRL"
  8. ModuleInfo "History: 1.09 Release"
  9. ModuleInfo "History: Offset glyph rect to allow for smooth font border"
  10. ModuleInfo "History: 1.08 Release"
  11. ModuleInfo "History: Fixed freetypelib being reopened per font"
  12. ModuleInfo "History: 1.07 Release"
  13. ModuleInfo "History: Added one pixel blank border around SMOOTHFONT glyphs for ultra smooth subpixel positioning."
  14. ModuleInfo "History: 1.06 Release"
  15. ModuleInfo "History: Fixed memory (incbin::) fonts"
  16. ModuleInfo "History: 1.05 Release"
  17. ModuleInfo "History: Improved unicode support"
  18. ModuleInfo "History: Replaced stream hooks with New_Memory_Face"
  19. ModuleInfo "History: 1.04 Release"
  20. ModuleInfo "History: Added stream hooks"
  21. Import BRL.Font
  22. Import BRL.Pixmap
  23. Import Pub.FreeType
  24. Private
  25. Function PadPixmap:TPixmap( p:TPixmap )
  26. Local t:TPixmap=TPixmap.Create( p.width+2,p.height+2,p.format )
  27. MemClear t.pixels,t.capacity
  28. t.Paste p,1,1
  29. Return t
  30. End Function
  31. Public
  32. Type TFreeTypeGlyph Extends TGlyph
  33. Field _pixmap:TPixmap
  34. Field _advance#,_x,_y,_w,_h
  35. Method Pixels:TPixmap()
  36. If _pixmap Return _pixmap
  37. Return _pixmap
  38. End Method
  39. Method Advance#()
  40. Return _advance
  41. End Method
  42. Method GetRect( x Var,y Var,w Var,h Var )
  43. x=_x
  44. y=_y
  45. w=_w
  46. h=_h
  47. End Method
  48. End Type
  49. Type TFreeTypeFont Extends BRL.Font.TFont
  50. Field _face:FTFace
  51. Field _ft_face:Byte Ptr
  52. Field _style,_height
  53. Field _ascend,_descend
  54. Field _glyphs:TFreeTypeGlyph[]
  55. Field _buf:Byte Ptr,_buf_size
  56. Method Delete()
  57. FT_Done_Face _ft_face
  58. MemFree _buf
  59. End Method
  60. Method Style()
  61. Return _style
  62. End Method
  63. Method Height()
  64. Return _height
  65. End Method
  66. Method CountGlyphs()
  67. Return _glyphs.length
  68. End Method
  69. Method CharToGlyph( char )
  70. Return FT_Get_Char_Index( _ft_face,char )-1
  71. End Method
  72. Method LoadGlyph:TFreeTypeGlyph( index )
  73. Local glyph:TFreeTypeGlyph=_glyphs[index]
  74. If glyph Return glyph
  75. glyph=New TFreeTypeGlyph
  76. _glyphs[index]=glyph
  77. If FT_Load_Glyph( _ft_face,index+1,FT_LOAD_RENDER ) Return glyph
  78. Local slot:FTGlyph=New FTGlyph
  79. MemCopy slot,_face.glyphslot,SizeOf slot
  80. glyph._x=slot.bitmap_left
  81. glyph._y=-slot.bitmap_top+_ascend
  82. glyph._w=slot.width
  83. glyph._h=slot.rows
  84. glyph._advance=slot.advancex Sar 6
  85. If slot.width=0 Return glyph
  86. Local pixmap:TPixmap
  87. If slot.numgreys
  88. pixmap=TPixmap.CreateStatic( slot.buffer,slot.width,slot.rows,slot.pitch,PF_A8 ).Copy()
  89. Else
  90. pixmap=CreatePixmap( slot.width,slot.rows,PF_A8 )
  91. Local b
  92. For Local y=0 Until slot.rows
  93. Local dst:Byte Ptr=pixmap.PixelPtr(0,y)
  94. Local src:Byte Ptr=slot.buffer+y*slot.pitch
  95. For Local x=0 Until slot.width
  96. If (x&7)=0 b=src[x/8]
  97. If b & $80 dst[x]=$ff Else dst[x]=0
  98. b:+b
  99. Next
  100. Next
  101. EndIf
  102. If _style & SMOOTHFONT
  103. glyph._x:-1
  104. glyph._y:-1
  105. glyph._w:+2
  106. glyph._h:+2
  107. pixmap=PadPixmap(pixmap)
  108. EndIf
  109. glyph._pixmap=pixmap
  110. Return glyph
  111. End Method
  112. Function Load:TFreeTypeFont( src$,size,style )
  113. Global ft_lib:Byte Ptr
  114. If Not ft_lib
  115. If FT_Init_FreeType( Varptr ft_lib ) Return
  116. EndIf
  117. Local buf:Byte Ptr,buf_size
  118. Local ft_face:Byte Ptr
  119. If src.Find( "::" )>0
  120. Local tmp:Byte[]=LoadByteArray( src )
  121. buf_size=tmp.length
  122. If Not buf_size Return
  123. buf=MemAlloc( buf_size )
  124. MemCopy buf,tmp,buf_size
  125. If FT_New_Memory_Face( ft_lib,buf,buf_size,0,Varptr ft_face )
  126. MemFree buf
  127. Return
  128. EndIf
  129. Else
  130. If FT_New_Face( ft_lib,src$,0,Varptr ft_face ) Return
  131. EndIf
  132. While size
  133. If Not FT_Set_Pixel_Sizes( ft_face,0,size ) Exit
  134. size:-1
  135. Wend
  136. If Not size
  137. FT_Done_Face ft_face
  138. Return
  139. EndIf
  140. Local face:FTFace=New FTFace
  141. MemCopy face,ft_face,SizeOf face
  142. Local metrics:FTMetrics=New FTMetrics
  143. MemCopy metrics,face.metrics,SizeOf metrics
  144. Local font:TFreeTypeFont=New TFreeTypeFont
  145. font._face=face
  146. font._ft_face=ft_face
  147. font._style=style
  148. font._height=metrics.height Sar 6
  149. font._ascend=metrics.ascend Sar 6
  150. font._descend=metrics.descend Sar 6
  151. font._glyphs=New TFreeTypeGlyph[face.numglyphs]
  152. font._buf=buf
  153. font._buf_size=buf_size
  154. Return font
  155. End Function
  156. End Type
  157. Type TFreeTypeFontLoader Extends TFontLoader
  158. Method LoadFont:TFreeTypeFont( url:Object,size,style )
  159. Local src$=String( url )
  160. If src Return TFreeTypeFont.Load( src,size,style )
  161. End Method
  162. End Type
  163. AddFontLoader New TFreeTypeFontLoader