DynamicFont.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace FairyGUI
  5. {
  6. /// <summary>
  7. ///
  8. /// </summary>
  9. public class DynamicFont : BaseFont
  10. {
  11. Font _font;
  12. int _size;
  13. float _ascent;
  14. float _lineHeight;
  15. float _scale;
  16. TextFormat _format;
  17. FontStyle _style;
  18. bool _boldVertice;
  19. CharacterInfo _char;
  20. CharacterInfo _lineChar;
  21. bool _gotLineChar;
  22. public DynamicFont()
  23. {
  24. this.canTint = true;
  25. this.keepCrisp = true;
  26. this.customOutline = true;
  27. this.shader = ShaderConfig.textShader;
  28. }
  29. /// <summary>
  30. ///
  31. /// </summary>
  32. /// <param name="name"></param>
  33. /// <param name="font"></param>
  34. /// <returns></returns>
  35. public DynamicFont(string name, Font font) : this()
  36. {
  37. this.name = name;
  38. this.nativeFont = font;
  39. }
  40. override public void Dispose()
  41. {
  42. Font.textureRebuilt -= textureRebuildCallback;
  43. }
  44. public Font nativeFont
  45. {
  46. get { return _font; }
  47. set
  48. {
  49. if (_font != null)
  50. Font.textureRebuilt -= textureRebuildCallback;
  51. _font = value;
  52. Font.textureRebuilt += textureRebuildCallback;
  53. _font.hideFlags = DisplayObject.hideFlags;
  54. _font.material.hideFlags = DisplayObject.hideFlags;
  55. _font.material.mainTexture.hideFlags = DisplayObject.hideFlags;
  56. if (mainTexture != null)
  57. mainTexture.Dispose();
  58. mainTexture = new NTexture(_font.material.mainTexture);
  59. mainTexture.destroyMethod = DestroyMethod.None;
  60. // _ascent = _font.ascent;
  61. // _lineHeight = _font.lineHeight;
  62. _ascent = _font.fontSize;
  63. _lineHeight = _font.fontSize * 1.25f;
  64. }
  65. }
  66. override public void SetFormat(TextFormat format, float fontSizeScale)
  67. {
  68. _format = format;
  69. float size = format.size * fontSizeScale;
  70. if (keepCrisp)
  71. size *= UIContentScaler.scaleFactor;
  72. if (_format.specialStyle == TextFormat.SpecialStyle.Subscript || _format.specialStyle == TextFormat.SpecialStyle.Superscript)
  73. size *= SupScale;
  74. _size = Mathf.FloorToInt(size);
  75. if (_size == 0)
  76. _size = 1;
  77. _scale = (float)_size / _font.fontSize;
  78. if (format.bold && !customBold)
  79. {
  80. if (format.italic)
  81. {
  82. if (customBoldAndItalic)
  83. _style = FontStyle.Italic;
  84. else
  85. _style = FontStyle.BoldAndItalic;
  86. }
  87. else
  88. _style = FontStyle.Bold;
  89. }
  90. else
  91. {
  92. if (format.italic)
  93. _style = FontStyle.Italic;
  94. else
  95. _style = FontStyle.Normal;
  96. }
  97. _boldVertice = format.bold && (customBold || (format.italic && customBoldAndItalic));
  98. format.FillVertexColors(vertexColors);
  99. }
  100. override public void PrepareCharacters(string text)
  101. {
  102. _font.RequestCharactersInTexture(text, _size, _style);
  103. }
  104. override public bool GetGlyph(char ch, out float width, out float height, out float baseline)
  105. {
  106. if (!_font.GetCharacterInfo(ch, out _char, _size, _style))
  107. {
  108. if (ch == ' ')
  109. {
  110. //space may not be prepared, try again
  111. _font.RequestCharactersInTexture(" ", _size, _style);
  112. _font.GetCharacterInfo(ch, out _char, _size, _style);
  113. }
  114. else
  115. {
  116. width = height = baseline = 0;
  117. return false;
  118. }
  119. }
  120. width = _char.advance;
  121. height = _lineHeight * _scale;
  122. baseline = _ascent * _scale;
  123. if (_boldVertice)
  124. width++;
  125. if (_format.specialStyle == TextFormat.SpecialStyle.Subscript)
  126. {
  127. height /= SupScale;
  128. baseline /= SupScale;
  129. }
  130. else if (_format.specialStyle == TextFormat.SpecialStyle.Superscript)
  131. {
  132. height = height / SupScale + baseline * SupOffset;
  133. baseline *= (SupOffset + 1 / SupScale);
  134. }
  135. height = Mathf.RoundToInt(height);
  136. baseline = Mathf.RoundToInt(baseline);
  137. if (keepCrisp)
  138. {
  139. width /= UIContentScaler.scaleFactor;
  140. height /= UIContentScaler.scaleFactor;
  141. baseline /= UIContentScaler.scaleFactor;
  142. }
  143. return true;
  144. }
  145. static Vector3 bottomLeft;
  146. static Vector3 topLeft;
  147. static Vector3 topRight;
  148. static Vector3 bottomRight;
  149. static Vector2 uvBottomLeft;
  150. static Vector2 uvTopLeft;
  151. static Vector2 uvTopRight;
  152. static Vector2 uvBottomRight;
  153. static Color32[] vertexColors = new Color32[4];
  154. static Vector3[] BOLD_OFFSET = new Vector3[]
  155. {
  156. new Vector3(-0.5f, 0f, 0f),
  157. new Vector3(0.5f, 0f, 0f),
  158. new Vector3(0f, -0.5f, 0f),
  159. new Vector3(0f, 0.5f, 0f)
  160. };
  161. override public int DrawGlyph(float x, float y,
  162. List<Vector3> vertList, List<Vector2> uvList, List<Vector2> uv2List, List<Color32> colList)
  163. {
  164. topLeft.x = _char.minX;
  165. topLeft.y = _char.maxY;
  166. bottomRight.x = _char.maxX;
  167. if (_char.glyphWidth == 0) //zero width, space etc
  168. bottomRight.x = topLeft.x + _size / 2;
  169. bottomRight.y = _char.minY;
  170. if (keepCrisp)
  171. {
  172. topLeft /= UIContentScaler.scaleFactor;
  173. bottomRight /= UIContentScaler.scaleFactor;
  174. }
  175. if (_format.specialStyle == TextFormat.SpecialStyle.Subscript)
  176. y = y - Mathf.RoundToInt(_ascent * _scale * SupOffset);
  177. else if (_format.specialStyle == TextFormat.SpecialStyle.Superscript)
  178. y = y + Mathf.RoundToInt(_ascent * _scale * (1 / SupScale - 1 + SupOffset));
  179. topLeft.x += x;
  180. topLeft.y += y;
  181. bottomRight.x += x;
  182. bottomRight.y += y;
  183. topRight.x = bottomRight.x;
  184. topRight.y = topLeft.y;
  185. bottomLeft.x = topLeft.x;
  186. bottomLeft.y = bottomRight.y;
  187. vertList.Add(bottomLeft);
  188. vertList.Add(topLeft);
  189. vertList.Add(topRight);
  190. vertList.Add(bottomRight);
  191. uvBottomLeft = _char.uvBottomLeft;
  192. uvTopLeft = _char.uvTopLeft;
  193. uvTopRight = _char.uvTopRight;
  194. uvBottomRight = _char.uvBottomRight;
  195. uvList.Add(uvBottomLeft);
  196. uvList.Add(uvTopLeft);
  197. uvList.Add(uvTopRight);
  198. uvList.Add(uvBottomRight);
  199. colList.Add(vertexColors[0]);
  200. colList.Add(vertexColors[1]);
  201. colList.Add(vertexColors[2]);
  202. colList.Add(vertexColors[3]);
  203. if (_boldVertice)
  204. {
  205. for (int b = 0; b < 4; b++)
  206. {
  207. Vector3 boldOffset = BOLD_OFFSET[b];
  208. vertList.Add(bottomLeft + boldOffset);
  209. vertList.Add(topLeft + boldOffset);
  210. vertList.Add(topRight + boldOffset);
  211. vertList.Add(bottomRight + boldOffset);
  212. uvList.Add(uvBottomLeft);
  213. uvList.Add(uvTopLeft);
  214. uvList.Add(uvTopRight);
  215. uvList.Add(uvBottomRight);
  216. colList.Add(vertexColors[0]);
  217. colList.Add(vertexColors[1]);
  218. colList.Add(vertexColors[2]);
  219. colList.Add(vertexColors[3]);
  220. }
  221. return 20;
  222. }
  223. else
  224. return 4;
  225. }
  226. override public int DrawLine(float x, float y, float width, int fontSize, int type,
  227. List<Vector3> vertList, List<Vector2> uvList, List<Vector2> uv2List, List<Color32> colList)
  228. {
  229. if (!_gotLineChar)
  230. {
  231. _gotLineChar = true;
  232. _font.RequestCharactersInTexture("_", 50, FontStyle.Normal);
  233. _font.GetCharacterInfo('_', out _lineChar, 50, FontStyle.Normal);
  234. }
  235. float thickness;
  236. float offset;
  237. thickness = Mathf.Max(1, fontSize / 16f); //guest underline size
  238. if (type == 0)
  239. offset = Mathf.RoundToInt(_lineChar.minY * (float)fontSize / 50 + thickness);
  240. else
  241. offset = Mathf.RoundToInt(_ascent * 0.4f * fontSize / _font.fontSize);
  242. if (thickness < 1)
  243. thickness = 1;
  244. topLeft.x = x;
  245. topLeft.y = y + offset;
  246. bottomRight.x = x + width;
  247. bottomRight.y = topLeft.y - thickness;
  248. topRight.x = bottomRight.x;
  249. topRight.y = topLeft.y;
  250. bottomLeft.x = topLeft.x;
  251. bottomLeft.y = bottomRight.y;
  252. vertList.Add(bottomLeft);
  253. vertList.Add(topLeft);
  254. vertList.Add(topRight);
  255. vertList.Add(bottomRight);
  256. uvBottomLeft = _lineChar.uvBottomLeft;
  257. uvTopLeft = _lineChar.uvTopLeft;
  258. uvTopRight = _lineChar.uvTopRight;
  259. uvBottomRight = _lineChar.uvBottomRight;
  260. //取中点的UV
  261. Vector2 u0;
  262. if (_lineChar.uvBottomLeft.x != _lineChar.uvBottomRight.x)
  263. u0.x = (_lineChar.uvBottomLeft.x + _lineChar.uvBottomRight.x) * 0.5f;
  264. else
  265. u0.x = (_lineChar.uvBottomLeft.x + _lineChar.uvTopLeft.x) * 0.5f;
  266. if (_lineChar.uvBottomLeft.y != _lineChar.uvTopLeft.y)
  267. u0.y = (_lineChar.uvBottomLeft.y + _lineChar.uvTopLeft.y) * 0.5f;
  268. else
  269. u0.y = (_lineChar.uvBottomLeft.y + _lineChar.uvBottomRight.y) * 0.5f;
  270. uvList.Add(u0);
  271. uvList.Add(u0);
  272. uvList.Add(u0);
  273. uvList.Add(u0);
  274. colList.Add(vertexColors[0]);
  275. colList.Add(vertexColors[1]);
  276. colList.Add(vertexColors[2]);
  277. colList.Add(vertexColors[3]);
  278. if (_boldVertice)
  279. {
  280. for (int b = 0; b < 4; b++)
  281. {
  282. Vector3 boldOffset = BOLD_OFFSET[b];
  283. vertList.Add(bottomLeft + boldOffset);
  284. vertList.Add(topLeft + boldOffset);
  285. vertList.Add(topRight + boldOffset);
  286. vertList.Add(bottomRight + boldOffset);
  287. uvList.Add(u0);
  288. uvList.Add(u0);
  289. uvList.Add(u0);
  290. uvList.Add(u0);
  291. colList.Add(vertexColors[0]);
  292. colList.Add(vertexColors[1]);
  293. colList.Add(vertexColors[2]);
  294. colList.Add(vertexColors[3]);
  295. }
  296. return 20;
  297. }
  298. else
  299. return 4;
  300. }
  301. override public bool HasCharacter(char ch)
  302. {
  303. return _font.HasCharacter(ch);
  304. }
  305. override public int GetLineHeight(int size)
  306. {
  307. return Mathf.RoundToInt(_lineHeight * size / _font.fontSize);
  308. }
  309. void textureRebuildCallback(Font targetFont)
  310. {
  311. if (_font != targetFont)
  312. return;
  313. if (mainTexture == null || !Application.isPlaying)
  314. {
  315. mainTexture = new NTexture(_font.material.mainTexture);
  316. mainTexture.destroyMethod = DestroyMethod.None;
  317. }
  318. else
  319. mainTexture.Reload(_font.material.mainTexture, null);
  320. _gotLineChar = false;
  321. textRebuildFlag = true;
  322. version++;
  323. //Debug.Log("Font texture rebuild: " + name + "," + mainTexture.width + "," + mainTexture.height);
  324. }
  325. }
  326. }