暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

TMP_FontAssetCommon.cs 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. using UnityEngine;
  2. using UnityEngine.Serialization;
  3. using UnityEngine.TextCore;
  4. using UnityEngine.TextCore.LowLevel;
  5. using System;
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. namespace TMPro
  10. {
  11. /// <summary>
  12. /// Class that contains the basic information about the font.
  13. /// </summary>
  14. [Serializable]
  15. public class FaceInfo_Legacy
  16. {
  17. public string Name;
  18. public float PointSize;
  19. public float Scale;
  20. public int CharacterCount;
  21. public float LineHeight;
  22. public float Baseline;
  23. public float Ascender;
  24. public float CapHeight;
  25. public float Descender;
  26. public float CenterLine;
  27. public float SuperscriptOffset;
  28. public float SubscriptOffset;
  29. public float SubSize;
  30. public float Underline;
  31. public float UnderlineThickness;
  32. public float strikethrough;
  33. public float strikethroughThickness;
  34. public float TabWidth;
  35. public float Padding;
  36. public float AtlasWidth;
  37. public float AtlasHeight;
  38. }
  39. // Class which contains the Glyph Info / Character definition for each character contained in the font asset.
  40. [Serializable]
  41. public class TMP_Glyph : TMP_TextElement_Legacy
  42. {
  43. /// <summary>
  44. /// Function to create a deep copy of a GlyphInfo.
  45. /// </summary>
  46. /// <param name="source"></param>
  47. /// <returns></returns>
  48. public static TMP_Glyph Clone(TMP_Glyph source)
  49. {
  50. TMP_Glyph copy = new TMP_Glyph();
  51. copy.id = source.id;
  52. copy.x = source.x;
  53. copy.y = source.y;
  54. copy.width = source.width;
  55. copy.height = source.height;
  56. copy.xOffset = source.xOffset;
  57. copy.yOffset = source.yOffset;
  58. copy.xAdvance = source.xAdvance;
  59. copy.scale = source.scale;
  60. return copy;
  61. }
  62. }
  63. // Structure which holds the font creation settings
  64. [Serializable]
  65. public struct FontAssetCreationSettings
  66. {
  67. public string sourceFontFileName;
  68. public string sourceFontFileGUID;
  69. public int faceIndex;
  70. public int pointSizeSamplingMode;
  71. public int pointSize;
  72. public int padding;
  73. public int paddingMode;
  74. public int packingMode;
  75. public int atlasWidth;
  76. public int atlasHeight;
  77. public int characterSetSelectionMode;
  78. public string characterSequence;
  79. public string referencedFontAssetGUID;
  80. public string referencedTextAssetGUID;
  81. public int fontStyle;
  82. public float fontStyleModifier;
  83. public int renderMode;
  84. public bool includeFontFeatures;
  85. internal FontAssetCreationSettings(string sourceFontFileGUID, int pointSize, int pointSizeSamplingMode, int padding, int packingMode, int atlasWidth, int atlasHeight, int characterSelectionMode, string characterSet, int renderMode)
  86. {
  87. this.sourceFontFileName = string.Empty;
  88. this.sourceFontFileGUID = sourceFontFileGUID;
  89. this.faceIndex = 0;
  90. this.pointSize = pointSize;
  91. this.pointSizeSamplingMode = pointSizeSamplingMode;
  92. this.padding = padding;
  93. this.paddingMode = 2;
  94. this.packingMode = packingMode;
  95. this.atlasWidth = atlasWidth;
  96. this.atlasHeight = atlasHeight;
  97. this.characterSequence = characterSet;
  98. this.characterSetSelectionMode = characterSelectionMode;
  99. this.renderMode = renderMode;
  100. this.referencedFontAssetGUID = string.Empty;
  101. this.referencedTextAssetGUID = string.Empty;
  102. this.fontStyle = 0;
  103. this.fontStyleModifier = 0;
  104. this.includeFontFeatures = false;
  105. }
  106. }
  107. /// <summary>
  108. /// Contains the font assets for the regular and italic styles associated with a given font weight.
  109. /// </summary>
  110. [Serializable]
  111. public struct TMP_FontWeightPair
  112. {
  113. public TMP_FontAsset regularTypeface;
  114. public TMP_FontAsset italicTypeface;
  115. }
  116. public struct KerningPairKey
  117. {
  118. public uint ascii_Left;
  119. public uint ascii_Right;
  120. public uint key;
  121. public KerningPairKey(uint ascii_left, uint ascii_right)
  122. {
  123. ascii_Left = ascii_left;
  124. ascii_Right = ascii_right;
  125. key = (ascii_right << 16) + ascii_left;
  126. }
  127. }
  128. /// <summary>
  129. /// Positional adjustments of a glyph
  130. /// </summary>
  131. [Serializable]
  132. public struct GlyphValueRecord_Legacy
  133. {
  134. public float xPlacement;
  135. public float yPlacement;
  136. public float xAdvance;
  137. public float yAdvance;
  138. internal GlyphValueRecord_Legacy(UnityEngine.TextCore.LowLevel.GlyphValueRecord valueRecord)
  139. {
  140. this.xPlacement = valueRecord.xPlacement;
  141. this.yPlacement = valueRecord.yPlacement;
  142. this.xAdvance = valueRecord.xAdvance;
  143. this.yAdvance = valueRecord.yAdvance;
  144. }
  145. public static GlyphValueRecord_Legacy operator +(GlyphValueRecord_Legacy a, GlyphValueRecord_Legacy b)
  146. {
  147. GlyphValueRecord_Legacy c;
  148. c.xPlacement = a.xPlacement + b.xPlacement;
  149. c.yPlacement = a.yPlacement + b.yPlacement;
  150. c.xAdvance = a.xAdvance + b.xAdvance;
  151. c.yAdvance = a.yAdvance + b.yAdvance;
  152. return c;
  153. }
  154. }
  155. [Serializable]
  156. public class KerningPair
  157. {
  158. /// <summary>
  159. /// The first glyph part of a kerning pair.
  160. /// </summary>
  161. public uint firstGlyph
  162. {
  163. get { return m_FirstGlyph; }
  164. set { m_FirstGlyph = value; }
  165. }
  166. [FormerlySerializedAs("AscII_Left")]
  167. [SerializeField]
  168. private uint m_FirstGlyph;
  169. /// <summary>
  170. /// The positional adjustment of the first glyph.
  171. /// </summary>
  172. public GlyphValueRecord_Legacy firstGlyphAdjustments
  173. {
  174. get { return m_FirstGlyphAdjustments; }
  175. }
  176. [SerializeField]
  177. private GlyphValueRecord_Legacy m_FirstGlyphAdjustments;
  178. /// <summary>
  179. /// The second glyph part of a kerning pair.
  180. /// </summary>
  181. public uint secondGlyph
  182. {
  183. get { return m_SecondGlyph; }
  184. set { m_SecondGlyph = value; }
  185. }
  186. [FormerlySerializedAs("AscII_Right")]
  187. [SerializeField]
  188. private uint m_SecondGlyph;
  189. /// <summary>
  190. /// The positional adjustment of the second glyph.
  191. /// </summary>
  192. public GlyphValueRecord_Legacy secondGlyphAdjustments
  193. {
  194. get { return m_SecondGlyphAdjustments; }
  195. }
  196. [SerializeField]
  197. private GlyphValueRecord_Legacy m_SecondGlyphAdjustments;
  198. [FormerlySerializedAs("XadvanceOffset")]
  199. public float xOffset;
  200. internal static KerningPair empty = new KerningPair(0, new GlyphValueRecord_Legacy(), 0, new GlyphValueRecord_Legacy());
  201. /// <summary>
  202. /// Determines if the Character Spacing property of the text object will affect the kerning pair.
  203. /// This is mostly relevant when using Diacritical marks to prevent Character Spacing from altering the spacing.
  204. /// </summary>
  205. public bool ignoreSpacingAdjustments
  206. {
  207. get { return m_IgnoreSpacingAdjustments; }
  208. }
  209. [SerializeField]
  210. private bool m_IgnoreSpacingAdjustments = false;
  211. public KerningPair()
  212. {
  213. m_FirstGlyph = 0;
  214. m_FirstGlyphAdjustments = new GlyphValueRecord_Legacy();
  215. m_SecondGlyph = 0;
  216. m_SecondGlyphAdjustments = new GlyphValueRecord_Legacy();
  217. }
  218. public KerningPair(uint left, uint right, float offset)
  219. {
  220. firstGlyph = left;
  221. m_SecondGlyph = right;
  222. xOffset = offset;
  223. }
  224. public KerningPair(uint firstGlyph, GlyphValueRecord_Legacy firstGlyphAdjustments, uint secondGlyph, GlyphValueRecord_Legacy secondGlyphAdjustments)
  225. {
  226. m_FirstGlyph = firstGlyph;
  227. m_FirstGlyphAdjustments = firstGlyphAdjustments;
  228. m_SecondGlyph = secondGlyph;
  229. m_SecondGlyphAdjustments = secondGlyphAdjustments;
  230. }
  231. internal void ConvertLegacyKerningData()
  232. {
  233. m_FirstGlyphAdjustments.xAdvance = xOffset;
  234. //xOffset = 0;
  235. }
  236. }
  237. [Serializable]
  238. public class KerningTable
  239. {
  240. public List<KerningPair> kerningPairs;
  241. public KerningTable()
  242. {
  243. kerningPairs = new List<KerningPair>();
  244. }
  245. public void AddKerningPair()
  246. {
  247. if (kerningPairs.Count == 0)
  248. {
  249. kerningPairs.Add(new KerningPair(0, 0, 0));
  250. }
  251. else
  252. {
  253. uint left = kerningPairs.Last().firstGlyph;
  254. uint right = kerningPairs.Last().secondGlyph;
  255. float xoffset = kerningPairs.Last().xOffset;
  256. kerningPairs.Add(new KerningPair(left, right, xoffset));
  257. }
  258. }
  259. /// <summary>
  260. /// Add Kerning Pair
  261. /// </summary>
  262. /// <param name="first">First glyph</param>
  263. /// <param name="second">Second glyph</param>
  264. /// <param name="offset">xAdvance value</param>
  265. /// <returns></returns>
  266. public int AddKerningPair(uint first, uint second, float offset)
  267. {
  268. int index = kerningPairs.FindIndex(item => item.firstGlyph == first && item.secondGlyph == second);
  269. if (index == -1)
  270. {
  271. kerningPairs.Add(new KerningPair(first, second, offset));
  272. return 0;
  273. }
  274. // Return -1 if Kerning Pair already exists.
  275. return -1;
  276. }
  277. /// <summary>
  278. /// Add Glyph pair adjustment record
  279. /// </summary>
  280. /// <param name="firstGlyph">The first glyph</param>
  281. /// <param name="firstGlyphAdjustments">Adjustment record for the first glyph</param>
  282. /// <param name="secondGlyph">The second glyph</param>
  283. /// <param name="secondGlyphAdjustments">Adjustment record for the second glyph</param>
  284. /// <returns></returns>
  285. public int AddGlyphPairAdjustmentRecord(uint first, GlyphValueRecord_Legacy firstAdjustments, uint second, GlyphValueRecord_Legacy secondAdjustments)
  286. {
  287. int index = kerningPairs.FindIndex(item => item.firstGlyph == first && item.secondGlyph == second);
  288. if (index == -1)
  289. {
  290. kerningPairs.Add(new KerningPair(first, firstAdjustments, second, secondAdjustments));
  291. return 0;
  292. }
  293. // Return -1 if Kerning Pair already exists.
  294. return -1;
  295. }
  296. public void RemoveKerningPair(int left, int right)
  297. {
  298. int index = kerningPairs.FindIndex(item => item.firstGlyph == left && item.secondGlyph == right);
  299. if (index != -1)
  300. kerningPairs.RemoveAt(index);
  301. }
  302. public void RemoveKerningPair(int index)
  303. {
  304. kerningPairs.RemoveAt(index);
  305. }
  306. public void SortKerningPairs()
  307. {
  308. // Sort List of Kerning Info
  309. if (kerningPairs.Count > 0)
  310. kerningPairs = kerningPairs.OrderBy(s => s.firstGlyph).ThenBy(s => s.secondGlyph).ToList();
  311. }
  312. }
  313. public static class TMP_FontUtilities
  314. {
  315. private static List<int> k_searchedFontAssets;
  316. /// <summary>
  317. /// Search through the given font and its fallbacks for the specified character.
  318. /// </summary>
  319. /// <param name="font">The font asset to search for the given character.</param>
  320. /// <param name="unicode">The character to find.</param>
  321. /// <param name="character">out parameter containing the glyph for the specified character (if found).</param>
  322. /// <returns></returns>
  323. public static TMP_FontAsset SearchForCharacter(TMP_FontAsset font, uint unicode, out TMP_Character character)
  324. {
  325. if (k_searchedFontAssets == null)
  326. k_searchedFontAssets = new List<int>();
  327. k_searchedFontAssets.Clear();
  328. return SearchForCharacterInternal(font, unicode, out character);
  329. }
  330. /// <summary>
  331. /// Search through the given list of fonts and their possible fallbacks for the specified character.
  332. /// </summary>
  333. /// <param name="fonts"></param>
  334. /// <param name="unicode"></param>
  335. /// <param name="character"></param>
  336. /// <returns></returns>
  337. public static TMP_FontAsset SearchForCharacter(List<TMP_FontAsset> fonts, uint unicode, out TMP_Character character)
  338. {
  339. return SearchForCharacterInternal(fonts, unicode, out character);
  340. }
  341. private static TMP_FontAsset SearchForCharacterInternal(TMP_FontAsset font, uint unicode, out TMP_Character character)
  342. {
  343. character = null;
  344. if (font == null) return null;
  345. if (font.characterLookupTable.TryGetValue(unicode, out character))
  346. {
  347. if (character.textAsset != null)
  348. return font;
  349. // Remove character from lookup table
  350. font.characterLookupTable.Remove(unicode);
  351. }
  352. if (font.fallbackFontAssetTable != null && font.fallbackFontAssetTable.Count > 0)
  353. {
  354. for (int i = 0; i < font.fallbackFontAssetTable.Count && character == null; i++)
  355. {
  356. TMP_FontAsset temp = font.fallbackFontAssetTable[i];
  357. if (temp == null) continue;
  358. int id = temp.GetInstanceID();
  359. // Skip over the fallback font asset in the event it is null or if already searched.
  360. if (k_searchedFontAssets.Contains(id)) continue;
  361. // Add to list of font assets already searched.
  362. k_searchedFontAssets.Add(id);
  363. temp = SearchForCharacterInternal(temp, unicode, out character);
  364. if (temp != null)
  365. return temp;
  366. }
  367. }
  368. return null;
  369. }
  370. private static TMP_FontAsset SearchForCharacterInternal(List<TMP_FontAsset> fonts, uint unicode, out TMP_Character character)
  371. {
  372. character = null;
  373. if (fonts != null && fonts.Count > 0)
  374. {
  375. for (int i = 0; i < fonts.Count; i++)
  376. {
  377. TMP_FontAsset fontAsset = SearchForCharacterInternal(fonts[i], unicode, out character);
  378. if (fontAsset != null)
  379. return fontAsset;
  380. }
  381. }
  382. return null;
  383. }
  384. }
  385. }