No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TMP_DynamicFontAssetUtilities.cs 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using UnityEngine.TextCore.LowLevel;
  4. namespace TMPro
  5. {
  6. internal class TMP_DynamicFontAssetUtilities
  7. {
  8. private static TMP_DynamicFontAssetUtilities s_Instance = new TMP_DynamicFontAssetUtilities();
  9. private Dictionary<ulong, FontReference> s_SystemFontLookup;
  10. private string[] s_SystemFontPaths;
  11. private uint s_RegularStyleNameHashCode = 1291372090;
  12. public struct FontReference
  13. {
  14. public string familyName;
  15. public string styleName;
  16. public int faceIndex;
  17. public string filePath;
  18. public ulong hashCode;
  19. /// <summary>
  20. /// Constructor for new FontReference
  21. /// </summary>
  22. /// <param name="faceNameAndStyle">String that combines the family name with style name</param>
  23. /// <param name="index">Index of the font face and style.</param>
  24. public FontReference(string fontFilePath, string faceNameAndStyle, int index)
  25. {
  26. familyName = null;
  27. styleName = null;
  28. faceIndex = index;
  29. uint familyNameHashCode = 0;
  30. uint styleNameHashCode = 0;
  31. filePath = fontFilePath;
  32. int length = faceNameAndStyle.Length;
  33. char[] conversionArray = new char[length];
  34. int readingFlag = 0;
  35. int writingIndex = 0;
  36. for (int i = 0; i < length; i++)
  37. {
  38. char c = faceNameAndStyle[i];
  39. // Read family name
  40. if (readingFlag == 0)
  41. {
  42. bool isSeparator = i + 2 < length && c == ' ' && faceNameAndStyle[i + 1] == '-' && faceNameAndStyle[i + 2] == ' ';
  43. if (isSeparator)
  44. {
  45. readingFlag = 1;
  46. this.familyName = new string(conversionArray, 0, writingIndex);
  47. i += 2;
  48. writingIndex = 0;
  49. continue;
  50. }
  51. familyNameHashCode = (familyNameHashCode << 5) + familyNameHashCode ^ TMP_TextUtilities.ToUpperFast(c);
  52. conversionArray[writingIndex++] = c;
  53. continue;
  54. }
  55. // Read style name
  56. if (readingFlag == 1)
  57. {
  58. styleNameHashCode = (styleNameHashCode << 5) + styleNameHashCode ^ TMP_TextUtilities.ToUpperFast(c);
  59. conversionArray[writingIndex++] = c;
  60. if (i + 1 == length)
  61. this.styleName = new string(conversionArray, 0, writingIndex);
  62. }
  63. }
  64. hashCode = (ulong)styleNameHashCode << 32 | familyNameHashCode;
  65. }
  66. }
  67. void InitializeSystemFontReferenceCache()
  68. {
  69. if (s_SystemFontLookup == null)
  70. s_SystemFontLookup = new Dictionary<ulong, FontReference>();
  71. else
  72. s_SystemFontLookup.Clear();
  73. if (s_SystemFontPaths == null)
  74. s_SystemFontPaths = Font.GetPathsToOSFonts();
  75. for (int i = 0; i < s_SystemFontPaths.Length; i++)
  76. {
  77. // Load font at the given path
  78. FontEngineError error = FontEngine.LoadFontFace(s_SystemFontPaths[i]);
  79. if (error != FontEngineError.Success)
  80. {
  81. Debug.LogWarning("Error [" + error + "] trying to load the font at path [" + s_SystemFontPaths[i] + "].");
  82. continue;
  83. }
  84. // Get font faces and styles for this font
  85. string[] fontFaces = FontEngine.GetFontFaces();
  86. // Iterate over each font face
  87. for (int j = 0; j < fontFaces.Length; j++)
  88. {
  89. FontReference fontRef = new FontReference(s_SystemFontPaths[i], fontFaces[j], j);
  90. if (s_SystemFontLookup.ContainsKey(fontRef.hashCode))
  91. {
  92. //Debug.Log("<color=#FFFF80>[" + i + "]</color> Family Name <color=#FFFF80>[" + fontRef.familyName + "]</color> Style Name <color=#FFFF80>[" + fontRef.styleName + "]</color> Index [" + fontRef.faceIndex + "] HashCode [" + fontRef.hashCode + "] Path [" + fontRef.filePath + "].");
  93. continue;
  94. }
  95. // Add font reference to lookup dictionary
  96. s_SystemFontLookup.Add(fontRef.hashCode, fontRef);
  97. Debug.Log("[" + i + "] Family Name [" + fontRef.familyName + "] Style Name [" + fontRef.styleName + "] Index [" + fontRef.faceIndex + "] HashCode [" + fontRef.hashCode + "] Path [" + fontRef.filePath + "].");
  98. }
  99. // Unload current font face.
  100. FontEngine.UnloadFontFace();
  101. }
  102. }
  103. /// <summary>
  104. ///
  105. /// </summary>
  106. /// <param name="familyName"></param>
  107. /// <param name="fontRef"></param>
  108. /// <returns></returns>
  109. public static bool TryGetSystemFontReference(string familyName, out FontReference fontRef)
  110. {
  111. return s_Instance.TryGetSystemFontReferenceInternal(familyName, null, out fontRef);
  112. }
  113. /// <summary>
  114. ///
  115. /// </summary>
  116. /// <param name="familyName"></param>
  117. /// <param name="styleName"></param>
  118. /// <param name="fontRef"></param>
  119. /// <returns></returns>
  120. public static bool TryGetSystemFontReference(string familyName, string styleName, out FontReference fontRef)
  121. {
  122. return s_Instance.TryGetSystemFontReferenceInternal(familyName, styleName, out fontRef);
  123. }
  124. bool TryGetSystemFontReferenceInternal(string familyName, string styleName, out FontReference fontRef)
  125. {
  126. if (s_SystemFontLookup == null)
  127. InitializeSystemFontReferenceCache();
  128. fontRef = new FontReference();
  129. // Compute family name hash code
  130. uint familyNameHashCode = TMP_TextUtilities.GetHashCodeCaseInSensitive(familyName);
  131. uint styleNameHashCode = string.IsNullOrEmpty(styleName) ? s_RegularStyleNameHashCode : TMP_TextUtilities.GetHashCodeCaseInSensitive(styleName);
  132. ulong key = (ulong)styleNameHashCode << 32 | familyNameHashCode;
  133. // Lookup font reference
  134. if (s_SystemFontLookup.ContainsKey(key))
  135. {
  136. fontRef = s_SystemFontLookup[key];
  137. return true;
  138. }
  139. // Return if specified family and style name is not found.
  140. if (styleNameHashCode != s_RegularStyleNameHashCode)
  141. return false;
  142. // Return first potential reference for the given family name
  143. foreach (KeyValuePair<ulong, FontReference> pair in s_SystemFontLookup)
  144. {
  145. if (pair.Value.familyName == familyName)
  146. {
  147. fontRef = pair.Value;
  148. return true;
  149. }
  150. }
  151. return false;
  152. }
  153. }
  154. }