font.monkey2 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #import "<mojo>"
  2. #import "<std>"
  3. Private
  4. Global __Afont:Font
  5. Public
  6. Function SetAFont:Font(url:String)
  7. If __Afont = Null
  8. __Afont = New Font
  9. Endif
  10. __Afont.LoadFont(url)
  11. Return __Afont
  12. End Function
  13. Function RenderText:Void(canvas:Canvas,txt:String,x:Float,y:Float)
  14. If __Afont = Null RuntimeError("font not initialized")
  15. __Afont.Render(canvas,txt,x,y)
  16. End Function
  17. Function GetActiveFont:Font()
  18. Return __Afont
  19. End Function
  20. Class Font
  21. Class Glyph
  22. Field id:Int
  23. Field x:Int
  24. Field y:Int
  25. Field width:Int
  26. Field height:Int
  27. Field xOffset:Float
  28. Field yOffset:Float
  29. Field xAdvance:Float
  30. Field page:Int
  31. Field characterName:String
  32. Field atlas:Image
  33. Method Render(canvas:Canvas,px:Float,py:Float,angle:float = 0)
  34. canvas.DrawRect(px+xOffset,py+yOffset,width,height,atlas,x,y)
  35. End Method
  36. End Class
  37. Method New()
  38. font = New Map<Int,Glyph>
  39. End Method
  40. Method LoadFont(url:String)
  41. Local text:string = LoadString("asset::"+url+".fnt")
  42. If text = Null Print "unable to load font"
  43. Local lines:= text.Split(String.FromChar(10))
  44. font.Clear()
  45. For Local line := Eachin lines
  46. Select True
  47. Case line.Contains("info face")
  48. Local i := 10
  49. If line[i] = 34
  50. i += 1
  51. Local n:String = ""
  52. While line[i]<>34
  53. n += line.Mid(i,1)
  54. i+=1
  55. Wend
  56. fontName = n
  57. Endif
  58. size = Int(GetString(line,"Size="))
  59. Case line.Contains("common")
  60. lineHeight = Float(GetString(line,"lineHeight="))
  61. atlasWidth = Float(GetString(line,"scaleW="))
  62. atlasHeight = Float(GetString(line,"scaleH="))
  63. pages = Float(GetString(line,"pages="))
  64. atlas = New Image[pages]
  65. Case line.Contains("page id")
  66. atlasName = GetString(line,"file=")
  67. atlasName = atlasName.Mid(1,atlasName.Length-2)
  68. atlas[0] = Image.Load("asset::"+atlasName)
  69. If atlas[0] = Null Print "invalid image "+atlasName
  70. Case line.Contains("chars count")
  71. charsCount = Int(GetString(line,"chars count="))
  72. Case line.Contains("char id")
  73. Local glyph := New Glyph
  74. glyph.id = Int( GetString(line,"char id="))
  75. glyph.x = Int(GetString(line,"x="))
  76. glyph.y = Int(GetString(line,"y="))
  77. glyph.width = Int(GetString(line,"width="))
  78. glyph.height = Int(GetString(line,"height="))
  79. glyph.xOffset = Int(GetString(line,"xoffset="))
  80. glyph.yOffset = Int(GetString(line,"yoffset="))
  81. glyph.xAdvance = Int(GetString(line,"xadvance="))
  82. glyph.page = Int( GetString(line,"page="))
  83. glyph.characterName = GetString(line,"letter=")
  84. glyph.characterName = glyph.characterName.Mid(1,glyph.characterName.Length-2)
  85. glyph.atlas = atlas[glyph.page]
  86. font.Add(glyph.id,glyph)
  87. End Select
  88. Next
  89. End Method
  90. Property Name:String()
  91. Return fontName
  92. End
  93. Property Height:Float()
  94. Return size
  95. End
  96. Property CharacterCount:int()
  97. Return charsCount
  98. End
  99. Method TextWidth:Int(text:string)
  100. Local width := 0
  101. For Local char := Eachin text
  102. Local glyph := font.Get(char)
  103. If glyph
  104. width += glyph.xAdvance
  105. Else
  106. width += 8
  107. Endif
  108. Next
  109. Return width
  110. End Method
  111. Method Render(canvas:Canvas,txt:String,x:float,y:Float)
  112. For Local char := Eachin txt
  113. Local glyph := font.Get(char)
  114. If glyph = Null
  115. Print "Invalid Character in text " + txt
  116. DebugStop()
  117. Else
  118. glyph.Render(canvas,x,y)
  119. x += glyph.xAdvance
  120. Endif
  121. Next
  122. End Method
  123. Private
  124. Method GetString:String(line:String,s:String)
  125. Local index:Int = s.Length + line.Find(s)
  126. Local text:String = ""
  127. While index < line.Length And line[index] <> 32
  128. text += line.Mid(index,1)
  129. index += 1
  130. Wend
  131. Return text
  132. End Method
  133. Field fontName:string
  134. Field size:Float
  135. Field lineHeight:Float
  136. Field atlasWidth:Float
  137. Field atlasHeight:Float
  138. Field pages:Float
  139. Field charsCount:Int
  140. Field atlas:Image[]
  141. Field atlasName:string
  142. Field font:Map<Int,Glyph>
  143. End Class