RichText.cs 77 KB

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