RichText.cs 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842
  1. using UnityEngine.EventSystems;
  2. namespace textUtility
  3. {
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. using UnityEditor.VisualStudioIntegration;
  9. using UnityEngine;
  10. using UnityEngine.UI;
  11. [Serializable]
  12. public class RichText : Text, IPointerClickHandler
  13. {
  14. private class ParseResult
  15. {
  16. public int ExtraOffset;
  17. public string NewText;
  18. public BaseMatch Match;
  19. }
  20. #region Config
  21. private List<string> OpenPatterns
  22. {
  23. get
  24. {
  25. if (!openPatterns.IsAvailable())
  26. {
  27. openPatterns = new List<string>();
  28. openPatterns.Add(SpriteOpenPattern);
  29. openPatterns.Add(UnderlineOpenPattern);
  30. openPatterns.Add(SuperlinkOpenPattern);
  31. }
  32. return openPatterns;
  33. }
  34. }
  35. private List<string> openPatterns;
  36. private List<string> ClosePatterns
  37. {
  38. get
  39. {
  40. if (!closePatterns.IsAvailable())
  41. {
  42. closePatterns = new List<string>();
  43. closePatterns.Add(SpriteClosePattern);
  44. closePatterns.Add(UnderlineClosePattern);
  45. closePatterns.Add(SuperlinkClosePattern);
  46. }
  47. return closePatterns;
  48. }
  49. }
  50. private List<string> closePatterns;
  51. private Dictionary<string, Func<string, MatchData, ParseResult>> OpenCloseParseFunctionDictionary
  52. {
  53. get
  54. {
  55. if (!openCloseParseFunctionDictionary.IsAvailable())
  56. {
  57. openCloseParseFunctionDictionary = new Dictionary<string, Func<string, MatchData, ParseResult>>();
  58. openCloseParseFunctionDictionary.Add(SpriteOpenPattern, ParseSpritePattern);
  59. openCloseParseFunctionDictionary.Add(UnderlineOpenPattern, ParseUnderlinePattern);
  60. openCloseParseFunctionDictionary.Add(SuperlinkOpenPattern, ParseSuperlinkPattern);
  61. }
  62. return openCloseParseFunctionDictionary;
  63. }
  64. }
  65. private Dictionary<string, Func<string, MatchData, ParseResult>> openCloseParseFunctionDictionary;
  66. public bool SpriteFoldout;
  67. public string SpriteOpenPattern = "<(";
  68. public string SpriteClosePattern = ")>";
  69. public char SpriteReplaceChar = ' ';
  70. public List<SpriteSetting> SpriteSettings; //todo 可能为空
  71. private Dictionary<int, SpriteSetting> SpriteSettingDictionary
  72. {
  73. get
  74. {
  75. if (!spriteSettingDictionary.IsAvailable())
  76. {
  77. spriteSettingDictionary = new Dictionary<int, SpriteSetting>();
  78. foreach (var item in SpriteSettings)
  79. {
  80. spriteSettingDictionary.Add(item.ID, item);
  81. }
  82. }
  83. return spriteSettingDictionary;
  84. }
  85. set { spriteSettingDictionary = value; }
  86. }
  87. private Dictionary<int, SpriteSetting> spriteSettingDictionary;
  88. private List<BaseMatch> AvailableSpriteMatches = new List<BaseMatch>();
  89. private List<BaseMatch> TruncateSpriteMatches = new List<BaseMatch>();
  90. public bool UnderlineFoldout;
  91. public string UnderlineOpenPattern = "<[";
  92. public string UnderlineClosePattern = "]>";
  93. public List<UnderlineSetting> UnderlineSettings; //todo 可能为空
  94. private Dictionary<int, UnderlineSetting> UnderlineSettingDictionary
  95. {
  96. get
  97. {
  98. if (!underlineSettingDictionary.IsAvailable())
  99. {
  100. underlineSettingDictionary = new Dictionary<int, UnderlineSetting>();
  101. foreach (var item in UnderlineSettings)
  102. {
  103. underlineSettingDictionary.Add(item.ID, item);
  104. }
  105. }
  106. return underlineSettingDictionary;
  107. }
  108. set { underlineSettingDictionary = value; }
  109. }
  110. private Dictionary<int, UnderlineSetting> underlineSettingDictionary;
  111. private List<BaseMatch> UnderlineMatches = new List<BaseMatch>();
  112. public bool SuperlinkFoldout;
  113. public string SuperlinkOpenPattern = "<{";
  114. public string SuperlinkClosePattern = "}>";
  115. public List<SuperlinkSetting> SuperlinkSettings; //todo 可能为空
  116. public Dictionary<int, Action<int>> SuperlinkCallbackDictionary = new Dictionary<int, Action<int>>();
  117. private Dictionary<int, SuperlinkSetting> SuperlinkSettingDictionary
  118. {
  119. get
  120. {
  121. if (superlinkSettingDictionary == null)
  122. {
  123. superlinkSettingDictionary = new Dictionary<int, SuperlinkSetting>();
  124. foreach (var item in SuperlinkSettings)
  125. {
  126. superlinkSettingDictionary.Add(item.ID, item);
  127. }
  128. }
  129. return superlinkSettingDictionary;
  130. }
  131. }
  132. private Dictionary<int, SuperlinkSetting> superlinkSettingDictionary;
  133. private List<BaseMatch> SuperlinkMatches = new List<BaseMatch>();
  134. private char TransferSpaceReplaceChar = 'i';
  135. private List<BaseMatch> TransferSpaceMatches = new List<BaseMatch>();
  136. private List<List<BaseMatch>> MatchesList = new List<List<BaseMatch>>();
  137. public int MinSize
  138. {
  139. get { return minSize; }
  140. set
  141. {
  142. minSize = value;
  143. ApplyVerticalBestfitSize();
  144. }
  145. }
  146. public int minSize = 10;
  147. public int MaxSize
  148. {
  149. get { return maxSize; }
  150. set
  151. {
  152. maxSize = value;
  153. ApplyVerticalBestfitSize();
  154. }
  155. }
  156. public int maxSize = 40;
  157. public bool VerticalBestfitFoldout;
  158. public bool UseOriginBestfit;
  159. public bool UseVerticalBestfit;
  160. public bool VerticalBestfitDirty;
  161. public bool Debug;
  162. public bool Foldout = true;
  163. public bool CalculateFlag;
  164. public string Content;
  165. public string IDPattern = "\\(\\d+\\)";
  166. public KerningSolution KerningSolution;
  167. public RichTextImageManager ImageManager;
  168. private char CalculateReferenceChar = 'i';
  169. private TextGenerator CalculateTextGenerator;
  170. #endregion
  171. protected override void Awake()
  172. {
  173. base.Awake();
  174. if (Debug)
  175. {
  176. text = Content;
  177. UnityEngine.Debug.LogWarning("没有关闭Debug", gameObject);
  178. }
  179. }
  180. protected override void OnPopulateMesh(VertexHelper toFill)
  181. {
  182. if (CalculateFlag)
  183. {
  184. CalculateFlag = false;
  185. }
  186. else
  187. {
  188. string newText = Content;
  189. if (Application.isPlaying || Debug)
  190. {
  191. bool addNewOpenCloseMatch = ParseAndFillMatches(ref newText);
  192. if (addNewOpenCloseMatch)
  193. {
  194. AddNewOpenCloseMatch(newText);
  195. }
  196. CalculateFlag = addNewOpenCloseMatch;
  197. }
  198. if (UseVerticalBestfit && horizontalOverflow != HorizontalWrapMode.Overflow && verticalOverflow != VerticalWrapMode.Overflow)
  199. {
  200. if (VerticalBestfitDirty)
  201. {
  202. int verticalBestfitFontSize = GetVerticalBestfitFontSize(newText);
  203. if (fontSize != verticalBestfitFontSize)
  204. {
  205. DelayCall.Call(1, () => { fontSize = verticalBestfitFontSize; });
  206. VerticalBestfitDirty = false;
  207. CalculateFlag = true;
  208. }
  209. }
  210. else
  211. {
  212. VerticalBestfitDirty = true;
  213. }
  214. }
  215. if (CalculateFlag)
  216. {
  217. return;
  218. }
  219. }
  220. base.OnPopulateMesh(toFill);
  221. List<UIVertex> vertices = new List<UIVertex>();
  222. toFill.GetUIVertexStream(vertices);
  223. ImageManager.Vertices = vertices;
  224. HandleTransferSpaceMatch(toFill, vertices);
  225. for (int i = 0; i < vertices.Count; i += 6)
  226. {
  227. Vector3 position0 = transform.TransformPoint(vertices[0 + i].position);
  228. Vector3 position1 = transform.TransformPoint(vertices[1 + i].position);
  229. Vector3 position2 = transform.TransformPoint(vertices[2 + i].position);
  230. Vector3 position3 = transform.TransformPoint(vertices[4 + i].position);
  231. UnityEngine.Debug.DrawLine(position0, position1, Color.black, 1);
  232. UnityEngine.Debug.DrawLine(position1, position2, Color.black, 1);
  233. UnityEngine.Debug.DrawLine(position2, position3, Color.black, 1);
  234. UnityEngine.Debug.DrawLine(position3, position0, Color.black, 1);
  235. }
  236. if (KerningSolution == KerningSolution.Precalculate)
  237. {
  238. for (int i = 0; i < AvailableSpriteMatches.Count; i++)
  239. {
  240. SpriteMatch spriteMatch = (SpriteMatch)AvailableSpriteMatches[i];
  241. int index0 = 4 + spriteMatch.StartIndex * 6;
  242. int index1 = 3 + spriteMatch.EndIndex * 6;
  243. Vector3 leftPosition = vertices[index0].position;
  244. Vector3 rightPosition = vertices[index1].position;
  245. Vector3 bottomMiddle = (leftPosition + rightPosition) / 2;
  246. Vector3 position0;
  247. Vector3 position1;
  248. Vector3 position2;
  249. Vector3 position3;
  250. spriteMatch.ScaledHeight = spriteMatch.SpriteInfo.GetScaledHeight(spriteMatch.ScaledWidth);
  251. position0 = bottomMiddle + new Vector3(-spriteMatch.ScaledWidth / 2, 0, 0);
  252. position1 = bottomMiddle + new Vector3(spriteMatch.ScaledWidth / 2, 0, 0);
  253. position2 = bottomMiddle + new Vector3(spriteMatch.ScaledWidth / 2, spriteMatch.ScaledHeight, 0);
  254. position3 = bottomMiddle + new Vector3(-spriteMatch.ScaledWidth / 2, spriteMatch.ScaledHeight, 0);
  255. position0 = transform.TransformPoint(position0);
  256. position1 = transform.TransformPoint(position1);
  257. position2 = transform.TransformPoint(position2);
  258. position3 = transform.TransformPoint(position3);
  259. spriteMatch.Positions.Add(position0);
  260. spriteMatch.Positions.Add(position1);
  261. spriteMatch.Positions.Add(position2);
  262. spriteMatch.Positions.Add(position3);
  263. }
  264. }
  265. else if (KerningSolution == KerningSolution.Shrink)
  266. {
  267. Dictionary<SpriteInfo, Dictionary<int, List<SpriteMatch>>> dictionary = new Dictionary<SpriteInfo, Dictionary<int, List<SpriteMatch>>>();
  268. for (int i = 0; i < AvailableSpriteMatches.Count; i++)
  269. {
  270. SpriteMatch spriteMatch = (SpriteMatch)AvailableSpriteMatches[i];
  271. if (dictionary.ContainsKey(spriteMatch.SpriteInfo))
  272. {
  273. if (dictionary[spriteMatch.SpriteInfo].ContainsKey(spriteMatch.Length))
  274. {
  275. dictionary[spriteMatch.SpriteInfo][spriteMatch.Length].Add(spriteMatch);
  276. }
  277. else
  278. {
  279. List<SpriteMatch> matches = new List<SpriteMatch>();
  280. matches.Add(spriteMatch);
  281. dictionary[spriteMatch.SpriteInfo].Add(spriteMatch.Length, matches);
  282. }
  283. }
  284. else
  285. {
  286. List<SpriteMatch> matches = new List<SpriteMatch>();
  287. matches.Add(spriteMatch);
  288. Dictionary<int, List<SpriteMatch>> lengthDictionary = new Dictionary<int, List<SpriteMatch>>();
  289. lengthDictionary.Add(spriteMatch.Length, matches);
  290. dictionary.Add(spriteMatch.SpriteInfo, lengthDictionary);
  291. }
  292. }
  293. foreach (var lengthDictionary in dictionary)
  294. {
  295. foreach (var matches in lengthDictionary.Value.Values)
  296. {
  297. float minScaledWidth = Mathf.Infinity;
  298. for (int i = 0; i < matches.Count; i++)
  299. {
  300. float scaledWidth = matches[i].ScaledWidth;
  301. int frontIndex = matches[i].StartIndex - 1;
  302. int rearIndex = matches[i].EndIndex + 1;
  303. float frontKerning;
  304. float rearKerning;
  305. if (frontIndex < 0)
  306. {
  307. frontKerning = 0;
  308. }
  309. else
  310. {
  311. frontKerning = GetKerning(text[frontIndex], SpriteReplaceChar);
  312. }
  313. if (rearIndex >= text.Length)
  314. {
  315. rearKerning = 0;
  316. }
  317. else
  318. {
  319. rearKerning = GetKerning(SpriteReplaceChar, text[rearIndex]);
  320. }
  321. if (frontKerning < 0)
  322. {
  323. scaledWidth += frontKerning;
  324. }
  325. if (rearKerning < 0)
  326. {
  327. scaledWidth += rearKerning;
  328. }
  329. if (minScaledWidth > scaledWidth)
  330. {
  331. minScaledWidth = scaledWidth;
  332. }
  333. matches[i].FrontKerning = frontKerning;
  334. matches[i].RearKerning = rearKerning;
  335. }
  336. float minScaledHeight = lengthDictionary.Key.GetScaledHeight(minScaledWidth);
  337. for (int i = 0; i < matches.Count; i++)
  338. {
  339. matches[i].ScaledWidth = minScaledWidth;
  340. matches[i].ScaledHeight = minScaledHeight;
  341. }
  342. }
  343. }
  344. for (int i = 0; i < AvailableSpriteMatches.Count; i++)
  345. {
  346. SpriteMatch spriteMatch = (SpriteMatch)AvailableSpriteMatches[i];
  347. int index0 = 4 + spriteMatch.StartIndex * 6;
  348. int index1 = 3 + spriteMatch.EndIndex * 6;
  349. Vector3 leftPosition = vertices[index0].position;
  350. Vector3 rightPosition = vertices[index1].position;
  351. leftPosition.x -= spriteMatch.FrontKerning;
  352. rightPosition.x += spriteMatch.RearKerning;
  353. Vector3 bottomMiddle = (leftPosition + rightPosition) / 2;
  354. Vector3 position0;
  355. Vector3 position1;
  356. Vector3 position2;
  357. Vector3 position3;
  358. position0 = bottomMiddle + new Vector3(-spriteMatch.ScaledWidth / 2, 0, 0);
  359. position1 = bottomMiddle + new Vector3(spriteMatch.ScaledWidth / 2, 0, 0);
  360. position2 = bottomMiddle + new Vector3(spriteMatch.ScaledWidth / 2, spriteMatch.ScaledHeight, 0);
  361. position3 = bottomMiddle + new Vector3(-spriteMatch.ScaledWidth / 2, spriteMatch.ScaledHeight, 0);
  362. position0 = transform.TransformPoint(position0);
  363. position1 = transform.TransformPoint(position1);
  364. position2 = transform.TransformPoint(position2);
  365. position3 = transform.TransformPoint(position3);
  366. spriteMatch.Positions.Add(position0);
  367. spriteMatch.Positions.Add(position1);
  368. spriteMatch.Positions.Add(position2);
  369. spriteMatch.Positions.Add(position3);
  370. }
  371. }
  372. for (int i = 0; i < UnderlineMatches.Count; i++)
  373. {
  374. UnderlineMatch match = UnderlineMatches[i] as UnderlineMatch;
  375. //print(match.StartIndex + " " + match.EndIndex);
  376. GetSegments(text, CalculateTextGenerator, match, match.UnderlineSetting.UnderlineExcludeChars);
  377. for (int j = 0; j < match.Segments.Count; j++)
  378. {
  379. int startCharIdx = match.Segments[j][0];
  380. int endCharIdx = match.Segments[j][1];
  381. //print(startCharIdx + " " + endCharIdx);
  382. int lineIndex = GetLineIndex(CalculateTextGenerator, startCharIdx);
  383. int lineEndCharacterIndex;
  384. float penPositionY = GetPenPositionY(lineIndex, CalculateTextGenerator.lineCount);
  385. float lineHeight = CalculateTextGenerator.lines[lineIndex].height;
  386. if (lineIndex != -1)
  387. {
  388. lineEndCharacterIndex = GetLineEndCharacterIndex(CalculateTextGenerator, lineIndex, text.Length);
  389. }
  390. else
  391. {
  392. break;
  393. }
  394. int newEndCharIdx = Mathf.Min(lineEndCharacterIndex, endCharIdx);
  395. List<Vector3> positions = new List<Vector3>();
  396. Vector3 position0 = vertices[4 + startCharIdx * 6].position;
  397. Vector3 position1 = vertices[2 + newEndCharIdx * 6].position;
  398. position0.y = penPositionY;
  399. position1.y = penPositionY;
  400. Vector3 position2 = position1;
  401. Vector3 position3 = position0;
  402. float underlineHeight = lineHeight * match.UnderlineSetting.Scale;
  403. position2.y -= underlineHeight;
  404. position3.y -= underlineHeight;
  405. if (match.UnderlineSetting.Style == UnderlineStyle.Ellipse)
  406. {
  407. if (vertices[1 + endCharIdx*6].position.x - vertices[0 + startCharIdx*6].position.x > underlineHeight*2)
  408. {
  409. position0.x += underlineHeight;
  410. position1.x -= underlineHeight;
  411. position2.x -= underlineHeight;
  412. position3.x += underlineHeight;
  413. List<Vector3> topHemispherePositions = new List<Vector3>();
  414. List<Vector3> bottomHemispherePositions = new List<Vector3>();
  415. int cutCount = Mathf.Max(4, Mathf.CeilToInt(underlineHeight));
  416. float radius = underlineHeight/2;
  417. for (int k = 0; k <= cutCount; k++)
  418. {
  419. float angle = 90f/cutCount*k;
  420. float radian = angle*Mathf.Deg2Rad;
  421. float x = radius * Mathf.Sin(radian);
  422. float y = radius * Mathf.Cos(radian);
  423. topHemispherePositions.Add(new Vector3(x, y, 0));
  424. if (k != cutCount)
  425. {
  426. bottomHemispherePositions.Insert(0, new Vector3(x, -y, 0));
  427. }
  428. }
  429. List<List<Vector3>> ellipsePositionsList = new List<List<Vector3>>();
  430. List<Vector3> ellipsePositions = new List<Vector3>(); //右半球
  431. ellipsePositions.Add((position1+position2)/2);
  432. foreach (var position in topHemispherePositions)
  433. {
  434. Vector3 newPosition = ellipsePositions[0] + position;
  435. ellipsePositions.Add(newPosition);
  436. }
  437. //ellipsePositions.Add(ellipsePositions[0] + new Vector3(radius, 0, 0));
  438. foreach (var position in bottomHemispherePositions)
  439. {
  440. Vector3 newPosition = ellipsePositions[0] + position;
  441. ellipsePositions.Add(newPosition);
  442. }
  443. for (int k = 0; k < ellipsePositions.Count; k++)
  444. {
  445. ellipsePositions[k] = rectTransform.TransformPoint(ellipsePositions[k]);
  446. }
  447. ellipsePositionsList.Add(ellipsePositions);
  448. ellipsePositions = new List<Vector3>(); //左半球
  449. ellipsePositions.Add((position0 + position3) / 2);
  450. foreach (var position in topHemispherePositions)
  451. {
  452. Vector3 newPosition = ellipsePositions[0];
  453. newPosition.x -= position.x;
  454. newPosition.y += position.y;
  455. ellipsePositions.Add(newPosition);
  456. }
  457. //ellipsePositions.Add(ellipsePositions[0] + new Vector3(-radius, 0, 0));
  458. foreach (var position in bottomHemispherePositions)
  459. {
  460. Vector3 newPosition = ellipsePositions[0];
  461. newPosition.x -= position.x;
  462. newPosition.y += position.y;
  463. ellipsePositions.Add(newPosition);
  464. }
  465. for (int k = 0; k < ellipsePositions.Count; k++)
  466. {
  467. ellipsePositions[k] = rectTransform.TransformPoint(ellipsePositions[k]);
  468. }
  469. ellipsePositionsList.Add(ellipsePositions);
  470. match.EllipsePositionsList.Add(ellipsePositionsList);
  471. }
  472. }
  473. positions.Add(position0);
  474. positions.Add(position1);
  475. positions.Add(position2);
  476. positions.Add(position3);
  477. positions[0] = rectTransform.TransformPoint(positions[0]);
  478. positions[1] = rectTransform.TransformPoint(positions[1]);
  479. positions[2] = rectTransform.TransformPoint(positions[2]);
  480. positions[3] = rectTransform.TransformPoint(positions[3]);
  481. match.RectanglePositionsList.Add(positions);
  482. if (endCharIdx > lineEndCharacterIndex)
  483. {
  484. break;
  485. }
  486. }
  487. }
  488. //print(SuperlinkMatches.Count);
  489. for (int i = 0; i < SuperlinkMatches.Count; i++)
  490. {
  491. SuperlinkMatch match = SuperlinkMatches[i] as SuperlinkMatch;
  492. //print(match.StartIndex + " " + match.EndIndex);
  493. GetSegments(text, CalculateTextGenerator, match, match.SuperlinkSetting.SuperlinkExcludeChars);
  494. for (int j = 0; j < match.Segments.Count; j++)
  495. {
  496. int startCharIdx = match.Segments[j][0];
  497. int endCharIdx = match.Segments[j][1];
  498. //print(startCharIdx + " " + endCharIdx);
  499. int lineIndex = GetLineIndex(CalculateTextGenerator, startCharIdx);
  500. int lineEndCharacterIndex;
  501. float lineCenterY = GetLineCenterY(lineIndex, CalculateTextGenerator.lineCount);
  502. float lineHeight = CalculateTextGenerator.lines[lineIndex].height;
  503. if (lineIndex != -1)
  504. {
  505. lineEndCharacterIndex = GetLineEndCharacterIndex(CalculateTextGenerator, lineIndex, text.Length);
  506. }
  507. else
  508. {
  509. break;
  510. }
  511. int newEndCharIdx = Mathf.Min(lineEndCharacterIndex, endCharIdx);
  512. List<Vector3> positions = new List<Vector3>();
  513. float lineMaxY = lineCenterY + (lineHeight / 2) * match.SuperlinkSetting.Scale;
  514. float lineMinY = lineCenterY - (lineHeight / 2) * match.SuperlinkSetting.Scale;
  515. Vector3 position0 = vertices[4 + startCharIdx * 6].position;
  516. Vector3 position1 = vertices[2 + newEndCharIdx * 6].position;
  517. Vector3 position2 = position1;
  518. Vector3 position3 = position0;
  519. position0.y = lineMaxY;
  520. position1.y = lineMaxY;
  521. position2.y = lineMinY;
  522. position3.y = lineMinY;
  523. positions.Add(position0);
  524. positions.Add(position1);
  525. positions.Add(position2);
  526. positions.Add(position3);
  527. positions[0] = rectTransform.TransformPoint(positions[0]);
  528. positions[1] = rectTransform.TransformPoint(positions[1]);
  529. positions[2] = rectTransform.TransformPoint(positions[2]);
  530. positions[3] = rectTransform.TransformPoint(positions[3]);
  531. match.RectanglePositionsList.Add(positions);
  532. if (endCharIdx > lineEndCharacterIndex)
  533. {
  534. break;
  535. }
  536. }
  537. }
  538. for (int i = 0; i < AvailableSpriteMatches.Count; i++)
  539. {
  540. SpriteMatch match = (SpriteMatch)AvailableSpriteMatches[i];
  541. Vector3 position0 = match.Positions[0];
  542. Vector3 position1 = match.Positions[1];
  543. Vector3 position2 = match.Positions[2];
  544. Vector3 position3 = match.Positions[3];
  545. UnityEngine.Debug.DrawLine(position0, position1, Color.red, 1);
  546. UnityEngine.Debug.DrawLine(position1, position2, Color.red, 1);
  547. UnityEngine.Debug.DrawLine(position2, position3, Color.red, 1);
  548. UnityEngine.Debug.DrawLine(position3, position0, Color.red, 1);
  549. }
  550. for (int i = 0; i < UnderlineMatches.Count; i++)
  551. {
  552. UnderlineMatch match = (UnderlineMatch)UnderlineMatches[i];
  553. for (int j = 0; j < match.RectanglePositionsList.Count; j++)
  554. {
  555. Vector3 position0 = match.RectanglePositionsList[j][0];
  556. Vector3 position1 = match.RectanglePositionsList[j][1];
  557. Vector3 position2 = match.RectanglePositionsList[j][2];
  558. Vector3 position3 = match.RectanglePositionsList[j][3];
  559. UnityEngine.Debug.DrawLine(position0, position1, Color.blue, 1);
  560. UnityEngine.Debug.DrawLine(position1, position2, Color.blue, 1);
  561. UnityEngine.Debug.DrawLine(position2, position3, Color.blue, 1);
  562. UnityEngine.Debug.DrawLine(position3, position0, Color.blue, 1);
  563. }
  564. for (int j = 0; j < match.EllipsePositionsList.Count; j++)
  565. {
  566. for (int k = 0; k < match.EllipsePositionsList[j].Count; k++)
  567. {
  568. for (int l = 1; l < match.EllipsePositionsList[j][k].Count - 1; l++)
  569. {
  570. Vector3 position0 = match.EllipsePositionsList[j][k][0];
  571. Vector3 position1 = match.EllipsePositionsList[j][k][l + 0];
  572. Vector3 position2 = match.EllipsePositionsList[j][k][l + 1];
  573. UnityEngine.Debug.DrawLine(position0, position1, Color.blue, 1);
  574. UnityEngine.Debug.DrawLine(position1, position2, Color.blue, 1);
  575. UnityEngine.Debug.DrawLine(position2, position0, Color.blue, 1);
  576. }
  577. }
  578. }
  579. }
  580. for (int i = 0; i < SuperlinkMatches.Count; i++)
  581. {
  582. SuperlinkMatch match = (SuperlinkMatch)SuperlinkMatches[i];
  583. for (int j = 0; j < match.RectanglePositionsList.Count; j++)
  584. {
  585. Vector3 position0 = match.RectanglePositionsList[j][0];
  586. Vector3 position1 = match.RectanglePositionsList[j][1];
  587. Vector3 position2 = match.RectanglePositionsList[j][2];
  588. Vector3 position3 = match.RectanglePositionsList[j][3];
  589. UnityEngine.Debug.DrawLine(position0, position1, Color.green, 1);
  590. UnityEngine.Debug.DrawLine(position1, position2, Color.green, 1);
  591. UnityEngine.Debug.DrawLine(position2, position3, Color.green, 1);
  592. UnityEngine.Debug.DrawLine(position3, position0, Color.green, 1);
  593. }
  594. }
  595. }
  596. public void SetContent(string content)
  597. {
  598. Content = content;
  599. text = content;
  600. }
  601. public void ClearMatches()
  602. {
  603. AvailableSpriteMatches = new List<BaseMatch>();
  604. TruncateSpriteMatches = new List<BaseMatch>();
  605. UnderlineMatches = new List<BaseMatch>();
  606. SuperlinkMatches = new List<BaseMatch>();
  607. TransferSpaceMatches = new List<BaseMatch>();
  608. MatchesList = new List<List<BaseMatch>>();
  609. SuperlinkCallbackDictionary = new Dictionary<int, Action<int>>();
  610. }
  611. private bool ParseMatches(ref string newText)
  612. {
  613. bool haveMatch = false;
  614. AvailableSpriteMatches = new List<BaseMatch>();
  615. UnderlineMatches = new List<BaseMatch>();
  616. SuperlinkMatches = new List<BaseMatch>();
  617. TransferSpaceMatches = new List<BaseMatch>();
  618. MatchesList = new List<List<BaseMatch>>
  619. {
  620. AvailableSpriteMatches,
  621. UnderlineMatches,
  622. SuperlinkMatches,
  623. TransferSpaceMatches,
  624. };
  625. newText = ParseTransferSpaceMatches(newText);
  626. newText = ParseOpenCloseMatches(newText);
  627. if (TransferSpaceMatches.Count > 0)
  628. {
  629. haveMatch = true;
  630. }
  631. if (AvailableSpriteMatches.Count > 0)
  632. {
  633. haveMatch = true;
  634. }
  635. if (UnderlineMatches.Count > 0)
  636. {
  637. haveMatch = true;
  638. }
  639. if (SuperlinkMatches.Count > 0)
  640. {
  641. haveMatch = true;
  642. }
  643. return haveMatch;
  644. }
  645. private string ParseTransferSpaceMatches(string newText)
  646. {
  647. string pattern = "\\\\ ";
  648. Match match = Regex.Match(newText, pattern);
  649. while (match.Success)
  650. {
  651. MatchData matchData = new MatchData();
  652. matchData.OpenPatternIndex = match.Index;
  653. matchData.MatchLength = match.Length;
  654. TransferSpaceMatch transferSpaceMatch = new TransferSpaceMatch();
  655. transferSpaceMatch.StartIndex = matchData.OpenPatternIndex;
  656. transferSpaceMatch.EndIndex = matchData.OpenPatternIndex;
  657. TransferSpaceMatches.Add(transferSpaceMatch);
  658. newText = newText.Replace(match.Index, match.Length, TransferSpaceReplaceChar.ToString());
  659. match = Regex.Match(newText, pattern);
  660. }
  661. return newText;
  662. }
  663. private string ParseOpenCloseMatches(string newText)
  664. {
  665. if (OpenPatterns.Count == 0 || ClosePatterns.Count == 0)
  666. {
  667. return newText;
  668. }
  669. if (OpenPatterns.Count != ClosePatterns.Count)
  670. {
  671. return newText;
  672. }
  673. List<string> transferedOpenPatterns = new List<string>();
  674. foreach (var openPattern in OpenPatterns)
  675. {
  676. transferedOpenPatterns.Add(openPattern.GetTransferedPattern());
  677. }
  678. List<string> transferedClosePatterns = new List<string>();
  679. foreach (var closePattern in ClosePatterns)
  680. {
  681. transferedClosePatterns.Add(closePattern.GetTransferedPattern());
  682. }
  683. string orOpenPattern = transferedOpenPatterns.ToOrPattern();
  684. string orClosePattern = transferedClosePatterns.ToOrPattern();
  685. string regexPattern = string.Format("{0}.+{1}", orOpenPattern, orClosePattern);
  686. Match match = Regex.Match(newText, regexPattern, RegexOptions.Singleline);
  687. while (match.Success)
  688. {
  689. Dictionary<string, int> openPatternIndexDictionary = new Dictionary<string, int>();
  690. Dictionary<string, int> closePatternIndexDictionary = new Dictionary<string, int>();
  691. for (int i = 0; i < OpenPatterns.Count; i++)
  692. {
  693. int index = match.Value.LastIndexOf(OpenPatterns[i]);
  694. if (index == -1) continue;
  695. else openPatternIndexDictionary.Add(OpenPatterns[i], index);
  696. }
  697. for (int i = 0; i < ClosePatterns.Count; i++)
  698. {
  699. string closeRegexPattern = ClosePatterns[i].GetTransferedPattern();
  700. Match closePatternMatch = Regex.Match(match.Value, closeRegexPattern);
  701. while (closePatternMatch.Success)
  702. {
  703. if (openPatternIndexDictionary[OpenPatterns[i]] > closePatternMatch.Index)
  704. {
  705. closePatternMatch = closePatternMatch.NextMatch();
  706. }
  707. else
  708. {
  709. closePatternIndexDictionary.Add(ClosePatterns[i], closePatternMatch.Index);
  710. break;
  711. }
  712. }
  713. }
  714. int[] openPatternIndexLength = new int[2];
  715. int[] closePatternIndexLength = new int[2];
  716. int dictionaryIndex = openPatternIndexDictionary.MyMax((pattern, index) => index);
  717. KVPair<string, int> pair = openPatternIndexDictionary.GetAtIndex(dictionaryIndex);
  718. openPatternIndexLength[0] = pair.value;
  719. openPatternIndexLength[1] = pair.key.Length;
  720. pair = closePatternIndexDictionary.GetAtIndex(dictionaryIndex);
  721. closePatternIndexLength[0] = pair.value;
  722. closePatternIndexLength[1] = pair.key.Length;
  723. int openPatternIndex = openPatternIndexLength[0];
  724. int openPatternLength = openPatternIndexLength[1];
  725. int closePatternIndex = closePatternIndexLength[0];
  726. int closePatternLength = closePatternIndexLength[1];
  727. int contentIndex = openPatternIndex + openPatternLength;
  728. int contentLength = closePatternIndex - contentIndex;
  729. int matchLength = closePatternIndex + closePatternLength - openPatternIndex;
  730. string matchValue = match.Value.Substring(openPatternIndex, matchLength);
  731. string openPattern = match.Value.Substring(openPatternIndex, openPatternLength);
  732. string closePattern = match.Value.Substring(closePatternIndex, closePatternLength);
  733. MatchData matchData = new MatchData();
  734. matchData.OpenPatternIndex = openPatternIndex + match.Index;
  735. matchData.OpenPatternLength = openPatternLength;
  736. matchData.ClosePatternIndex = closePatternIndex + match.Index;
  737. matchData.ClosePatternLength = closePatternLength;
  738. matchData.ContentIndex = contentIndex + match.Index;
  739. matchData.ContentLength = contentLength;
  740. matchData.MatchLength = matchLength;
  741. matchData.MatchValue = matchValue;
  742. matchData.OpenPattern = openPattern;
  743. matchData.ClosePattern = closePattern;
  744. ParseResult parseResult = OpenCloseParseFunctionDictionary[openPattern].Invoke(newText, matchData);
  745. for (int i = 0; i < OpenPatterns.Count; i++)
  746. {
  747. if (matchData.OpenPattern != OpenPatterns[i]) continue;
  748. MatchesList[i].Add(parseResult.Match);
  749. for (int j = 0; j < MatchesList.Count; j++)
  750. {
  751. AdjustIndicesByMatch(parseResult.ExtraOffset, parseResult.Match, MatchesList[j]);
  752. }
  753. }
  754. newText = parseResult.NewText;
  755. match = Regex.Match(newText, regexPattern);
  756. }
  757. return newText;
  758. }
  759. private ParseResult ParseSpritePattern(string newText, MatchData matchData)
  760. {
  761. int id = 0;
  762. string name;
  763. string content = newText.Substring(matchData.ContentIndex, matchData.ContentLength);
  764. Match idMatch = Regex.Match(content, IDPattern);
  765. if (idMatch.Success)
  766. {
  767. Match match = Regex.Match(idMatch.Value, "\\d+");
  768. id = int.Parse(match.Value);
  769. name = content.Replace(idMatch.Index, idMatch.Length, "");
  770. }
  771. else
  772. {
  773. name = content;
  774. }
  775. newText = newText.Replace(matchData.OpenPatternIndex, matchData.MatchLength, SpriteReplaceChar.ToString());
  776. SpriteMatch spriteMatch = new SpriteMatch();
  777. spriteMatch.ID = id;
  778. spriteMatch.Name = name;
  779. spriteMatch.SpriteSetting = SpriteSettingDictionary[id];
  780. spriteMatch.MatchData = matchData;
  781. spriteMatch.StartIndex = matchData.OpenPatternIndex;
  782. spriteMatch.EndIndex = matchData.OpenPatternIndex;
  783. ParseResult parseResult = new ParseResult();
  784. parseResult.Match = spriteMatch;
  785. parseResult.ExtraOffset = -matchData.ContentLength + 1;
  786. parseResult.NewText = newText;
  787. return parseResult;
  788. }
  789. private ParseResult ParseUnderlinePattern(string newText, MatchData matchData)
  790. {
  791. newText = newText.Replace(matchData.ClosePatternIndex, matchData.ClosePatternLength, "");
  792. int id = 0;
  793. int extraOffset = 0;
  794. string content = newText.Substring(matchData.ContentIndex, matchData.ContentLength);
  795. Match idMatch = Regex.Match(content, IDPattern);
  796. if (idMatch.Success)
  797. {
  798. Match match = Regex.Match(idMatch.Value, "\\d+");
  799. id = int.Parse(match.Value);
  800. extraOffset = idMatch.Length;
  801. newText = newText.Replace(matchData.ContentIndex + idMatch.Index, idMatch.Length, "");
  802. }
  803. newText = newText.Replace(matchData.OpenPatternIndex, matchData.OpenPatternLength, "");
  804. UnderlineMatch underlineMatch = new UnderlineMatch();
  805. underlineMatch.ID = id;
  806. underlineMatch.UnderlineSetting = UnderlineSettingDictionary[id];
  807. underlineMatch.MatchData = matchData;
  808. underlineMatch.StartIndex = matchData.OpenPatternIndex;
  809. underlineMatch.EndIndex = matchData.OpenPatternIndex + matchData.MatchLength - matchData.OpenPatternLength - matchData.ClosePatternLength - 1 - extraOffset;
  810. //print(newText);
  811. //print(underlineMatch.StartIndex + " " + underlineMatch.EndIndex);
  812. ParseResult parseResult = new ParseResult();
  813. parseResult.Match = underlineMatch;
  814. parseResult.ExtraOffset = extraOffset;
  815. parseResult.NewText = newText;
  816. return parseResult;
  817. }
  818. private ParseResult ParseSuperlinkPattern(string newText, MatchData matchData)
  819. {
  820. newText = newText.Replace(matchData.ClosePatternIndex, matchData.ClosePatternLength, "");
  821. int id = 0;
  822. int extraOffset = 0;
  823. string content = newText.Substring(matchData.ContentIndex, matchData.ContentLength);
  824. Match idMatch = Regex.Match(content, IDPattern);
  825. if (idMatch.Success)
  826. {
  827. Match match = Regex.Match(idMatch.Value, "\\d+");
  828. id = int.Parse(match.Value);
  829. extraOffset = idMatch.Length;
  830. newText = newText.Replace(matchData.ContentIndex + idMatch.Index, idMatch.Length, "");
  831. }
  832. newText = newText.Replace(matchData.OpenPatternIndex, matchData.OpenPatternLength, "");
  833. SuperlinkMatch superlinkMatch = new SuperlinkMatch();
  834. superlinkMatch.ID = id;
  835. superlinkMatch.SuperlinkSetting = SuperlinkSettingDictionary[id];
  836. superlinkMatch.MatchData = matchData;
  837. superlinkMatch.StartIndex = matchData.OpenPatternIndex;
  838. superlinkMatch.EndIndex = matchData.OpenPatternIndex + matchData.MatchLength - matchData.OpenPatternLength - matchData.ClosePatternLength - 1 - extraOffset;
  839. ParseResult parseResult = new ParseResult();
  840. parseResult.Match = superlinkMatch;
  841. parseResult.ExtraOffset = extraOffset;
  842. parseResult.NewText = newText;
  843. return parseResult;
  844. }
  845. private void AddNewOpenCloseMatch(string newText)
  846. {
  847. DelayCall.Call
  848. (
  849. 1,
  850. () =>
  851. {
  852. text = newText;
  853. //ImageManager.Init(this);
  854. //ImageManager.ClearRenderTask();
  855. //ImageManager.RenderSprites(SpriteMatches);
  856. //ImageManager.RenderUnderlines(UnderlineMatches);
  857. //ImageManager.RenderSuperlinks(SuperlinkMatches);
  858. }
  859. );
  860. }
  861. private void FillSpriteMatches(List<BaseMatch> spriteMatches, List<BaseMatch> truncateSpriteMatches, ref string newText/*, bool fillTruncate*/)
  862. {
  863. spriteMatches.MySort((match0, match1) => match1.StartIndex < match0.StartIndex);
  864. float replaceCharWidth = GetCharacterWidth(SpriteReplaceChar);
  865. //bool isTextChanged = false;
  866. //if (!fillTruncate)
  867. //{
  868. /*isTextChanged = */ReplaceAllSpriteMatch(spriteMatches, replaceCharWidth, ref newText);
  869. //}
  870. if (horizontalOverflow == HorizontalWrapMode.Overflow)
  871. {
  872. return;
  873. }
  874. /*isTextChanged = isTextChanged | */CalculateSpriteMatchPosition(spriteMatches, truncateSpriteMatches, replaceCharWidth, ref newText);
  875. //return isTextChanged;
  876. }
  877. private void ReplaceAllSpriteMatch(List<BaseMatch> spriteMatches, float replaceCharWidth, ref string newText)
  878. {
  879. foreach (var match in spriteMatches)
  880. {
  881. SpriteMatch spriteMatch = match as SpriteMatch;
  882. SpriteInfo spriteInfo = SpriteInfoManager.GetSpriteInfo(spriteMatch.Name);
  883. float scaledWidth = replaceCharWidth * 2 * spriteMatch.SpriteSetting.Scale;
  884. float minReplaceWidth = scaledWidth;
  885. if (KerningSolution == KerningSolution.Precalculate)
  886. {
  887. int frontIndex = spriteMatch.StartIndex - 1;
  888. int rearIndex = spriteMatch.EndIndex + 1;
  889. float frontKerning;
  890. float rearKerning;
  891. if (frontIndex < 0)
  892. {
  893. frontKerning = 0;
  894. }
  895. else
  896. {
  897. frontKerning = GetKerning(text[frontIndex], SpriteReplaceChar);
  898. }
  899. if (rearIndex >= text.Length)
  900. {
  901. rearKerning = 0;
  902. }
  903. else
  904. {
  905. rearKerning = GetKerning(SpriteReplaceChar, text[rearIndex]);
  906. }
  907. if (frontKerning < 0)
  908. {
  909. minReplaceWidth -= frontKerning;
  910. }
  911. if (rearKerning < 0)
  912. {
  913. minReplaceWidth -= rearKerning;
  914. }
  915. spriteMatch.FrontKerning = frontKerning;
  916. spriteMatch.RearKerning = rearKerning;
  917. }
  918. int replaceCharCount = Mathf.CeilToInt(minReplaceWidth / replaceCharWidth);
  919. for (int j = 0; j < MatchesList.Count; j++)
  920. {
  921. AdjustIndicesByIndex(replaceCharCount - 1, spriteMatch, MatchesList[j]);
  922. }
  923. StringBuilder stringBuilder = new StringBuilder();
  924. for (int j = 0; j < replaceCharCount; j++)
  925. {
  926. stringBuilder.Append(SpriteReplaceChar);
  927. }
  928. newText = newText.Replace(spriteMatch.StartIndex, spriteMatch.Length, stringBuilder.ToString());
  929. spriteMatch.SpriteInfo = spriteInfo;
  930. spriteMatch.ReplaceWidth = replaceCharCount*replaceCharWidth;
  931. spriteMatch.ScaledWidth = scaledWidth;
  932. spriteMatch.EndIndex += replaceCharCount - 1;
  933. }
  934. }
  935. private void CalculateSpriteMatchPosition(List<BaseMatch> spriteMatches, List<BaseMatch> stashSpriteMatches, float replaceCharWidth, ref string newText/*, bool fillTruncate*/)
  936. {
  937. float changeLineAccuracy = replaceCharWidth/5;
  938. //bool isTextChanged = false;
  939. TextGenerationSettings settings = GetGenerationSettings(rectTransform.rect.size);
  940. settings.textAnchor = alignment;
  941. CalculateTextGenerator = new TextGenerator();
  942. CalculateTextGenerator.Populate(newText, settings);
  943. AdjustVerts(CalculateTextGenerator.verts);
  944. //if (IsSpritesOutOfBound(spriteMatches))
  945. //{
  946. // UnityEngine.Debug.LogWarning("文本框过小");
  947. // if (!fillTruncate)
  948. // {
  949. // StashSpriteMatch(0, spriteMatches, stashSpriteMatches);
  950. // }
  951. // return false;
  952. //}
  953. for (int i = 0; i < spriteMatches.Count; i++)
  954. {
  955. SpriteMatch spriteMatch = spriteMatches[i] as SpriteMatch;
  956. //print(CalculateTextGenerator.lineCount);
  957. int lineIndex = GetLineIndex(CalculateTextGenerator, spriteMatch.StartIndex);
  958. int lineStartCharacterIndex;
  959. int lineEndCharacterIndex;
  960. if (lineIndex != -1)
  961. {
  962. lineStartCharacterIndex = CalculateTextGenerator.lines[lineIndex].startCharIdx;
  963. lineEndCharacterIndex = GetLineEndCharacterIndex(CalculateTextGenerator, lineIndex, newText.Length);
  964. }
  965. else
  966. {
  967. lineStartCharacterIndex = -1;
  968. lineEndCharacterIndex = -1;
  969. }
  970. //int lineCharacterCount = lineEndCharacterIndex - lineStartCharacterIndex;
  971. //print(spriteMatch.EndIndex);
  972. //print(lineEndCharacterIndex);
  973. if (spriteMatch.EndIndex > lineEndCharacterIndex) //被Truncate
  974. {
  975. //if (!fillTruncate)
  976. //{
  977. StashSpriteMatch(i, spriteMatches, stashSpriteMatches);
  978. //}
  979. break;
  980. }
  981. List<BaseMatch> matches = GetMatchesInLine(spriteMatches, CalculateTextGenerator, lineIndex, lineEndCharacterIndex);
  982. if (matches.Count == 1)
  983. {
  984. continue;
  985. }
  986. else if (matches.Count > 1)
  987. {
  988. bool changeLine = false;
  989. if (spriteMatch.ReplaceWidth > rectTransform.rect.width) //图片太大 需要换行
  990. {
  991. if (i < spriteMatches.Count - 1)
  992. {
  993. i++;
  994. spriteMatch = spriteMatches[i] as SpriteMatch;
  995. changeLine = true;
  996. //isTextChanged = true;
  997. }
  998. }
  999. else
  1000. {
  1001. float leftMargin = rectTransform.rect.xMin - CalculateTextGenerator.verts[0 + lineStartCharacterIndex * 4].position.x;
  1002. float rightMargin = CalculateTextGenerator.verts[1 + lineEndCharacterIndex * 4].position.x - rectTransform.rect.xMax;
  1003. float horizontalMargin = CalculateTextGenerator.verts[1 + lineEndCharacterIndex * 4].position.x - CalculateTextGenerator.verts[0 + lineStartCharacterIndex * 4].position.x - rectTransform.rect.width;
  1004. if (alignment == TextAnchor.LowerLeft || alignment == TextAnchor.MiddleLeft || alignment == TextAnchor.UpperLeft)
  1005. {
  1006. if (leftMargin <= 0 && rightMargin > changeLineAccuracy)
  1007. {
  1008. //向右突出
  1009. matches.MySort((match0, match1) => match1.StartIndex > match0.StartIndex);
  1010. float margin = horizontalMargin;
  1011. spriteMatch = GetMarginSpriteMatch(matches, margin, replaceCharWidth) as SpriteMatch;
  1012. i = spriteMatches.IndexOf(spriteMatch);
  1013. changeLine = true;
  1014. //isTextChanged = true;
  1015. }
  1016. }
  1017. else if (alignment == TextAnchor.LowerCenter || alignment == TextAnchor.MiddleCenter || alignment == TextAnchor.UpperCenter)
  1018. {
  1019. if (leftMargin > changeLineAccuracy && rightMargin > changeLineAccuracy)
  1020. {
  1021. //左右同时突出
  1022. matches.MySort((match0, match1) => match1.StartIndex > match0.StartIndex);
  1023. float margin = leftMargin + rightMargin;
  1024. spriteMatch = GetMarginSpriteMatch(matches, margin, replaceCharWidth) as SpriteMatch;
  1025. i = spriteMatches.IndexOf(spriteMatch);
  1026. changeLine = true;
  1027. //isTextChanged = true;
  1028. }
  1029. else if (leftMargin <= 0 && rightMargin > changeLineAccuracy)
  1030. {
  1031. //向右突出
  1032. matches.MySort((match0, match1) => match1.StartIndex > match0.StartIndex);
  1033. float margin = horizontalMargin;
  1034. spriteMatch = GetMarginSpriteMatch(matches, margin, replaceCharWidth) as SpriteMatch;
  1035. i = spriteMatches.IndexOf(spriteMatch);
  1036. changeLine = true;
  1037. //isTextChanged = true;
  1038. }
  1039. }
  1040. else if (alignment == TextAnchor.LowerRight || alignment == TextAnchor.MiddleRight || alignment == TextAnchor.UpperRight)
  1041. {
  1042. if (leftMargin > changeLineAccuracy && rightMargin <= 0)
  1043. {
  1044. //向左突出
  1045. matches.MySort((match0, match1) => match1.StartIndex > match0.StartIndex);
  1046. float margin = leftMargin;
  1047. spriteMatch = GetMarginSpriteMatch(matches, margin, replaceCharWidth) as SpriteMatch;
  1048. i = spriteMatches.IndexOf(spriteMatch);
  1049. changeLine = true;
  1050. //isTextChanged = true;
  1051. }
  1052. else if (leftMargin <= 0 && rightMargin > changeLineAccuracy)
  1053. {
  1054. //向右突出
  1055. matches.MySort((match0, match1) => match1.StartIndex > match0.StartIndex);
  1056. float margin = horizontalMargin;
  1057. spriteMatch = GetMarginSpriteMatch(matches, margin, replaceCharWidth) as SpriteMatch;
  1058. i = spriteMatches.IndexOf(spriteMatch);
  1059. changeLine = true;
  1060. //isTextChanged = true;
  1061. }
  1062. }
  1063. }
  1064. if (changeLine)
  1065. {
  1066. lineIndex++;
  1067. if (lineIndex < GetMaxLineCount()) //换行后不被Truncate
  1068. {
  1069. newText = newText.Insert(spriteMatch.StartIndex, "\n");
  1070. for (int j = 0; j < MatchesList.Count; j++)
  1071. {
  1072. AdjustIndicesByIndex(1, spriteMatch, MatchesList[j]);
  1073. }
  1074. spriteMatch.StartIndex += 1;
  1075. spriteMatch.EndIndex += 1;
  1076. CalculateTextGenerator = new TextGenerator();
  1077. CalculateTextGenerator.Populate(newText, settings);
  1078. AdjustVerts(CalculateTextGenerator.verts);
  1079. }
  1080. }
  1081. }
  1082. //if (fillTruncate)
  1083. //{
  1084. // stashSpriteMatches.Add(spriteMatch);
  1085. // spriteMatches.Remove(spriteMatch);
  1086. //}
  1087. }
  1088. //return isTextChanged;
  1089. }
  1090. //private bool IsSpritesOutOfBound(List<BaseMatch> spriteMatches)
  1091. //{
  1092. // for (int i = 0; i < spriteMatches.Count; i++)
  1093. // {
  1094. // SpriteMatch spriteMatch = spriteMatches[i] as SpriteMatch;
  1095. // if (spriteMatch.ReplaceWidth > rectTransform.rect.width)
  1096. // {
  1097. // return true;
  1098. // }
  1099. // }
  1100. // return false;
  1101. //}
  1102. private void StashSpriteMatch(int startIndex, List<BaseMatch> spriteMatches, List<BaseMatch> stashSpriteMatches)
  1103. {
  1104. for (int i = startIndex; i < spriteMatches.Count; i++)
  1105. {
  1106. stashSpriteMatches.Add(spriteMatches[i]);
  1107. spriteMatches.Remove(spriteMatches[i]);
  1108. i--;
  1109. }
  1110. }
  1111. private List<BaseMatch> GetMatchesInLine(List<BaseMatch> matches, TextGenerator textGenerator, int lineIndex, int endCharacterIndex)
  1112. {
  1113. List<BaseMatch> result = new List<BaseMatch>();
  1114. foreach (var match in matches)
  1115. {
  1116. if (match.StartIndex > endCharacterIndex)
  1117. {
  1118. continue;
  1119. }
  1120. int matchLineIndex = GetLineIndex(textGenerator, match.StartIndex);
  1121. if (matchLineIndex == lineIndex)
  1122. {
  1123. result.Add(match);
  1124. }
  1125. }
  1126. return result;
  1127. }
  1128. private BaseMatch GetMarginSpriteMatch(List<BaseMatch> matches, float margin, float replaceCharWidth)
  1129. {
  1130. foreach (var match in matches)
  1131. {
  1132. margin -= replaceCharWidth * match.Length;
  1133. if (margin <= 0)
  1134. {
  1135. return match;
  1136. }
  1137. }
  1138. throw new Exception();
  1139. }
  1140. //private bool IsCharacterTruncated(TextGenerator textGenerator, int characterIndex)
  1141. //{
  1142. // print(textGenerator.characterCount - 1);
  1143. // print(characterIndex + 1);
  1144. // if (textGenerator.characterCount - 1 < characterIndex + 1)
  1145. // {
  1146. // return true;
  1147. // }
  1148. // else
  1149. // {
  1150. // return false;
  1151. // }
  1152. //}
  1153. private void HandleTransferSpaceMatch(VertexHelper toFill, List<UIVertex> vertices)
  1154. {
  1155. foreach (var transferSpaceMatch in TransferSpaceMatches)
  1156. {
  1157. int index0 = 0 + transferSpaceMatch.StartIndex * 4;
  1158. int index1 = 1 + transferSpaceMatch.EndIndex * 4;
  1159. int index2 = 2 + transferSpaceMatch.EndIndex * 4;
  1160. int index3 = 3 + transferSpaceMatch.StartIndex * 4;
  1161. UIVertex vertex0 = vertices[index0];
  1162. UIVertex vertex1 = vertices[index1];
  1163. UIVertex vertex2 = vertices[index2];
  1164. UIVertex vertex3 = vertices[index3];
  1165. vertex0.color = new Color32(0, 0, 0, 0);
  1166. vertex1.color = new Color32(0, 0, 0, 0);
  1167. vertex2.color = new Color32(0, 0, 0, 0);
  1168. vertex3.color = new Color32(0, 0, 0, 0);
  1169. vertices[index0] = vertex0;
  1170. vertices[index1] = vertex1;
  1171. vertices[index2] = vertex2;
  1172. vertices[index3] = vertex3;
  1173. toFill.SetUIVertex(vertex0, index0);
  1174. toFill.SetUIVertex(vertex1, index1);
  1175. toFill.SetUIVertex(vertex2, index2);
  1176. toFill.SetUIVertex(vertex3, index3);
  1177. }
  1178. }
  1179. public string GetUnparsedText()
  1180. {
  1181. List<BaseMatch> matches = new List<BaseMatch>();
  1182. matches.AddRange(TransferSpaceMatches);
  1183. matches.AddRange(AvailableSpriteMatches);
  1184. matches.AddRange(UnderlineMatches);
  1185. matches.AddRange(SuperlinkMatches);
  1186. matches.MySort((match0, match1) => match1.StartIndex > match0.StartIndex);
  1187. string result = text;
  1188. foreach (var baseMatch in matches)
  1189. {
  1190. if (baseMatch is TransferSpaceMatch)
  1191. {
  1192. result = result.Insert(baseMatch.StartIndex, "\\");
  1193. }
  1194. else
  1195. {
  1196. string openPattern = baseMatch.MatchData.OpenPattern;
  1197. string idPattern = IDPattern.Replace("\\d+", baseMatch.ID.ToString());
  1198. idPattern = idPattern.Replace("\\", "");
  1199. string closePattern = baseMatch.MatchData.ClosePattern;
  1200. result = result.Insert(baseMatch.StartIndex + baseMatch.EndIndex, idPattern + closePattern);
  1201. result = result.Insert(baseMatch.StartIndex, openPattern);
  1202. }
  1203. }
  1204. return result;
  1205. }
  1206. private Vector3[] GetLocalCorners()
  1207. {
  1208. Vector3[] corners = new Vector3[4];
  1209. rectTransform.GetLocalCorners(corners);
  1210. return corners;
  1211. }
  1212. private Vector3[] GetWorldCorners()
  1213. {
  1214. Vector3[] corners = new Vector3[4];
  1215. rectTransform.GetWorldCorners(corners);
  1216. return corners;
  1217. }
  1218. private float GetKerning(char c0, char c1)
  1219. {
  1220. TextGenerator textGenerator = new TextGenerator(0);
  1221. textGenerator.Populate(string.Format("{0}{1}", c0, c1), GetGenerationSettings(rectTransform.rect.size));
  1222. //AdjustVerts(textGenerator.verts);
  1223. float kerning = textGenerator.verts[4].position.x - textGenerator.verts[1].position.x;
  1224. kerning /= canvas.scaleFactor;
  1225. return kerning;
  1226. //return textGenerator.verts[4].position.x - textGenerator.verts[1].position.x;
  1227. }
  1228. private float GetCharacterHeight(char c)
  1229. {
  1230. TextGenerator textGenerator = new TextGenerator(0);
  1231. textGenerator.Populate(c.ToString(), GetGenerationSettings(rectTransform.rect.size));
  1232. //AdjustVerts(textGenerator.verts);
  1233. float height = textGenerator.verts[0].position.y - textGenerator.verts[2].position.y;
  1234. height /= canvas.scaleFactor;
  1235. return height;
  1236. //return textGenerator.verts[0].position.y - textGenerator.verts[2].position.y;
  1237. }
  1238. private float GetCharacterWidth(char c)
  1239. {
  1240. TextGenerator textGenerator = new TextGenerator(0);
  1241. textGenerator.Populate(c.ToString(), GetGenerationSettings(rectTransform.rect.size));
  1242. //AdjustVerts(textGenerator.verts);
  1243. float width = textGenerator.verts[1].position.x - textGenerator.verts[0].position.x;
  1244. width /= canvas.scaleFactor;
  1245. return width;
  1246. //return textGenerator.verts[1].position.x - textGenerator.verts[0].position.x;
  1247. }
  1248. public float GetPenPositionY(int lineIndex, int lineCount)
  1249. {
  1250. StringBuilder stringBuilder = new StringBuilder();
  1251. for (int i = 0; i < lineCount; i++)
  1252. {
  1253. stringBuilder.Append(CalculateReferenceChar);
  1254. if (i < lineCount - 1)
  1255. {
  1256. stringBuilder.Append("\n");
  1257. }
  1258. }
  1259. TextGenerator textGenerator = new TextGenerator();
  1260. textGenerator.Populate(stringBuilder.ToString(), GetGenerationSettings(rectTransform.rect.size));
  1261. AdjustVerts(textGenerator.verts);
  1262. return textGenerator.verts[2 + lineIndex*8].position.y;
  1263. }
  1264. public float GetLineCenterY(int lineIndex, int lineCount)
  1265. {
  1266. StringBuilder stringBuilder = new StringBuilder();
  1267. for (int i = 0; i < lineCount; i++)
  1268. {
  1269. stringBuilder.Append(CalculateReferenceChar);
  1270. if (i < lineCount - 1)
  1271. {
  1272. stringBuilder.Append("\n");
  1273. }
  1274. }
  1275. TextGenerator textGenerator = new TextGenerator();
  1276. textGenerator.Populate(stringBuilder.ToString(), GetGenerationSettings(rectTransform.rect.size));
  1277. AdjustVerts(textGenerator.verts);
  1278. return (textGenerator.verts[0 + lineIndex*8].position.y + textGenerator.verts[2 + lineIndex*8].position.y)/2;
  1279. }
  1280. public int GetLineIndex(TextGenerator textGenerator, int charIndex)
  1281. {
  1282. for (int i = 0; i < textGenerator.lines.Count; i++)
  1283. {
  1284. if (charIndex >= textGenerator.lines.Back(i).startCharIdx)
  1285. {
  1286. return textGenerator.lines.Count - 1 - i;
  1287. }
  1288. }
  1289. return -1;
  1290. }
  1291. public int GetMaxLineCount()
  1292. {
  1293. TextGenerationSettings settings = GetGenerationSettings(rectTransform.rect.size);
  1294. settings.textAnchor = alignment;
  1295. CalculateTextGenerator = new TextGenerator();
  1296. int lineCount = 0;
  1297. StringBuilder stringBuilder = new StringBuilder();
  1298. while (CalculateTextGenerator.GetPreferredHeight(stringBuilder.ToString(), settings) / canvas.scaleFactor < rectTransform.rect.height)
  1299. {
  1300. lineCount++;
  1301. stringBuilder.Append("\n");
  1302. }
  1303. return lineCount;
  1304. }
  1305. public int GetLineEndCharacterIndex(TextGenerator textGenerator, int lineIndex, int realCharacterCount)
  1306. {
  1307. if (lineIndex >= textGenerator.lines.Count)
  1308. {
  1309. throw new Exception();
  1310. }
  1311. if (textGenerator.lines.Count == 1 || lineIndex == textGenerator.lines.Count - 1)
  1312. {
  1313. if (textGenerator.characterCount - 1 == realCharacterCount) //TextGenerator会自动在结尾添加换行符
  1314. {
  1315. return realCharacterCount - 1;
  1316. }
  1317. else
  1318. {
  1319. return textGenerator.characterCount - 1;
  1320. }
  1321. }
  1322. else
  1323. {
  1324. return textGenerator.lines[lineIndex + 1].startCharIdx - 1;
  1325. }
  1326. }
  1327. public int GetLineCharacterCount(TextGenerator textGenerator, int lineIndex)
  1328. {
  1329. if (lineIndex >= textGenerator.lines.Count)
  1330. {
  1331. throw new Exception();
  1332. }
  1333. if (textGenerator.lines.Count == 1)
  1334. {
  1335. return textGenerator.characterCount;
  1336. }
  1337. if (lineIndex == textGenerator.lines.Count - 1)
  1338. {
  1339. return textGenerator.characterCount - textGenerator.lines.Back(0).startCharIdx;
  1340. }
  1341. else
  1342. {
  1343. return textGenerator.lines[lineIndex + 1].startCharIdx - textGenerator.lines[lineIndex].startCharIdx;
  1344. }
  1345. }
  1346. public float GetLineMaxY(TextGenerator textGenerator, int lineIndex)
  1347. {
  1348. float lineCenterY = GetLineCenterY(lineIndex, textGenerator.lineCount);
  1349. float lineHeight = textGenerator.lines[lineIndex].height;
  1350. return lineCenterY + lineHeight/2;
  1351. }
  1352. public float GetLineMinY(TextGenerator textGenerator, int lineIndex)
  1353. {
  1354. float lineCenterY = GetLineCenterY(lineIndex, textGenerator.lineCount);
  1355. float lineHeight = textGenerator.lines[lineIndex].height;
  1356. return lineCenterY - lineHeight/2;
  1357. }
  1358. public float GetLineTopY(TextGenerator textGenerator, int lineIndex)
  1359. {
  1360. return textGenerator.lines[lineIndex].topY;
  1361. }
  1362. public float GetLineBottomY(TextGenerator textGenerator, int lineIndex)
  1363. {
  1364. return textGenerator.lines[lineIndex].topY - textGenerator.lines[lineIndex].height;
  1365. }
  1366. public bool IsSameLine(TextGenerator textGenerator, int charIndex0, int charIndex1)
  1367. {
  1368. if (textGenerator.lines.Count == 1)
  1369. {
  1370. return true;
  1371. }
  1372. else
  1373. {
  1374. for (int i = 0; i < textGenerator.lines.Count - 1; i++)
  1375. {
  1376. if ((charIndex0 >= textGenerator.lines[i].startCharIdx && charIndex0 < textGenerator.lines[i + 1].startCharIdx) && charIndex1 >= textGenerator.lines[i + 1].startCharIdx)
  1377. {
  1378. return false;
  1379. }
  1380. }
  1381. return true;
  1382. }
  1383. }
  1384. private void AdjustVerts(IList<UIVertex> verts) //取自UGUI源代码
  1385. {
  1386. float unitsPerPixel = 1/pixelsPerUnit;
  1387. int vertCount = verts.Count - 4;
  1388. Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y)*unitsPerPixel;
  1389. roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset;
  1390. if (roundingOffset != Vector2.zero)
  1391. {
  1392. for (int i = 0; i < vertCount; ++i)
  1393. {
  1394. UIVertex vertex = verts[i];
  1395. vertex.position *= unitsPerPixel;
  1396. vertex.position.x += roundingOffset.x;
  1397. vertex.position.y += roundingOffset.y;
  1398. verts[i] = vertex;
  1399. }
  1400. }
  1401. else
  1402. {
  1403. for (int i = 0; i < vertCount; ++i)
  1404. {
  1405. UIVertex vertex = verts[i];
  1406. vertex.position *= unitsPerPixel;
  1407. verts[i] = vertex;
  1408. }
  1409. }
  1410. }
  1411. private void AdjustIndicesByIndex(int indexOffset, BaseMatch referenceMatch, List<BaseMatch> adjusteeMatches)
  1412. {
  1413. for (int i = 0; i < adjusteeMatches.Count; i++)
  1414. {
  1415. BaseMatch adjusteeMatch = adjusteeMatches[i];
  1416. if (referenceMatch == adjusteeMatch) continue;
  1417. if (referenceMatch.StartIndex < adjusteeMatch.StartIndex) //referenceIndex-adjusteeMatch-adjusteeMatch
  1418. {
  1419. adjusteeMatch.StartIndex += indexOffset;
  1420. adjusteeMatch.EndIndex += indexOffset;
  1421. }
  1422. else if (referenceMatch.StartIndex < adjusteeMatch.EndIndex) //adjusteeMatch-referenceIndex-adjusteeMatch
  1423. {
  1424. adjusteeMatch.EndIndex += indexOffset;
  1425. }
  1426. }
  1427. }
  1428. private void AdjustIndicesByMatch(int extraOffset, BaseMatch referenceMatch, List<BaseMatch> adjusteeMatches)
  1429. {
  1430. for (int i = 0; i < adjusteeMatches.Count; i++)
  1431. {
  1432. BaseMatch adjusteeMatch = adjusteeMatches[i];
  1433. if (referenceMatch == adjusteeMatch) continue;
  1434. if (referenceMatch.StartIndex < adjusteeMatch.EndIndex) //排除 adjusteeMatch...adjusteeMatch...refeMatch-refeMatch
  1435. {
  1436. if (referenceMatch.EndIndex < adjusteeMatch.StartIndex) //refeMatch-refeMatch...adjusteeMatch-adjusteeMatch
  1437. {
  1438. int indexOffset = -referenceMatch.MatchData.OpenPatternLength - referenceMatch.MatchData.ClosePatternLength + extraOffset;
  1439. adjusteeMatch.StartIndex += indexOffset;
  1440. adjusteeMatch.EndIndex += indexOffset;
  1441. }
  1442. else if (referenceMatch.EndIndex < adjusteeMatch.EndIndex) //refeMatch...adjusteeMatch...refeMatch...adjusteeMatch
  1443. {
  1444. int indexOffset = -referenceMatch.MatchData.ClosePatternLength + extraOffset;
  1445. adjusteeMatch.StartIndex += indexOffset;
  1446. adjusteeMatch.EndIndex += indexOffset;
  1447. }
  1448. else if (referenceMatch.EndIndex > adjusteeMatch.EndIndex) //adjusteeMatch...refeMatch...adjusteeMatch...refeMatch
  1449. {
  1450. int indexOffset = -referenceMatch.MatchData.OpenPatternLength + extraOffset;
  1451. adjusteeMatch.StartIndex += indexOffset;
  1452. adjusteeMatch.EndIndex += indexOffset;
  1453. }
  1454. //不应该出现的情况refeMatch...adjusteeMatch-adjusteeMatch...refeMatch adjusteeMatch...refeMatch...refeMatch...adjusteeMatch
  1455. }
  1456. }
  1457. }
  1458. public void GetSegments<T>(string newText, TextGenerator textGenerator, T match, List<char> excludeChars) where T : SegmentMatch
  1459. {
  1460. //print(excludeChars.Count);
  1461. if (textGenerator.lines.Count == 1)
  1462. {
  1463. match.Segments.Add(new List<int> {match.StartIndex, match.EndIndex});
  1464. }
  1465. else
  1466. {
  1467. int endLineIndex;
  1468. int startLineIndex;
  1469. for (int i = 0; i < textGenerator.lines.Count; i++)
  1470. {
  1471. startLineIndex = textGenerator.lines.Count - 1 - i;
  1472. if (match.StartIndex >= textGenerator.lines[startLineIndex].startCharIdx)
  1473. {
  1474. if (startLineIndex == textGenerator.lines.Count - 1)
  1475. {
  1476. match.Segments.Add(new List<int> {match.StartIndex, match.EndIndex});
  1477. goto jumpOut;
  1478. }
  1479. else
  1480. {
  1481. if (match.EndIndex >= textGenerator.lines.Back(0).startCharIdx)
  1482. {
  1483. endLineIndex = textGenerator.lines.Count - 1;
  1484. }
  1485. else
  1486. {
  1487. for (int j = startLineIndex; j < textGenerator.lines.Count; j++)
  1488. {
  1489. if (match.EndIndex < textGenerator.lines[j + 1].startCharIdx)
  1490. {
  1491. if (j == startLineIndex)
  1492. {
  1493. match.Segments.Add(new List<int> {match.StartIndex, match.EndIndex});
  1494. goto jumpOut;
  1495. }
  1496. else
  1497. {
  1498. endLineIndex = j;
  1499. goto segment;
  1500. }
  1501. }
  1502. }
  1503. throw new Exception();
  1504. }
  1505. segment:
  1506. int segmentCount = endLineIndex - startLineIndex + 1;
  1507. match.Segments.Add(new List<int> {match.StartIndex, textGenerator.lines[startLineIndex + 1].startCharIdx - 1}); //第一段
  1508. match.Segments.Add(new List<int> {textGenerator.lines[endLineIndex].startCharIdx, match.EndIndex}); //最后一段
  1509. for (int k = 0; k < segmentCount - 2; k++)
  1510. {
  1511. match.Segments.Add(new List<int> {textGenerator.lines[startLineIndex + 1 + k].startCharIdx, textGenerator.lines[startLineIndex + 2 + k].startCharIdx - 1});
  1512. }
  1513. goto jumpOut;
  1514. }
  1515. }
  1516. }
  1517. }
  1518. jumpOut:
  1519. //for (int i = 0; i < match.Segments.Count; i++)
  1520. //{
  1521. // Debug.LogWarning(match.Segments[i][0] + "\t" + match.Segments[i][1]);
  1522. //}
  1523. exclude:
  1524. for (int i = 0; i < match.Segments.Count; i++)
  1525. {
  1526. int startIndex = match.Segments[i][0];
  1527. int endIndex = match.Segments[i][1];
  1528. for (int j = startIndex; j <= endIndex; j++)
  1529. {
  1530. //print((int)newText[j]);
  1531. if (excludeChars.Contains(newText[j]))
  1532. {
  1533. if (j == startIndex)
  1534. {
  1535. //Debug.Log("start " + match.Segments[i][0] + "\t" + match.Segments[i][1]);
  1536. //Debug.Log(j);
  1537. //newText = newText.Remove(startIndex, 1);
  1538. match.Segments[i][0] = startIndex + 1;
  1539. //Debug.Log("start " + match.Segments[i][0] + "\t" + match.Segments[i][1]);
  1540. }
  1541. else if (j == endIndex)
  1542. {
  1543. //Debug.Log("end " + match.Segments[i][0] + "\t" + match.Segments[i][1]);
  1544. //Debug.Log(j);
  1545. //newText = newText.Remove(endIndex, 1);
  1546. match.Segments[i][1] = endIndex - 1;
  1547. //Debug.Log("end " + match.Segments[i][0] + "\t" + match.Segments[i][1]);
  1548. }
  1549. else
  1550. {
  1551. //Debug.Log(j);
  1552. //newText = newText.Remove(j, 1);
  1553. //Debug.Log("remove " + match.Segments[i][0] + "\t" + match.Segments[i][1]);
  1554. match.Segments.RemoveAt(i);
  1555. match.Segments.Insert(0, new List<int> {startIndex, j - 1});
  1556. //Debug.Log("add " + match.Segments[0][0] + "\t" + match.Segments[0][1]);
  1557. match.Segments.Insert(0, new List<int> {j + 1, endIndex});
  1558. //Debug.Log("add " + match.Segments[0][0] + "\t" + match.Segments[0][1]);
  1559. }
  1560. goto exclude;
  1561. }
  1562. }
  1563. }
  1564. for (int i = 0; i < match.Segments.Count; i++)
  1565. {
  1566. if (match.Segments[i][1] < match.Segments[i][0])
  1567. {
  1568. match.Segments.RemoveAt(i--);
  1569. }
  1570. }
  1571. //for (int i = 0; i < match.Segments.Count; i++)
  1572. //{
  1573. // Debug.Log(match.Segments[i][0] + "\t" + match.Segments[i][1]);
  1574. //}
  1575. }
  1576. private int GetVerticalBestfitFontSize(string newText)
  1577. {
  1578. int antiCrush = 0;
  1579. TextGenerationSettings settings = GetGenerationSettings(rectTransform.rect.size);
  1580. List<int> leftSizes = new List<int> {resizeTextMinSize};
  1581. List<int> rightSizes = new List<int> {resizeTextMaxSize};
  1582. settings.fontSize = (leftSizes[0] + rightSizes[0])/2;
  1583. while (true)
  1584. {
  1585. if (antiCrush++ > 300)
  1586. {
  1587. throw new Exception("Crush");
  1588. }
  1589. float preferredHeight = cachedTextGenerator.GetPreferredHeight(newText, settings);
  1590. if (preferredHeight > rectTransform.rect.size.y*canvas.scaleFactor)
  1591. {
  1592. rightSizes.Add(settings.fontSize);
  1593. settings.fontSize = (leftSizes[leftSizes.Count - 1] + settings.fontSize)/2;
  1594. }
  1595. else if (preferredHeight < rectTransform.rect.size.y*canvas.scaleFactor)
  1596. {
  1597. if (leftSizes.Contains(settings.fontSize))
  1598. {
  1599. return settings.fontSize;
  1600. }
  1601. else
  1602. {
  1603. leftSizes.Add(settings.fontSize);
  1604. }
  1605. settings.fontSize = (rightSizes[rightSizes.Count - 1] + settings.fontSize)/2;
  1606. }
  1607. else
  1608. {
  1609. return settings.fontSize;
  1610. }
  1611. }
  1612. }
  1613. public void ApplyVerticalBestfitSize()
  1614. {
  1615. resizeTextMinSize = MinSize;
  1616. resizeTextMaxSize = MaxSize;
  1617. }
  1618. public void DisableOriginBestfit()
  1619. {
  1620. resizeTextForBestFit = false;
  1621. }
  1622. public void EnableVerticalBestfit()
  1623. {
  1624. UseOriginBestfit = resizeTextForBestFit;
  1625. MinSize = resizeTextMinSize;
  1626. MaxSize = resizeTextMaxSize;
  1627. UseVerticalBestfit = true;
  1628. VerticalBestfitDirty = true;
  1629. DisableOriginBestfit();
  1630. }
  1631. public void DisableVerticalBestfit()
  1632. {
  1633. resizeTextForBestFit = UseOriginBestfit;
  1634. UseVerticalBestfit = false;
  1635. }
  1636. private bool ParseAndFillMatches(ref string newText)
  1637. {
  1638. bool haveMatch = ParseMatches(ref newText);
  1639. if (haveMatch)
  1640. {
  1641. FillSpriteMatches(AvailableSpriteMatches, TruncateSpriteMatches, ref newText);
  1642. }
  1643. return haveMatch;
  1644. }
  1645. public void EnableDebugMode()
  1646. {
  1647. //TextGenerationSettings settings = GetGenerationSettings(rectTransform.rect.size);
  1648. //settings.textAnchor = alignment;
  1649. //CalculateTextGenerator = new TextGenerator();
  1650. //print(CalculateTextGenerator.GetPreferredHeight("", settings) / canvas.scaleFactor);
  1651. //print(cachedTextGenerator.characterCount);
  1652. //print(cachedTextGenerator.lineCount);
  1653. Debug = true;
  1654. Content = text;
  1655. SetVerticesDirty();
  1656. SetLayoutDirty();
  1657. //string newText = Content;
  1658. //if (ParseAndFillMatches(ref newText))
  1659. //{
  1660. // AddNewOpenCloseMatch(newText);
  1661. //}
  1662. }
  1663. public void DisableDebugMode()
  1664. {
  1665. Debug = false;
  1666. text = Content;
  1667. ClearMatches();
  1668. ImageManager.ClearRenderTask();
  1669. }
  1670. public void OnPointerClick(PointerEventData eventData)
  1671. {
  1672. //Vector3 clickPosition = eventData.position;
  1673. //Debug.Log(clickPosition);
  1674. OnPointerClick(eventData.position);
  1675. }
  1676. private Dictionary<int, List<List<Vector3>>> SuperlinkPositionsDictionary = new Dictionary<int, List<List<Vector3>>>();
  1677. public void OnPointerClick(Vector3 worldPosition)
  1678. {
  1679. SuperlinkPositionsDictionary = new Dictionary<int, List<List<Vector3>>>();
  1680. foreach (var match in SuperlinkMatches)
  1681. {
  1682. SuperlinkMatch superlinkMatch = (SuperlinkMatch) match;
  1683. SuperlinkPositionsDictionary.Add(superlinkMatch.ID, superlinkMatch.RectanglePositionsList);
  1684. }
  1685. Vector3 clickPosition = worldPosition;
  1686. //Vector3 clickPosition = rectTransform.InverseTransformPoint(worldPosition);
  1687. foreach (var kv in SuperlinkPositionsDictionary)
  1688. {
  1689. foreach (var positions in kv.Value)
  1690. {
  1691. float minX = positions.MyMin(vector => vector.x).x;
  1692. float maxX = positions.MyMax(vector => vector.x).x;
  1693. float minY = positions.MyMin(vector => vector.y).y;
  1694. float maxY = positions.MyMax(vector => vector.y).y;
  1695. //UnityEngine.Debug.Log(clickPosition);
  1696. //UnityEngine.Debug.Log(minX + " " + maxX + " " + minY + " " + maxY);
  1697. if ((minX <= clickPosition.x && clickPosition.x <= maxX) && (minY <= clickPosition.y && clickPosition.y <= maxY))
  1698. {
  1699. if (SuperlinkCallbackDictionary.ContainsKey(kv.Key))
  1700. {
  1701. SuperlinkCallbackDictionary[kv.Key].Invoke(kv.Key);
  1702. }
  1703. else
  1704. {
  1705. UnityEngine.Debug.LogWarning(string.Format("没有找到事件 id : {0}", kv.Key));
  1706. }
  1707. }
  1708. }
  1709. }
  1710. }
  1711. }
  1712. }