TextGraphics.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using CommonUI.Data;
  6. using UnityEngine;
  7. using UnityEngine.UI;
  8. using CommonUI_Unity3D.Impl;
  9. using BaseVertexEffect = UnityEngine.UI.BaseMeshEffect;
  10. namespace CommonUnity3D.UGUI
  11. { //---------------------------------------------------------------------------------------------------
  12. public class TextGraphics : Text, ITextComponent
  13. {
  14. public enum UnderlineStyle
  15. {
  16. Sequence = 0,
  17. Fill = 1,
  18. Sliced = 2,
  19. }
  20. public static string DefaultUnderlineChar = "_";
  21. public static UnderlineStyle DefaultUnderlineType = UnderlineStyle.Fill;
  22. private DisplayNode mBinding;
  23. private BaseVertexEffect mTextEffect;
  24. private CommonUI.Data.TextAnchor mTextAnchor = CommonUI.Data.TextAnchor.L_T;
  25. private static readonly UIVertex[] m_TempVerts = new UIVertex[4];
  26. [SerializeField]
  27. private Vector2 m_TextOffset = new Vector2();
  28. [SerializeField]
  29. private Color m_FontColor = Color.white;
  30. [SerializeField]
  31. private bool m_IsUnderline = false;
  32. [SerializeField]
  33. private string m_UnderlineChar = DefaultUnderlineChar;
  34. [SerializeField]
  35. private UnderlineStyle m_UnderlineType = DefaultUnderlineType;
  36. public DisplayNode Binding { get { return mBinding; } }
  37. public BaseVertexEffect TextEffect
  38. {
  39. get { return mTextEffect; }
  40. }
  41. public string Text
  42. {
  43. get { return this.text; }
  44. set
  45. {
  46. if (value == null) value = "";
  47. if (value != this.text)
  48. {
  49. this.text = value;
  50. }
  51. }
  52. }
  53. public int FontSize
  54. {
  55. get { return this.fontSize; }
  56. set { this.fontSize = value; }
  57. }
  58. public UnityEngine.Color FontColor
  59. {
  60. get { return m_FontColor; }
  61. set
  62. {
  63. if (m_FontColor != value)
  64. {
  65. m_FontColor = value;
  66. value.a = base.color.a * value.a;
  67. base.color = value;
  68. }
  69. }
  70. }
  71. public Vector2 TextOffset
  72. {
  73. get { return m_TextOffset; }
  74. set
  75. {
  76. if (value != m_TextOffset)
  77. {
  78. m_TextOffset = value;
  79. base.SetVerticesDirty();
  80. }
  81. }
  82. }
  83. public CommonUI.Data.TextAnchor Anchor
  84. {
  85. get { return mTextAnchor; }
  86. set
  87. {
  88. this.mTextAnchor = value;
  89. this.alignment = UIUtils.ToUnityAnchor(value);
  90. }
  91. }
  92. public CommonUI.Data.FontStyle Style
  93. {
  94. get { return (CommonUI.Data.FontStyle)base.fontStyle; }
  95. set { base.fontStyle = (UnityEngine.FontStyle)value; }
  96. }
  97. public bool IsUnderline
  98. {
  99. get { return m_IsUnderline; }
  100. set
  101. {
  102. if (value != m_IsUnderline)
  103. {
  104. m_IsUnderline = value;
  105. base.SetVerticesDirty();
  106. }
  107. }
  108. }
  109. public string UnderlineChar
  110. {
  111. get { return m_UnderlineChar; }
  112. set
  113. {
  114. if (value != m_UnderlineChar)
  115. {
  116. m_UnderlineChar = value;
  117. base.SetVerticesDirty();
  118. }
  119. }
  120. }
  121. public UnderlineStyle UnderlineType
  122. {
  123. get { return m_UnderlineType; }
  124. set
  125. {
  126. if (value != m_UnderlineType)
  127. {
  128. m_UnderlineType = value;
  129. base.SetVerticesDirty();
  130. }
  131. }
  132. }
  133. public Vector2 PreferredSize
  134. {
  135. get { return new Vector2(base.preferredWidth, base.preferredHeight); }
  136. }
  137. public Rect LastCaretPosition
  138. {
  139. get { return new Rect(mBinding.Width, 0, UIFactory.Instance.DefaultCaretSize.x, mBinding.Height); }
  140. }
  141. public TextGraphics()
  142. {
  143. this.font = UIFactory.Instance.DefaultFont;
  144. this.fontSize = 24;
  145. this.fontStyle = UnityEngine.FontStyle.Normal;
  146. this.color = Color.white;
  147. this.resizeTextForBestFit = true;
  148. this.resizeTextMinSize = UIFactory.Instance.DefaultFontBestFitMin;
  149. this.resizeTextMaxSize = UIFactory.Instance.DefaultFontBestFitMax;
  150. this.horizontalOverflow = HorizontalWrapMode.Overflow;
  151. this.verticalOverflow = VerticalWrapMode.Overflow;
  152. //this.RegisterDirtyVerticesCallback(()=> { OnRefreshUnderline(); });
  153. }
  154. protected override void Start()
  155. {
  156. this.mBinding = DisplayNode.AsDisplayNode(gameObject);
  157. base.Start();
  158. }
  159. public UnityEngine.UI.Outline AddBorder(UnityEngine.Color bc, Vector2 distance)
  160. {
  161. if (mTextEffect != null)
  162. {
  163. Component.Destroy(mTextEffect);
  164. }
  165. if (distance != Vector2.zero)
  166. {
  167. UnityEngine.UI.Outline border = base.gameObject.AddComponent<UnityEngine.UI.Outline>();
  168. border.effectColor = bc;
  169. border.effectDistance = new Vector2(distance.x, -distance.y);
  170. this.mTextEffect = border;
  171. return border;
  172. }
  173. return null;
  174. }
  175. public UnityEngine.UI.Shadow AddShadow(UnityEngine.Color bc, Vector2 distance)
  176. {
  177. if (mTextEffect != null)
  178. {
  179. Component.Destroy(mTextEffect);
  180. }
  181. if (distance != Vector2.zero)
  182. {
  183. UnityEngine.UI.Shadow shadow = base.gameObject.AddComponent<UnityEngine.UI.Shadow>();
  184. shadow.effectColor = bc;
  185. shadow.effectDistance = new Vector2(distance.x, -distance.y);
  186. this.mTextEffect = shadow;
  187. return shadow;
  188. }
  189. return null;
  190. }
  191. public void SetBorder(Color bc, Vector2 distance)
  192. {
  193. AddBorder(bc, distance);
  194. }
  195. public void SetShadow(Color bc, Vector2 distance)
  196. {
  197. AddShadow(bc, distance);
  198. }
  199. public void SetFont(UnityEngine.Font font)
  200. {
  201. this.font = font;
  202. }
  203. public void SetTextFont(UnityEngine.Font font, int size, UnityEngine.FontStyle style)
  204. {
  205. this.font = font;
  206. this.fontSize = size;
  207. this.fontStyle = style;
  208. }
  209. protected override void OnPopulateMesh(VertexHelper vh)
  210. {
  211. base.OnPopulateMesh(vh);
  212. if (m_IsUnderline)
  213. {
  214. this.OnPopulateUnderlineMesh(vh);
  215. }
  216. if (m_TextOffset != Vector2.zero)
  217. {
  218. this.OnPopulateOffset(vh);
  219. }
  220. }
  221. protected virtual void OnPopulateOffset(VertexHelper vh)
  222. {
  223. if (font == null) { return; }
  224. Vector3 offset = new Vector3(m_TextOffset.x, -m_TextOffset.y);
  225. var vertex = UIVertex.simpleVert;
  226. for (int i = vh.currentVertCount - 1; i >= 0; --i)
  227. {
  228. vh.PopulateUIVertex(ref vertex, i);
  229. vertex.position += offset;
  230. vh.SetUIVertex(vertex, i);
  231. }
  232. }
  233. protected virtual void OnPopulateUnderlineMesh(VertexHelper vh)
  234. {
  235. if (font == null) { return; }
  236. if (vh.currentVertCount >= 4)
  237. {
  238. this.m_DisableFontTextureRebuiltCallback = true;
  239. Vector2 size = base.rectTransform.rect.size;
  240. TextGenerationSettings generationSettings = this.GetGenerationSettings(size);
  241. this.cachedTextGenerator.Populate(m_UnderlineChar, generationSettings);
  242. IList<UIVertex> verts = this.cachedTextGenerator.verts;
  243. int num = verts.Count - 4;
  244. if (num >= 4)
  245. {
  246. UICharInfo dchar = this.cachedTextGenerator.characters[0];
  247. if (dchar.charWidth > 0)
  248. {
  249. UIVertex begin_vertex = UIVertex.simpleVert;
  250. UIVertex end_vertex = UIVertex.simpleVert;
  251. vh.PopulateUIVertex(ref begin_vertex, 0);
  252. vh.PopulateUIVertex(ref end_vertex, vh.currentVertCount - 2);
  253. float d = 1f / this.pixelsPerUnit;
  254. switch (m_UnderlineType)
  255. {
  256. case UnderlineStyle.Fill:
  257. {
  258. for (int j = 0; j < 4; j++)
  259. {
  260. m_TempVerts[j] = verts[j];
  261. m_TempVerts[j].position = m_TempVerts[j].position * d;
  262. }
  263. m_TempVerts[0].position.x = m_TempVerts[3].position.x = begin_vertex.position.x;
  264. m_TempVerts[1].position.x = m_TempVerts[2].position.x = end_vertex.position.x;
  265. vh.AddUIVertexQuad(m_TempVerts);
  266. }
  267. break;
  268. case UnderlineStyle.Sequence:
  269. for (float x = begin_vertex.position.x; x < end_vertex.position.x; x += dchar.charWidth)
  270. {
  271. for (int j = 0; j < 4; j++)
  272. {
  273. m_TempVerts[j] = verts[j];
  274. m_TempVerts[j].position = m_TempVerts[j].position * d;
  275. m_TempVerts[j].position.x += x;
  276. }
  277. vh.AddUIVertexQuad(m_TempVerts);
  278. }
  279. break;
  280. case UnderlineStyle.Sliced:
  281. {
  282. float u_clip = Math.Abs(verts[1].uv0.x - verts[0].uv0.x) / 3;//将u切成3份//
  283. float x_clip = (dchar.charWidth) / 3;//将x切成3份//
  284. float u_0 = verts[0].uv0.x;
  285. float u_1 = u_0 + u_clip;
  286. float u_3 = verts[1].uv0.x;
  287. float u_2 = u_3 - u_clip;
  288. float x_0 = begin_vertex.position.x;
  289. float x_1 = x_0 + x_clip;
  290. float x_3 = end_vertex.position.x;
  291. float x_2 = x_3 - x_clip;
  292. for (int i = m_TempVerts.Length - 1; i >= 0; --i)
  293. {
  294. m_TempVerts[i] = verts[i];
  295. m_TempVerts[i].position = m_TempVerts[i].position * d;
  296. }
  297. // left
  298. {
  299. m_TempVerts[3].position.x = m_TempVerts[0].position.x = x_0;
  300. m_TempVerts[2].position.x = m_TempVerts[1].position.x = x_1;
  301. m_TempVerts[3].uv0.x = m_TempVerts[0].uv0.x = u_0;
  302. m_TempVerts[2].uv0.x = m_TempVerts[1].uv0.x = u_1;
  303. vh.AddUIVertexQuad(m_TempVerts);
  304. }
  305. // center
  306. {
  307. m_TempVerts[3].position.x = m_TempVerts[0].position.x = x_1;
  308. m_TempVerts[2].position.x = m_TempVerts[1].position.x = x_2;
  309. m_TempVerts[3].uv0.x = m_TempVerts[0].uv0.x = u_1;
  310. m_TempVerts[2].uv0.x = m_TempVerts[1].uv0.x = u_2;
  311. vh.AddUIVertexQuad(m_TempVerts);
  312. }
  313. // right
  314. {
  315. m_TempVerts[3].position.x = m_TempVerts[0].position.x = x_2;
  316. m_TempVerts[2].position.x = m_TempVerts[1].position.x = x_3;
  317. m_TempVerts[3].uv0.x = m_TempVerts[0].uv0.x = u_2;
  318. m_TempVerts[2].uv0.x = m_TempVerts[1].uv0.x = u_3;
  319. vh.AddUIVertexQuad(m_TempVerts);
  320. }
  321. }
  322. break;
  323. }
  324. }
  325. }
  326. this.m_DisableFontTextureRebuiltCallback = false;
  327. }
  328. }
  329. public override bool Raycast(Vector2 sp, Camera eventCamera)
  330. {
  331. if (mBinding.Enable && mBinding.EnableTouchInParents)
  332. {
  333. return base.Raycast(sp, eventCamera);
  334. }
  335. return false;
  336. }
  337. readonly Vector3[] m_Corners = new Vector3[4];
  338. private Rect rootCanvasRect
  339. {
  340. get
  341. {
  342. rectTransform.GetWorldCorners(m_Corners);
  343. if (canvas)
  344. {
  345. Canvas rootCanvas = canvas.rootCanvas;
  346. for (int i = 0; i < 4; ++i)
  347. m_Corners[i] = rootCanvas.transform.InverseTransformPoint(m_Corners[i]);
  348. }
  349. return new Rect(m_Corners[0].x, m_Corners[0].y, m_Corners[2].x - m_Corners[0].x, m_Corners[2].y - m_Corners[0].y);
  350. }
  351. }
  352. public override void Cull(Rect clipRect, bool validRect)
  353. {
  354. var cull = !validRect || !clipRect.Overlaps(rootCanvasRect, true);
  355. UpdateCull(cull);
  356. }
  357. private void UpdateCull(bool cull)
  358. {
  359. var cullingChanged = canvasRenderer.cull != cull;
  360. canvasRenderer.cull = cull;
  361. if (cullingChanged)
  362. {
  363. onCullStateChanged.Invoke(cull);
  364. SetVerticesDirty();
  365. }
  366. }
  367. }
  368. }