|
@@ -0,0 +1,1842 @@
|
|
|
+using UnityEngine.EventSystems;
|
|
|
+
|
|
|
+namespace textUtility
|
|
|
+{
|
|
|
+
|
|
|
+
|
|
|
+ using System;
|
|
|
+ using System.Collections.Generic;
|
|
|
+ using System.Text;
|
|
|
+ using System.Text.RegularExpressions;
|
|
|
+ using UnityEditor.VisualStudioIntegration;
|
|
|
+ using UnityEngine;
|
|
|
+ using UnityEngine.UI;
|
|
|
+
|
|
|
+ [Serializable]
|
|
|
+ public class RichText : Text, IPointerClickHandler
|
|
|
+ {
|
|
|
+ private class ParseResult
|
|
|
+ {
|
|
|
+ public int ExtraOffset;
|
|
|
+ public string NewText;
|
|
|
+ public BaseMatch Match;
|
|
|
+ }
|
|
|
+
|
|
|
+ #region Config
|
|
|
+
|
|
|
+ private List<string> OpenPatterns
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (!openPatterns.IsAvailable())
|
|
|
+ {
|
|
|
+ openPatterns = new List<string>();
|
|
|
+ openPatterns.Add(SpriteOpenPattern);
|
|
|
+ openPatterns.Add(UnderlineOpenPattern);
|
|
|
+ openPatterns.Add(SuperlinkOpenPattern);
|
|
|
+ }
|
|
|
+ return openPatterns;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private List<string> openPatterns;
|
|
|
+
|
|
|
+ private List<string> ClosePatterns
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (!closePatterns.IsAvailable())
|
|
|
+ {
|
|
|
+ closePatterns = new List<string>();
|
|
|
+ closePatterns.Add(SpriteClosePattern);
|
|
|
+ closePatterns.Add(UnderlineClosePattern);
|
|
|
+ closePatterns.Add(SuperlinkClosePattern);
|
|
|
+ }
|
|
|
+ return closePatterns;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private List<string> closePatterns;
|
|
|
+
|
|
|
+ private Dictionary<string, Func<string, MatchData, ParseResult>> OpenCloseParseFunctionDictionary
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (!openCloseParseFunctionDictionary.IsAvailable())
|
|
|
+ {
|
|
|
+ openCloseParseFunctionDictionary = new Dictionary<string, Func<string, MatchData, ParseResult>>();
|
|
|
+ openCloseParseFunctionDictionary.Add(SpriteOpenPattern, ParseSpritePattern);
|
|
|
+ openCloseParseFunctionDictionary.Add(UnderlineOpenPattern, ParseUnderlinePattern);
|
|
|
+ openCloseParseFunctionDictionary.Add(SuperlinkOpenPattern, ParseSuperlinkPattern);
|
|
|
+ }
|
|
|
+ return openCloseParseFunctionDictionary;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private Dictionary<string, Func<string, MatchData, ParseResult>> openCloseParseFunctionDictionary;
|
|
|
+
|
|
|
+ public bool SpriteFoldout;
|
|
|
+ public string SpriteOpenPattern = "<(";
|
|
|
+ public string SpriteClosePattern = ")>";
|
|
|
+ public char SpriteReplaceChar = ' ';
|
|
|
+ public List<SpriteSetting> SpriteSettings; //todo 可能为空
|
|
|
+ private Dictionary<int, SpriteSetting> SpriteSettingDictionary
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (!spriteSettingDictionary.IsAvailable())
|
|
|
+ {
|
|
|
+ spriteSettingDictionary = new Dictionary<int, SpriteSetting>();
|
|
|
+ foreach (var item in SpriteSettings)
|
|
|
+ {
|
|
|
+ spriteSettingDictionary.Add(item.ID, item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return spriteSettingDictionary;
|
|
|
+ }
|
|
|
+ set { spriteSettingDictionary = value; }
|
|
|
+ }
|
|
|
+ private Dictionary<int, SpriteSetting> spriteSettingDictionary;
|
|
|
+ private List<BaseMatch> AvailableSpriteMatches = new List<BaseMatch>();
|
|
|
+ private List<BaseMatch> TruncateSpriteMatches = new List<BaseMatch>();
|
|
|
+
|
|
|
+ public bool UnderlineFoldout;
|
|
|
+ public string UnderlineOpenPattern = "<[";
|
|
|
+ public string UnderlineClosePattern = "]>";
|
|
|
+ public List<UnderlineSetting> UnderlineSettings; //todo 可能为空
|
|
|
+ private Dictionary<int, UnderlineSetting> UnderlineSettingDictionary
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (!underlineSettingDictionary.IsAvailable())
|
|
|
+ {
|
|
|
+ underlineSettingDictionary = new Dictionary<int, UnderlineSetting>();
|
|
|
+ foreach (var item in UnderlineSettings)
|
|
|
+ {
|
|
|
+ underlineSettingDictionary.Add(item.ID, item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return underlineSettingDictionary;
|
|
|
+ }
|
|
|
+ set { underlineSettingDictionary = value; }
|
|
|
+ }
|
|
|
+ private Dictionary<int, UnderlineSetting> underlineSettingDictionary;
|
|
|
+ private List<BaseMatch> UnderlineMatches = new List<BaseMatch>();
|
|
|
+
|
|
|
+ public bool SuperlinkFoldout;
|
|
|
+ public string SuperlinkOpenPattern = "<{";
|
|
|
+ public string SuperlinkClosePattern = "}>";
|
|
|
+ public List<SuperlinkSetting> SuperlinkSettings; //todo 可能为空
|
|
|
+ public Dictionary<int, Action<int>> SuperlinkCallbackDictionary = new Dictionary<int, Action<int>>();
|
|
|
+ private Dictionary<int, SuperlinkSetting> SuperlinkSettingDictionary
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (superlinkSettingDictionary == null)
|
|
|
+ {
|
|
|
+ superlinkSettingDictionary = new Dictionary<int, SuperlinkSetting>();
|
|
|
+ foreach (var item in SuperlinkSettings)
|
|
|
+ {
|
|
|
+ superlinkSettingDictionary.Add(item.ID, item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return superlinkSettingDictionary;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private Dictionary<int, SuperlinkSetting> superlinkSettingDictionary;
|
|
|
+ private List<BaseMatch> SuperlinkMatches = new List<BaseMatch>();
|
|
|
+
|
|
|
+ private char TransferSpaceReplaceChar = 'i';
|
|
|
+ private List<BaseMatch> TransferSpaceMatches = new List<BaseMatch>();
|
|
|
+ private List<List<BaseMatch>> MatchesList = new List<List<BaseMatch>>();
|
|
|
+
|
|
|
+ public int MinSize
|
|
|
+ {
|
|
|
+ get { return minSize; }
|
|
|
+ set
|
|
|
+ {
|
|
|
+ minSize = value;
|
|
|
+ ApplyVerticalBestfitSize();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public int minSize = 10;
|
|
|
+
|
|
|
+ public int MaxSize
|
|
|
+ {
|
|
|
+ get { return maxSize; }
|
|
|
+ set
|
|
|
+ {
|
|
|
+ maxSize = value;
|
|
|
+ ApplyVerticalBestfitSize();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public int maxSize = 40;
|
|
|
+
|
|
|
+ public bool VerticalBestfitFoldout;
|
|
|
+ public bool UseOriginBestfit;
|
|
|
+ public bool UseVerticalBestfit;
|
|
|
+ public bool VerticalBestfitDirty;
|
|
|
+
|
|
|
+ public bool Debug;
|
|
|
+ public bool Foldout = true;
|
|
|
+ public bool CalculateFlag;
|
|
|
+ public string Content;
|
|
|
+ public string IDPattern = "\\(\\d+\\)";
|
|
|
+ public KerningSolution KerningSolution;
|
|
|
+ public RichTextImageManager ImageManager;
|
|
|
+
|
|
|
+ private char CalculateReferenceChar = 'i';
|
|
|
+ private TextGenerator CalculateTextGenerator;
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ protected override void Awake()
|
|
|
+ {
|
|
|
+ base.Awake();
|
|
|
+
|
|
|
+ if (Debug)
|
|
|
+ {
|
|
|
+ text = Content;
|
|
|
+ UnityEngine.Debug.LogWarning("没有关闭Debug", gameObject);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override void OnPopulateMesh(VertexHelper toFill)
|
|
|
+ {
|
|
|
+ if (CalculateFlag)
|
|
|
+ {
|
|
|
+ CalculateFlag = false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ string newText = Content;
|
|
|
+
|
|
|
+ if (Application.isPlaying || Debug)
|
|
|
+ {
|
|
|
+ bool addNewOpenCloseMatch = ParseAndFillMatches(ref newText);
|
|
|
+ if (addNewOpenCloseMatch)
|
|
|
+ {
|
|
|
+ AddNewOpenCloseMatch(newText);
|
|
|
+ }
|
|
|
+ CalculateFlag = addNewOpenCloseMatch;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (UseVerticalBestfit && horizontalOverflow != HorizontalWrapMode.Overflow && verticalOverflow != VerticalWrapMode.Overflow)
|
|
|
+ {
|
|
|
+ if (VerticalBestfitDirty)
|
|
|
+ {
|
|
|
+ int verticalBestfitFontSize = GetVerticalBestfitFontSize(newText);
|
|
|
+ if (fontSize != verticalBestfitFontSize)
|
|
|
+ {
|
|
|
+ DelayCall.Call(1, () => { fontSize = verticalBestfitFontSize; });
|
|
|
+ VerticalBestfitDirty = false;
|
|
|
+ CalculateFlag = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ VerticalBestfitDirty = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (CalculateFlag)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ base.OnPopulateMesh(toFill);
|
|
|
+
|
|
|
+ List<UIVertex> vertices = new List<UIVertex>();
|
|
|
+ toFill.GetUIVertexStream(vertices);
|
|
|
+ ImageManager.Vertices = vertices;
|
|
|
+
|
|
|
+ HandleTransferSpaceMatch(toFill, vertices);
|
|
|
+
|
|
|
+ for (int i = 0; i < vertices.Count; i += 6)
|
|
|
+ {
|
|
|
+ Vector3 position0 = transform.TransformPoint(vertices[0 + i].position);
|
|
|
+ Vector3 position1 = transform.TransformPoint(vertices[1 + i].position);
|
|
|
+ Vector3 position2 = transform.TransformPoint(vertices[2 + i].position);
|
|
|
+ Vector3 position3 = transform.TransformPoint(vertices[4 + i].position);
|
|
|
+
|
|
|
+ UnityEngine.Debug.DrawLine(position0, position1, Color.black, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position1, position2, Color.black, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position2, position3, Color.black, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position3, position0, Color.black, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (KerningSolution == KerningSolution.Precalculate)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < AvailableSpriteMatches.Count; i++)
|
|
|
+ {
|
|
|
+ SpriteMatch spriteMatch = (SpriteMatch)AvailableSpriteMatches[i];
|
|
|
+ int index0 = 4 + spriteMatch.StartIndex * 6;
|
|
|
+ int index1 = 3 + spriteMatch.EndIndex * 6;
|
|
|
+ Vector3 leftPosition = vertices[index0].position;
|
|
|
+ Vector3 rightPosition = vertices[index1].position;
|
|
|
+ Vector3 bottomMiddle = (leftPosition + rightPosition) / 2;
|
|
|
+ Vector3 position0;
|
|
|
+ Vector3 position1;
|
|
|
+ Vector3 position2;
|
|
|
+ Vector3 position3;
|
|
|
+ spriteMatch.ScaledHeight = spriteMatch.SpriteInfo.GetScaledHeight(spriteMatch.ScaledWidth);
|
|
|
+ position0 = bottomMiddle + new Vector3(-spriteMatch.ScaledWidth / 2, 0, 0);
|
|
|
+ position1 = bottomMiddle + new Vector3(spriteMatch.ScaledWidth / 2, 0, 0);
|
|
|
+ position2 = bottomMiddle + new Vector3(spriteMatch.ScaledWidth / 2, spriteMatch.ScaledHeight, 0);
|
|
|
+ position3 = bottomMiddle + new Vector3(-spriteMatch.ScaledWidth / 2, spriteMatch.ScaledHeight, 0);
|
|
|
+ position0 = transform.TransformPoint(position0);
|
|
|
+ position1 = transform.TransformPoint(position1);
|
|
|
+ position2 = transform.TransformPoint(position2);
|
|
|
+ position3 = transform.TransformPoint(position3);
|
|
|
+ spriteMatch.Positions.Add(position0);
|
|
|
+ spriteMatch.Positions.Add(position1);
|
|
|
+ spriteMatch.Positions.Add(position2);
|
|
|
+ spriteMatch.Positions.Add(position3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (KerningSolution == KerningSolution.Shrink)
|
|
|
+ {
|
|
|
+ Dictionary<SpriteInfo, Dictionary<int, List<SpriteMatch>>> dictionary = new Dictionary<SpriteInfo, Dictionary<int, List<SpriteMatch>>>();
|
|
|
+ for (int i = 0; i < AvailableSpriteMatches.Count; i++)
|
|
|
+ {
|
|
|
+ SpriteMatch spriteMatch = (SpriteMatch)AvailableSpriteMatches[i];
|
|
|
+ if (dictionary.ContainsKey(spriteMatch.SpriteInfo))
|
|
|
+ {
|
|
|
+ if (dictionary[spriteMatch.SpriteInfo].ContainsKey(spriteMatch.Length))
|
|
|
+ {
|
|
|
+ dictionary[spriteMatch.SpriteInfo][spriteMatch.Length].Add(spriteMatch);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ List<SpriteMatch> matches = new List<SpriteMatch>();
|
|
|
+ matches.Add(spriteMatch);
|
|
|
+ dictionary[spriteMatch.SpriteInfo].Add(spriteMatch.Length, matches);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ List<SpriteMatch> matches = new List<SpriteMatch>();
|
|
|
+ matches.Add(spriteMatch);
|
|
|
+ Dictionary<int, List<SpriteMatch>> lengthDictionary = new Dictionary<int, List<SpriteMatch>>();
|
|
|
+ lengthDictionary.Add(spriteMatch.Length, matches);
|
|
|
+ dictionary.Add(spriteMatch.SpriteInfo, lengthDictionary);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach (var lengthDictionary in dictionary)
|
|
|
+ {
|
|
|
+ foreach (var matches in lengthDictionary.Value.Values)
|
|
|
+ {
|
|
|
+ float minScaledWidth = Mathf.Infinity;
|
|
|
+ for (int i = 0; i < matches.Count; i++)
|
|
|
+ {
|
|
|
+ float scaledWidth = matches[i].ScaledWidth;
|
|
|
+ int frontIndex = matches[i].StartIndex - 1;
|
|
|
+ int rearIndex = matches[i].EndIndex + 1;
|
|
|
+ float frontKerning;
|
|
|
+ float rearKerning;
|
|
|
+ if (frontIndex < 0)
|
|
|
+ {
|
|
|
+ frontKerning = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ frontKerning = GetKerning(text[frontIndex], SpriteReplaceChar);
|
|
|
+ }
|
|
|
+ if (rearIndex >= text.Length)
|
|
|
+ {
|
|
|
+ rearKerning = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ rearKerning = GetKerning(SpriteReplaceChar, text[rearIndex]);
|
|
|
+ }
|
|
|
+ if (frontKerning < 0)
|
|
|
+ {
|
|
|
+ scaledWidth += frontKerning;
|
|
|
+ }
|
|
|
+ if (rearKerning < 0)
|
|
|
+ {
|
|
|
+ scaledWidth += rearKerning;
|
|
|
+ }
|
|
|
+ if (minScaledWidth > scaledWidth)
|
|
|
+ {
|
|
|
+ minScaledWidth = scaledWidth;
|
|
|
+ }
|
|
|
+ matches[i].FrontKerning = frontKerning;
|
|
|
+ matches[i].RearKerning = rearKerning;
|
|
|
+ }
|
|
|
+ float minScaledHeight = lengthDictionary.Key.GetScaledHeight(minScaledWidth);
|
|
|
+ for (int i = 0; i < matches.Count; i++)
|
|
|
+ {
|
|
|
+ matches[i].ScaledWidth = minScaledWidth;
|
|
|
+ matches[i].ScaledHeight = minScaledHeight;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < AvailableSpriteMatches.Count; i++)
|
|
|
+ {
|
|
|
+ SpriteMatch spriteMatch = (SpriteMatch)AvailableSpriteMatches[i];
|
|
|
+ int index0 = 4 + spriteMatch.StartIndex * 6;
|
|
|
+ int index1 = 3 + spriteMatch.EndIndex * 6;
|
|
|
+ Vector3 leftPosition = vertices[index0].position;
|
|
|
+ Vector3 rightPosition = vertices[index1].position;
|
|
|
+ leftPosition.x -= spriteMatch.FrontKerning;
|
|
|
+ rightPosition.x += spriteMatch.RearKerning;
|
|
|
+ Vector3 bottomMiddle = (leftPosition + rightPosition) / 2;
|
|
|
+ Vector3 position0;
|
|
|
+ Vector3 position1;
|
|
|
+ Vector3 position2;
|
|
|
+ Vector3 position3;
|
|
|
+ position0 = bottomMiddle + new Vector3(-spriteMatch.ScaledWidth / 2, 0, 0);
|
|
|
+ position1 = bottomMiddle + new Vector3(spriteMatch.ScaledWidth / 2, 0, 0);
|
|
|
+ position2 = bottomMiddle + new Vector3(spriteMatch.ScaledWidth / 2, spriteMatch.ScaledHeight, 0);
|
|
|
+ position3 = bottomMiddle + new Vector3(-spriteMatch.ScaledWidth / 2, spriteMatch.ScaledHeight, 0);
|
|
|
+ position0 = transform.TransformPoint(position0);
|
|
|
+ position1 = transform.TransformPoint(position1);
|
|
|
+ position2 = transform.TransformPoint(position2);
|
|
|
+ position3 = transform.TransformPoint(position3);
|
|
|
+ spriteMatch.Positions.Add(position0);
|
|
|
+ spriteMatch.Positions.Add(position1);
|
|
|
+ spriteMatch.Positions.Add(position2);
|
|
|
+ spriteMatch.Positions.Add(position3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < UnderlineMatches.Count; i++)
|
|
|
+ {
|
|
|
+ UnderlineMatch match = UnderlineMatches[i] as UnderlineMatch;
|
|
|
+ //print(match.StartIndex + " " + match.EndIndex);
|
|
|
+ GetSegments(text, CalculateTextGenerator, match, match.UnderlineSetting.UnderlineExcludeChars);
|
|
|
+ for (int j = 0; j < match.Segments.Count; j++)
|
|
|
+ {
|
|
|
+ int startCharIdx = match.Segments[j][0];
|
|
|
+ int endCharIdx = match.Segments[j][1];
|
|
|
+ //print(startCharIdx + " " + endCharIdx);
|
|
|
+ int lineIndex = GetLineIndex(CalculateTextGenerator, startCharIdx);
|
|
|
+ int lineEndCharacterIndex;
|
|
|
+ float penPositionY = GetPenPositionY(lineIndex, CalculateTextGenerator.lineCount);
|
|
|
+ float lineHeight = CalculateTextGenerator.lines[lineIndex].height;
|
|
|
+ if (lineIndex != -1)
|
|
|
+ {
|
|
|
+ lineEndCharacterIndex = GetLineEndCharacterIndex(CalculateTextGenerator, lineIndex, text.Length);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ int newEndCharIdx = Mathf.Min(lineEndCharacterIndex, endCharIdx);
|
|
|
+ List<Vector3> positions = new List<Vector3>();
|
|
|
+ Vector3 position0 = vertices[4 + startCharIdx * 6].position;
|
|
|
+ Vector3 position1 = vertices[2 + newEndCharIdx * 6].position;
|
|
|
+ position0.y = penPositionY;
|
|
|
+ position1.y = penPositionY;
|
|
|
+ Vector3 position2 = position1;
|
|
|
+ Vector3 position3 = position0;
|
|
|
+ float underlineHeight = lineHeight * match.UnderlineSetting.Scale;
|
|
|
+ position2.y -= underlineHeight;
|
|
|
+ position3.y -= underlineHeight;
|
|
|
+ if (match.UnderlineSetting.Style == UnderlineStyle.Ellipse)
|
|
|
+ {
|
|
|
+ if (vertices[1 + endCharIdx*6].position.x - vertices[0 + startCharIdx*6].position.x > underlineHeight*2)
|
|
|
+ {
|
|
|
+ position0.x += underlineHeight;
|
|
|
+ position1.x -= underlineHeight;
|
|
|
+ position2.x -= underlineHeight;
|
|
|
+ position3.x += underlineHeight;
|
|
|
+ List<Vector3> topHemispherePositions = new List<Vector3>();
|
|
|
+ List<Vector3> bottomHemispherePositions = new List<Vector3>();
|
|
|
+ int cutCount = Mathf.Max(4, Mathf.CeilToInt(underlineHeight));
|
|
|
+ float radius = underlineHeight/2;
|
|
|
+ for (int k = 0; k <= cutCount; k++)
|
|
|
+ {
|
|
|
+ float angle = 90f/cutCount*k;
|
|
|
+ float radian = angle*Mathf.Deg2Rad;
|
|
|
+ float x = radius * Mathf.Sin(radian);
|
|
|
+ float y = radius * Mathf.Cos(radian);
|
|
|
+ topHemispherePositions.Add(new Vector3(x, y, 0));
|
|
|
+ if (k != cutCount)
|
|
|
+ {
|
|
|
+ bottomHemispherePositions.Insert(0, new Vector3(x, -y, 0));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<List<Vector3>> ellipsePositionsList = new List<List<Vector3>>();
|
|
|
+ List<Vector3> ellipsePositions = new List<Vector3>(); //右半球
|
|
|
+ ellipsePositions.Add((position1+position2)/2);
|
|
|
+ foreach (var position in topHemispherePositions)
|
|
|
+ {
|
|
|
+ Vector3 newPosition = ellipsePositions[0] + position;
|
|
|
+ ellipsePositions.Add(newPosition);
|
|
|
+ }
|
|
|
+ //ellipsePositions.Add(ellipsePositions[0] + new Vector3(radius, 0, 0));
|
|
|
+ foreach (var position in bottomHemispherePositions)
|
|
|
+ {
|
|
|
+ Vector3 newPosition = ellipsePositions[0] + position;
|
|
|
+ ellipsePositions.Add(newPosition);
|
|
|
+ }
|
|
|
+ for (int k = 0; k < ellipsePositions.Count; k++)
|
|
|
+ {
|
|
|
+ ellipsePositions[k] = rectTransform.TransformPoint(ellipsePositions[k]);
|
|
|
+ }
|
|
|
+ ellipsePositionsList.Add(ellipsePositions);
|
|
|
+ ellipsePositions = new List<Vector3>(); //左半球
|
|
|
+ ellipsePositions.Add((position0 + position3) / 2);
|
|
|
+ foreach (var position in topHemispherePositions)
|
|
|
+ {
|
|
|
+ Vector3 newPosition = ellipsePositions[0];
|
|
|
+ newPosition.x -= position.x;
|
|
|
+ newPosition.y += position.y;
|
|
|
+ ellipsePositions.Add(newPosition);
|
|
|
+ }
|
|
|
+ //ellipsePositions.Add(ellipsePositions[0] + new Vector3(-radius, 0, 0));
|
|
|
+ foreach (var position in bottomHemispherePositions)
|
|
|
+ {
|
|
|
+ Vector3 newPosition = ellipsePositions[0];
|
|
|
+ newPosition.x -= position.x;
|
|
|
+ newPosition.y += position.y;
|
|
|
+ ellipsePositions.Add(newPosition);
|
|
|
+ }
|
|
|
+ for (int k = 0; k < ellipsePositions.Count; k++)
|
|
|
+ {
|
|
|
+ ellipsePositions[k] = rectTransform.TransformPoint(ellipsePositions[k]);
|
|
|
+ }
|
|
|
+ ellipsePositionsList.Add(ellipsePositions);
|
|
|
+ match.EllipsePositionsList.Add(ellipsePositionsList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ positions.Add(position0);
|
|
|
+ positions.Add(position1);
|
|
|
+ positions.Add(position2);
|
|
|
+ positions.Add(position3);
|
|
|
+ positions[0] = rectTransform.TransformPoint(positions[0]);
|
|
|
+ positions[1] = rectTransform.TransformPoint(positions[1]);
|
|
|
+ positions[2] = rectTransform.TransformPoint(positions[2]);
|
|
|
+ positions[3] = rectTransform.TransformPoint(positions[3]);
|
|
|
+ match.RectanglePositionsList.Add(positions);
|
|
|
+ if (endCharIdx > lineEndCharacterIndex)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //print(SuperlinkMatches.Count);
|
|
|
+ for (int i = 0; i < SuperlinkMatches.Count; i++)
|
|
|
+ {
|
|
|
+ SuperlinkMatch match = SuperlinkMatches[i] as SuperlinkMatch;
|
|
|
+ //print(match.StartIndex + " " + match.EndIndex);
|
|
|
+ GetSegments(text, CalculateTextGenerator, match, match.SuperlinkSetting.SuperlinkExcludeChars);
|
|
|
+ for (int j = 0; j < match.Segments.Count; j++)
|
|
|
+ {
|
|
|
+ int startCharIdx = match.Segments[j][0];
|
|
|
+ int endCharIdx = match.Segments[j][1];
|
|
|
+ //print(startCharIdx + " " + endCharIdx);
|
|
|
+ int lineIndex = GetLineIndex(CalculateTextGenerator, startCharIdx);
|
|
|
+ int lineEndCharacterIndex;
|
|
|
+ float lineCenterY = GetLineCenterY(lineIndex, CalculateTextGenerator.lineCount);
|
|
|
+ float lineHeight = CalculateTextGenerator.lines[lineIndex].height;
|
|
|
+ if (lineIndex != -1)
|
|
|
+ {
|
|
|
+ lineEndCharacterIndex = GetLineEndCharacterIndex(CalculateTextGenerator, lineIndex, text.Length);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ int newEndCharIdx = Mathf.Min(lineEndCharacterIndex, endCharIdx);
|
|
|
+ List<Vector3> positions = new List<Vector3>();
|
|
|
+ float lineMaxY = lineCenterY + (lineHeight / 2) * match.SuperlinkSetting.Scale;
|
|
|
+ float lineMinY = lineCenterY - (lineHeight / 2) * match.SuperlinkSetting.Scale;
|
|
|
+ Vector3 position0 = vertices[4 + startCharIdx * 6].position;
|
|
|
+ Vector3 position1 = vertices[2 + newEndCharIdx * 6].position;
|
|
|
+ Vector3 position2 = position1;
|
|
|
+ Vector3 position3 = position0;
|
|
|
+ position0.y = lineMaxY;
|
|
|
+ position1.y = lineMaxY;
|
|
|
+ position2.y = lineMinY;
|
|
|
+ position3.y = lineMinY;
|
|
|
+ positions.Add(position0);
|
|
|
+ positions.Add(position1);
|
|
|
+ positions.Add(position2);
|
|
|
+ positions.Add(position3);
|
|
|
+ positions[0] = rectTransform.TransformPoint(positions[0]);
|
|
|
+ positions[1] = rectTransform.TransformPoint(positions[1]);
|
|
|
+ positions[2] = rectTransform.TransformPoint(positions[2]);
|
|
|
+ positions[3] = rectTransform.TransformPoint(positions[3]);
|
|
|
+ match.RectanglePositionsList.Add(positions);
|
|
|
+ if (endCharIdx > lineEndCharacterIndex)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < AvailableSpriteMatches.Count; i++)
|
|
|
+ {
|
|
|
+ SpriteMatch match = (SpriteMatch)AvailableSpriteMatches[i];
|
|
|
+ Vector3 position0 = match.Positions[0];
|
|
|
+ Vector3 position1 = match.Positions[1];
|
|
|
+ Vector3 position2 = match.Positions[2];
|
|
|
+ Vector3 position3 = match.Positions[3];
|
|
|
+ UnityEngine.Debug.DrawLine(position0, position1, Color.red, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position1, position2, Color.red, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position2, position3, Color.red, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position3, position0, Color.red, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < UnderlineMatches.Count; i++)
|
|
|
+ {
|
|
|
+ UnderlineMatch match = (UnderlineMatch)UnderlineMatches[i];
|
|
|
+ for (int j = 0; j < match.RectanglePositionsList.Count; j++)
|
|
|
+ {
|
|
|
+ Vector3 position0 = match.RectanglePositionsList[j][0];
|
|
|
+ Vector3 position1 = match.RectanglePositionsList[j][1];
|
|
|
+ Vector3 position2 = match.RectanglePositionsList[j][2];
|
|
|
+ Vector3 position3 = match.RectanglePositionsList[j][3];
|
|
|
+ UnityEngine.Debug.DrawLine(position0, position1, Color.blue, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position1, position2, Color.blue, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position2, position3, Color.blue, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position3, position0, Color.blue, 1);
|
|
|
+ }
|
|
|
+ for (int j = 0; j < match.EllipsePositionsList.Count; j++)
|
|
|
+ {
|
|
|
+ for (int k = 0; k < match.EllipsePositionsList[j].Count; k++)
|
|
|
+ {
|
|
|
+ for (int l = 1; l < match.EllipsePositionsList[j][k].Count - 1; l++)
|
|
|
+ {
|
|
|
+ Vector3 position0 = match.EllipsePositionsList[j][k][0];
|
|
|
+ Vector3 position1 = match.EllipsePositionsList[j][k][l + 0];
|
|
|
+ Vector3 position2 = match.EllipsePositionsList[j][k][l + 1];
|
|
|
+ UnityEngine.Debug.DrawLine(position0, position1, Color.blue, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position1, position2, Color.blue, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position2, position0, Color.blue, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < SuperlinkMatches.Count; i++)
|
|
|
+ {
|
|
|
+ SuperlinkMatch match = (SuperlinkMatch)SuperlinkMatches[i];
|
|
|
+ for (int j = 0; j < match.RectanglePositionsList.Count; j++)
|
|
|
+ {
|
|
|
+ Vector3 position0 = match.RectanglePositionsList[j][0];
|
|
|
+ Vector3 position1 = match.RectanglePositionsList[j][1];
|
|
|
+ Vector3 position2 = match.RectanglePositionsList[j][2];
|
|
|
+ Vector3 position3 = match.RectanglePositionsList[j][3];
|
|
|
+ UnityEngine.Debug.DrawLine(position0, position1, Color.green, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position1, position2, Color.green, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position2, position3, Color.green, 1);
|
|
|
+ UnityEngine.Debug.DrawLine(position3, position0, Color.green, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void SetContent(string content)
|
|
|
+ {
|
|
|
+ Content = content;
|
|
|
+ text = content;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void ClearMatches()
|
|
|
+ {
|
|
|
+ AvailableSpriteMatches = new List<BaseMatch>();
|
|
|
+ TruncateSpriteMatches = new List<BaseMatch>();
|
|
|
+ UnderlineMatches = new List<BaseMatch>();
|
|
|
+ SuperlinkMatches = new List<BaseMatch>();
|
|
|
+ TransferSpaceMatches = new List<BaseMatch>();
|
|
|
+ MatchesList = new List<List<BaseMatch>>();
|
|
|
+ SuperlinkCallbackDictionary = new Dictionary<int, Action<int>>();
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool ParseMatches(ref string newText)
|
|
|
+ {
|
|
|
+ bool haveMatch = false;
|
|
|
+ AvailableSpriteMatches = new List<BaseMatch>();
|
|
|
+ UnderlineMatches = new List<BaseMatch>();
|
|
|
+ SuperlinkMatches = new List<BaseMatch>();
|
|
|
+ TransferSpaceMatches = new List<BaseMatch>();
|
|
|
+ MatchesList = new List<List<BaseMatch>>
|
|
|
+ {
|
|
|
+ AvailableSpriteMatches,
|
|
|
+ UnderlineMatches,
|
|
|
+ SuperlinkMatches,
|
|
|
+ TransferSpaceMatches,
|
|
|
+ };
|
|
|
+
|
|
|
+ newText = ParseTransferSpaceMatches(newText);
|
|
|
+ newText = ParseOpenCloseMatches(newText);
|
|
|
+
|
|
|
+ if (TransferSpaceMatches.Count > 0)
|
|
|
+ {
|
|
|
+ haveMatch = true;
|
|
|
+ }
|
|
|
+ if (AvailableSpriteMatches.Count > 0)
|
|
|
+ {
|
|
|
+ haveMatch = true;
|
|
|
+ }
|
|
|
+ if (UnderlineMatches.Count > 0)
|
|
|
+ {
|
|
|
+ haveMatch = true;
|
|
|
+ }
|
|
|
+ if (SuperlinkMatches.Count > 0)
|
|
|
+ {
|
|
|
+ haveMatch = true;
|
|
|
+ }
|
|
|
+ return haveMatch;
|
|
|
+ }
|
|
|
+
|
|
|
+ private string ParseTransferSpaceMatches(string newText)
|
|
|
+ {
|
|
|
+ string pattern = "\\\\ ";
|
|
|
+ Match match = Regex.Match(newText, pattern);
|
|
|
+ while (match.Success)
|
|
|
+ {
|
|
|
+ MatchData matchData = new MatchData();
|
|
|
+ matchData.OpenPatternIndex = match.Index;
|
|
|
+ matchData.MatchLength = match.Length;
|
|
|
+
|
|
|
+ TransferSpaceMatch transferSpaceMatch = new TransferSpaceMatch();
|
|
|
+ transferSpaceMatch.StartIndex = matchData.OpenPatternIndex;
|
|
|
+ transferSpaceMatch.EndIndex = matchData.OpenPatternIndex;
|
|
|
+ TransferSpaceMatches.Add(transferSpaceMatch);
|
|
|
+
|
|
|
+ newText = newText.Replace(match.Index, match.Length, TransferSpaceReplaceChar.ToString());
|
|
|
+ match = Regex.Match(newText, pattern);
|
|
|
+ }
|
|
|
+ return newText;
|
|
|
+ }
|
|
|
+
|
|
|
+ private string ParseOpenCloseMatches(string newText)
|
|
|
+ {
|
|
|
+ if (OpenPatterns.Count == 0 || ClosePatterns.Count == 0)
|
|
|
+ {
|
|
|
+ return newText;
|
|
|
+ }
|
|
|
+ if (OpenPatterns.Count != ClosePatterns.Count)
|
|
|
+ {
|
|
|
+ return newText;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<string> transferedOpenPatterns = new List<string>();
|
|
|
+ foreach (var openPattern in OpenPatterns)
|
|
|
+ {
|
|
|
+ transferedOpenPatterns.Add(openPattern.GetTransferedPattern());
|
|
|
+ }
|
|
|
+ List<string> transferedClosePatterns = new List<string>();
|
|
|
+ foreach (var closePattern in ClosePatterns)
|
|
|
+ {
|
|
|
+ transferedClosePatterns.Add(closePattern.GetTransferedPattern());
|
|
|
+ }
|
|
|
+ string orOpenPattern = transferedOpenPatterns.ToOrPattern();
|
|
|
+ string orClosePattern = transferedClosePatterns.ToOrPattern();
|
|
|
+ string regexPattern = string.Format("{0}.+{1}", orOpenPattern, orClosePattern);
|
|
|
+
|
|
|
+ Match match = Regex.Match(newText, regexPattern, RegexOptions.Singleline);
|
|
|
+ while (match.Success)
|
|
|
+ {
|
|
|
+ Dictionary<string, int> openPatternIndexDictionary = new Dictionary<string, int>();
|
|
|
+ Dictionary<string, int> closePatternIndexDictionary = new Dictionary<string, int>();
|
|
|
+ for (int i = 0; i < OpenPatterns.Count; i++)
|
|
|
+ {
|
|
|
+ int index = match.Value.LastIndexOf(OpenPatterns[i]);
|
|
|
+ if (index == -1) continue;
|
|
|
+ else openPatternIndexDictionary.Add(OpenPatterns[i], index);
|
|
|
+ }
|
|
|
+ for (int i = 0; i < ClosePatterns.Count; i++)
|
|
|
+ {
|
|
|
+ string closeRegexPattern = ClosePatterns[i].GetTransferedPattern();
|
|
|
+ Match closePatternMatch = Regex.Match(match.Value, closeRegexPattern);
|
|
|
+ while (closePatternMatch.Success)
|
|
|
+ {
|
|
|
+ if (openPatternIndexDictionary[OpenPatterns[i]] > closePatternMatch.Index)
|
|
|
+ {
|
|
|
+ closePatternMatch = closePatternMatch.NextMatch();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ closePatternIndexDictionary.Add(ClosePatterns[i], closePatternMatch.Index);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ int[] openPatternIndexLength = new int[2];
|
|
|
+ int[] closePatternIndexLength = new int[2];
|
|
|
+ int dictionaryIndex = openPatternIndexDictionary.MyMax((pattern, index) => index);
|
|
|
+ KVPair<string, int> pair = openPatternIndexDictionary.GetAtIndex(dictionaryIndex);
|
|
|
+ openPatternIndexLength[0] = pair.value;
|
|
|
+ openPatternIndexLength[1] = pair.key.Length;
|
|
|
+ pair = closePatternIndexDictionary.GetAtIndex(dictionaryIndex);
|
|
|
+ closePatternIndexLength[0] = pair.value;
|
|
|
+ closePatternIndexLength[1] = pair.key.Length;
|
|
|
+
|
|
|
+ int openPatternIndex = openPatternIndexLength[0];
|
|
|
+ int openPatternLength = openPatternIndexLength[1];
|
|
|
+ int closePatternIndex = closePatternIndexLength[0];
|
|
|
+ int closePatternLength = closePatternIndexLength[1];
|
|
|
+ int contentIndex = openPatternIndex + openPatternLength;
|
|
|
+ int contentLength = closePatternIndex - contentIndex;
|
|
|
+ int matchLength = closePatternIndex + closePatternLength - openPatternIndex;
|
|
|
+ string matchValue = match.Value.Substring(openPatternIndex, matchLength);
|
|
|
+ string openPattern = match.Value.Substring(openPatternIndex, openPatternLength);
|
|
|
+ string closePattern = match.Value.Substring(closePatternIndex, closePatternLength);
|
|
|
+
|
|
|
+ MatchData matchData = new MatchData();
|
|
|
+ matchData.OpenPatternIndex = openPatternIndex + match.Index;
|
|
|
+ matchData.OpenPatternLength = openPatternLength;
|
|
|
+ matchData.ClosePatternIndex = closePatternIndex + match.Index;
|
|
|
+ matchData.ClosePatternLength = closePatternLength;
|
|
|
+ matchData.ContentIndex = contentIndex + match.Index;
|
|
|
+ matchData.ContentLength = contentLength;
|
|
|
+ matchData.MatchLength = matchLength;
|
|
|
+ matchData.MatchValue = matchValue;
|
|
|
+ matchData.OpenPattern = openPattern;
|
|
|
+ matchData.ClosePattern = closePattern;
|
|
|
+
|
|
|
+ ParseResult parseResult = OpenCloseParseFunctionDictionary[openPattern].Invoke(newText, matchData);
|
|
|
+ for (int i = 0; i < OpenPatterns.Count; i++)
|
|
|
+ {
|
|
|
+ if (matchData.OpenPattern != OpenPatterns[i]) continue;
|
|
|
+ MatchesList[i].Add(parseResult.Match);
|
|
|
+ for (int j = 0; j < MatchesList.Count; j++)
|
|
|
+ {
|
|
|
+ AdjustIndicesByMatch(parseResult.ExtraOffset, parseResult.Match, MatchesList[j]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ newText = parseResult.NewText;
|
|
|
+ match = Regex.Match(newText, regexPattern);
|
|
|
+ }
|
|
|
+ return newText;
|
|
|
+ }
|
|
|
+
|
|
|
+ private ParseResult ParseSpritePattern(string newText, MatchData matchData)
|
|
|
+ {
|
|
|
+ int id = 0;
|
|
|
+ string name;
|
|
|
+ string content = newText.Substring(matchData.ContentIndex, matchData.ContentLength);
|
|
|
+ Match idMatch = Regex.Match(content, IDPattern);
|
|
|
+ if (idMatch.Success)
|
|
|
+ {
|
|
|
+ Match match = Regex.Match(idMatch.Value, "\\d+");
|
|
|
+ id = int.Parse(match.Value);
|
|
|
+ name = content.Replace(idMatch.Index, idMatch.Length, "");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ name = content;
|
|
|
+ }
|
|
|
+ newText = newText.Replace(matchData.OpenPatternIndex, matchData.MatchLength, SpriteReplaceChar.ToString());
|
|
|
+
|
|
|
+ SpriteMatch spriteMatch = new SpriteMatch();
|
|
|
+ spriteMatch.ID = id;
|
|
|
+ spriteMatch.Name = name;
|
|
|
+ spriteMatch.SpriteSetting = SpriteSettingDictionary[id];
|
|
|
+ spriteMatch.MatchData = matchData;
|
|
|
+ spriteMatch.StartIndex = matchData.OpenPatternIndex;
|
|
|
+ spriteMatch.EndIndex = matchData.OpenPatternIndex;
|
|
|
+ ParseResult parseResult = new ParseResult();
|
|
|
+ parseResult.Match = spriteMatch;
|
|
|
+ parseResult.ExtraOffset = -matchData.ContentLength + 1;
|
|
|
+ parseResult.NewText = newText;
|
|
|
+ return parseResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ private ParseResult ParseUnderlinePattern(string newText, MatchData matchData)
|
|
|
+ {
|
|
|
+ newText = newText.Replace(matchData.ClosePatternIndex, matchData.ClosePatternLength, "");
|
|
|
+ int id = 0;
|
|
|
+ int extraOffset = 0;
|
|
|
+ string content = newText.Substring(matchData.ContentIndex, matchData.ContentLength);
|
|
|
+ Match idMatch = Regex.Match(content, IDPattern);
|
|
|
+ if (idMatch.Success)
|
|
|
+ {
|
|
|
+ Match match = Regex.Match(idMatch.Value, "\\d+");
|
|
|
+ id = int.Parse(match.Value);
|
|
|
+ extraOffset = idMatch.Length;
|
|
|
+ newText = newText.Replace(matchData.ContentIndex + idMatch.Index, idMatch.Length, "");
|
|
|
+ }
|
|
|
+ newText = newText.Replace(matchData.OpenPatternIndex, matchData.OpenPatternLength, "");
|
|
|
+
|
|
|
+ UnderlineMatch underlineMatch = new UnderlineMatch();
|
|
|
+ underlineMatch.ID = id;
|
|
|
+ underlineMatch.UnderlineSetting = UnderlineSettingDictionary[id];
|
|
|
+ underlineMatch.MatchData = matchData;
|
|
|
+ underlineMatch.StartIndex = matchData.OpenPatternIndex;
|
|
|
+ underlineMatch.EndIndex = matchData.OpenPatternIndex + matchData.MatchLength - matchData.OpenPatternLength - matchData.ClosePatternLength - 1 - extraOffset;
|
|
|
+ //print(newText);
|
|
|
+ //print(underlineMatch.StartIndex + " " + underlineMatch.EndIndex);
|
|
|
+ ParseResult parseResult = new ParseResult();
|
|
|
+ parseResult.Match = underlineMatch;
|
|
|
+ parseResult.ExtraOffset = extraOffset;
|
|
|
+ parseResult.NewText = newText;
|
|
|
+ return parseResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ private ParseResult ParseSuperlinkPattern(string newText, MatchData matchData)
|
|
|
+ {
|
|
|
+ newText = newText.Replace(matchData.ClosePatternIndex, matchData.ClosePatternLength, "");
|
|
|
+ int id = 0;
|
|
|
+ int extraOffset = 0;
|
|
|
+ string content = newText.Substring(matchData.ContentIndex, matchData.ContentLength);
|
|
|
+ Match idMatch = Regex.Match(content, IDPattern);
|
|
|
+ if (idMatch.Success)
|
|
|
+ {
|
|
|
+ Match match = Regex.Match(idMatch.Value, "\\d+");
|
|
|
+ id = int.Parse(match.Value);
|
|
|
+ extraOffset = idMatch.Length;
|
|
|
+ newText = newText.Replace(matchData.ContentIndex + idMatch.Index, idMatch.Length, "");
|
|
|
+ }
|
|
|
+ newText = newText.Replace(matchData.OpenPatternIndex, matchData.OpenPatternLength, "");
|
|
|
+
|
|
|
+ SuperlinkMatch superlinkMatch = new SuperlinkMatch();
|
|
|
+ superlinkMatch.ID = id;
|
|
|
+ superlinkMatch.SuperlinkSetting = SuperlinkSettingDictionary[id];
|
|
|
+ superlinkMatch.MatchData = matchData;
|
|
|
+ superlinkMatch.StartIndex = matchData.OpenPatternIndex;
|
|
|
+ superlinkMatch.EndIndex = matchData.OpenPatternIndex + matchData.MatchLength - matchData.OpenPatternLength - matchData.ClosePatternLength - 1 - extraOffset;
|
|
|
+ ParseResult parseResult = new ParseResult();
|
|
|
+ parseResult.Match = superlinkMatch;
|
|
|
+ parseResult.ExtraOffset = extraOffset;
|
|
|
+ parseResult.NewText = newText;
|
|
|
+ return parseResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void AddNewOpenCloseMatch(string newText)
|
|
|
+ {
|
|
|
+ DelayCall.Call
|
|
|
+ (
|
|
|
+ 1,
|
|
|
+ () =>
|
|
|
+ {
|
|
|
+ text = newText;
|
|
|
+ //ImageManager.Init(this);
|
|
|
+ //ImageManager.ClearRenderTask();
|
|
|
+ //ImageManager.RenderSprites(SpriteMatches);
|
|
|
+ //ImageManager.RenderUnderlines(UnderlineMatches);
|
|
|
+ //ImageManager.RenderSuperlinks(SuperlinkMatches);
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void FillSpriteMatches(List<BaseMatch> spriteMatches, List<BaseMatch> truncateSpriteMatches, ref string newText/*, bool fillTruncate*/)
|
|
|
+ {
|
|
|
+ spriteMatches.MySort((match0, match1) => match1.StartIndex < match0.StartIndex);
|
|
|
+
|
|
|
+ float replaceCharWidth = GetCharacterWidth(SpriteReplaceChar);
|
|
|
+ //bool isTextChanged = false;
|
|
|
+ //if (!fillTruncate)
|
|
|
+ //{
|
|
|
+ /*isTextChanged = */ReplaceAllSpriteMatch(spriteMatches, replaceCharWidth, ref newText);
|
|
|
+ //}
|
|
|
+
|
|
|
+ if (horizontalOverflow == HorizontalWrapMode.Overflow)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*isTextChanged = isTextChanged | */CalculateSpriteMatchPosition(spriteMatches, truncateSpriteMatches, replaceCharWidth, ref newText);
|
|
|
+ //return isTextChanged;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ReplaceAllSpriteMatch(List<BaseMatch> spriteMatches, float replaceCharWidth, ref string newText)
|
|
|
+ {
|
|
|
+ foreach (var match in spriteMatches)
|
|
|
+ {
|
|
|
+ SpriteMatch spriteMatch = match as SpriteMatch;
|
|
|
+ SpriteInfo spriteInfo = SpriteInfoManager.GetSpriteInfo(spriteMatch.Name);
|
|
|
+ float scaledWidth = replaceCharWidth * 2 * spriteMatch.SpriteSetting.Scale;
|
|
|
+ float minReplaceWidth = scaledWidth;
|
|
|
+ if (KerningSolution == KerningSolution.Precalculate)
|
|
|
+ {
|
|
|
+ int frontIndex = spriteMatch.StartIndex - 1;
|
|
|
+ int rearIndex = spriteMatch.EndIndex + 1;
|
|
|
+ float frontKerning;
|
|
|
+ float rearKerning;
|
|
|
+ if (frontIndex < 0)
|
|
|
+ {
|
|
|
+ frontKerning = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ frontKerning = GetKerning(text[frontIndex], SpriteReplaceChar);
|
|
|
+ }
|
|
|
+ if (rearIndex >= text.Length)
|
|
|
+ {
|
|
|
+ rearKerning = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ rearKerning = GetKerning(SpriteReplaceChar, text[rearIndex]);
|
|
|
+ }
|
|
|
+ if (frontKerning < 0)
|
|
|
+ {
|
|
|
+ minReplaceWidth -= frontKerning;
|
|
|
+ }
|
|
|
+ if (rearKerning < 0)
|
|
|
+ {
|
|
|
+ minReplaceWidth -= rearKerning;
|
|
|
+ }
|
|
|
+ spriteMatch.FrontKerning = frontKerning;
|
|
|
+ spriteMatch.RearKerning = rearKerning;
|
|
|
+ }
|
|
|
+ int replaceCharCount = Mathf.CeilToInt(minReplaceWidth / replaceCharWidth);
|
|
|
+
|
|
|
+ for (int j = 0; j < MatchesList.Count; j++)
|
|
|
+ {
|
|
|
+ AdjustIndicesByIndex(replaceCharCount - 1, spriteMatch, MatchesList[j]);
|
|
|
+ }
|
|
|
+
|
|
|
+ StringBuilder stringBuilder = new StringBuilder();
|
|
|
+ for (int j = 0; j < replaceCharCount; j++)
|
|
|
+ {
|
|
|
+ stringBuilder.Append(SpriteReplaceChar);
|
|
|
+ }
|
|
|
+ newText = newText.Replace(spriteMatch.StartIndex, spriteMatch.Length, stringBuilder.ToString());
|
|
|
+
|
|
|
+ spriteMatch.SpriteInfo = spriteInfo;
|
|
|
+ spriteMatch.ReplaceWidth = replaceCharCount*replaceCharWidth;
|
|
|
+ spriteMatch.ScaledWidth = scaledWidth;
|
|
|
+ spriteMatch.EndIndex += replaceCharCount - 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void CalculateSpriteMatchPosition(List<BaseMatch> spriteMatches, List<BaseMatch> stashSpriteMatches, float replaceCharWidth, ref string newText/*, bool fillTruncate*/)
|
|
|
+ {
|
|
|
+ float changeLineAccuracy = replaceCharWidth/5;
|
|
|
+ //bool isTextChanged = false;
|
|
|
+ TextGenerationSettings settings = GetGenerationSettings(rectTransform.rect.size);
|
|
|
+ settings.textAnchor = alignment;
|
|
|
+ CalculateTextGenerator = new TextGenerator();
|
|
|
+ CalculateTextGenerator.Populate(newText, settings);
|
|
|
+ AdjustVerts(CalculateTextGenerator.verts);
|
|
|
+ //if (IsSpritesOutOfBound(spriteMatches))
|
|
|
+ //{
|
|
|
+ // UnityEngine.Debug.LogWarning("文本框过小");
|
|
|
+ // if (!fillTruncate)
|
|
|
+ // {
|
|
|
+ // StashSpriteMatch(0, spriteMatches, stashSpriteMatches);
|
|
|
+ // }
|
|
|
+ // return false;
|
|
|
+ //}
|
|
|
+ for (int i = 0; i < spriteMatches.Count; i++)
|
|
|
+ {
|
|
|
+ SpriteMatch spriteMatch = spriteMatches[i] as SpriteMatch;
|
|
|
+ //print(CalculateTextGenerator.lineCount);
|
|
|
+ int lineIndex = GetLineIndex(CalculateTextGenerator, spriteMatch.StartIndex);
|
|
|
+ int lineStartCharacterIndex;
|
|
|
+ int lineEndCharacterIndex;
|
|
|
+ if (lineIndex != -1)
|
|
|
+ {
|
|
|
+ lineStartCharacterIndex = CalculateTextGenerator.lines[lineIndex].startCharIdx;
|
|
|
+ lineEndCharacterIndex = GetLineEndCharacterIndex(CalculateTextGenerator, lineIndex, newText.Length);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ lineStartCharacterIndex = -1;
|
|
|
+ lineEndCharacterIndex = -1;
|
|
|
+ }
|
|
|
+ //int lineCharacterCount = lineEndCharacterIndex - lineStartCharacterIndex;
|
|
|
+ //print(spriteMatch.EndIndex);
|
|
|
+ //print(lineEndCharacterIndex);
|
|
|
+ if (spriteMatch.EndIndex > lineEndCharacterIndex) //被Truncate
|
|
|
+ {
|
|
|
+ //if (!fillTruncate)
|
|
|
+ //{
|
|
|
+ StashSpriteMatch(i, spriteMatches, stashSpriteMatches);
|
|
|
+ //}
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ List<BaseMatch> matches = GetMatchesInLine(spriteMatches, CalculateTextGenerator, lineIndex, lineEndCharacterIndex);
|
|
|
+ if (matches.Count == 1)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ else if (matches.Count > 1)
|
|
|
+ {
|
|
|
+ bool changeLine = false;
|
|
|
+ if (spriteMatch.ReplaceWidth > rectTransform.rect.width) //图片太大 需要换行
|
|
|
+ {
|
|
|
+ if (i < spriteMatches.Count - 1)
|
|
|
+ {
|
|
|
+ i++;
|
|
|
+ spriteMatch = spriteMatches[i] as SpriteMatch;
|
|
|
+ changeLine = true;
|
|
|
+ //isTextChanged = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ float leftMargin = rectTransform.rect.xMin - CalculateTextGenerator.verts[0 + lineStartCharacterIndex * 4].position.x;
|
|
|
+ float rightMargin = CalculateTextGenerator.verts[1 + lineEndCharacterIndex * 4].position.x - rectTransform.rect.xMax;
|
|
|
+ float horizontalMargin = CalculateTextGenerator.verts[1 + lineEndCharacterIndex * 4].position.x - CalculateTextGenerator.verts[0 + lineStartCharacterIndex * 4].position.x - rectTransform.rect.width;
|
|
|
+ if (alignment == TextAnchor.LowerLeft || alignment == TextAnchor.MiddleLeft || alignment == TextAnchor.UpperLeft)
|
|
|
+ {
|
|
|
+ if (leftMargin <= 0 && rightMargin > changeLineAccuracy)
|
|
|
+ {
|
|
|
+ //向右突出
|
|
|
+ matches.MySort((match0, match1) => match1.StartIndex > match0.StartIndex);
|
|
|
+ float margin = horizontalMargin;
|
|
|
+ spriteMatch = GetMarginSpriteMatch(matches, margin, replaceCharWidth) as SpriteMatch;
|
|
|
+ i = spriteMatches.IndexOf(spriteMatch);
|
|
|
+ changeLine = true;
|
|
|
+ //isTextChanged = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (alignment == TextAnchor.LowerCenter || alignment == TextAnchor.MiddleCenter || alignment == TextAnchor.UpperCenter)
|
|
|
+ {
|
|
|
+ if (leftMargin > changeLineAccuracy && rightMargin > changeLineAccuracy)
|
|
|
+ {
|
|
|
+ //左右同时突出
|
|
|
+ matches.MySort((match0, match1) => match1.StartIndex > match0.StartIndex);
|
|
|
+ float margin = leftMargin + rightMargin;
|
|
|
+ spriteMatch = GetMarginSpriteMatch(matches, margin, replaceCharWidth) as SpriteMatch;
|
|
|
+ i = spriteMatches.IndexOf(spriteMatch);
|
|
|
+ changeLine = true;
|
|
|
+ //isTextChanged = true;
|
|
|
+ }
|
|
|
+ else if (leftMargin <= 0 && rightMargin > changeLineAccuracy)
|
|
|
+ {
|
|
|
+ //向右突出
|
|
|
+ matches.MySort((match0, match1) => match1.StartIndex > match0.StartIndex);
|
|
|
+ float margin = horizontalMargin;
|
|
|
+ spriteMatch = GetMarginSpriteMatch(matches, margin, replaceCharWidth) as SpriteMatch;
|
|
|
+ i = spriteMatches.IndexOf(spriteMatch);
|
|
|
+ changeLine = true;
|
|
|
+ //isTextChanged = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (alignment == TextAnchor.LowerRight || alignment == TextAnchor.MiddleRight || alignment == TextAnchor.UpperRight)
|
|
|
+ {
|
|
|
+ if (leftMargin > changeLineAccuracy && rightMargin <= 0)
|
|
|
+ {
|
|
|
+ //向左突出
|
|
|
+ matches.MySort((match0, match1) => match1.StartIndex > match0.StartIndex);
|
|
|
+ float margin = leftMargin;
|
|
|
+ spriteMatch = GetMarginSpriteMatch(matches, margin, replaceCharWidth) as SpriteMatch;
|
|
|
+ i = spriteMatches.IndexOf(spriteMatch);
|
|
|
+ changeLine = true;
|
|
|
+ //isTextChanged = true;
|
|
|
+ }
|
|
|
+ else if (leftMargin <= 0 && rightMargin > changeLineAccuracy)
|
|
|
+ {
|
|
|
+ //向右突出
|
|
|
+ matches.MySort((match0, match1) => match1.StartIndex > match0.StartIndex);
|
|
|
+ float margin = horizontalMargin;
|
|
|
+ spriteMatch = GetMarginSpriteMatch(matches, margin, replaceCharWidth) as SpriteMatch;
|
|
|
+ i = spriteMatches.IndexOf(spriteMatch);
|
|
|
+ changeLine = true;
|
|
|
+ //isTextChanged = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (changeLine)
|
|
|
+ {
|
|
|
+ lineIndex++;
|
|
|
+ if (lineIndex < GetMaxLineCount()) //换行后不被Truncate
|
|
|
+ {
|
|
|
+ newText = newText.Insert(spriteMatch.StartIndex, "\n");
|
|
|
+ for (int j = 0; j < MatchesList.Count; j++)
|
|
|
+ {
|
|
|
+ AdjustIndicesByIndex(1, spriteMatch, MatchesList[j]);
|
|
|
+ }
|
|
|
+ spriteMatch.StartIndex += 1;
|
|
|
+ spriteMatch.EndIndex += 1;
|
|
|
+
|
|
|
+ CalculateTextGenerator = new TextGenerator();
|
|
|
+ CalculateTextGenerator.Populate(newText, settings);
|
|
|
+ AdjustVerts(CalculateTextGenerator.verts);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //if (fillTruncate)
|
|
|
+ //{
|
|
|
+ // stashSpriteMatches.Add(spriteMatch);
|
|
|
+ // spriteMatches.Remove(spriteMatch);
|
|
|
+ //}
|
|
|
+ }
|
|
|
+ //return isTextChanged;
|
|
|
+ }
|
|
|
+
|
|
|
+ //private bool IsSpritesOutOfBound(List<BaseMatch> spriteMatches)
|
|
|
+ //{
|
|
|
+ // for (int i = 0; i < spriteMatches.Count; i++)
|
|
|
+ // {
|
|
|
+ // SpriteMatch spriteMatch = spriteMatches[i] as SpriteMatch;
|
|
|
+ // if (spriteMatch.ReplaceWidth > rectTransform.rect.width)
|
|
|
+ // {
|
|
|
+ // return true;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // return false;
|
|
|
+ //}
|
|
|
+
|
|
|
+ private void StashSpriteMatch(int startIndex, List<BaseMatch> spriteMatches, List<BaseMatch> stashSpriteMatches)
|
|
|
+ {
|
|
|
+ for (int i = startIndex; i < spriteMatches.Count; i++)
|
|
|
+ {
|
|
|
+ stashSpriteMatches.Add(spriteMatches[i]);
|
|
|
+ spriteMatches.Remove(spriteMatches[i]);
|
|
|
+ i--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<BaseMatch> GetMatchesInLine(List<BaseMatch> matches, TextGenerator textGenerator, int lineIndex, int endCharacterIndex)
|
|
|
+ {
|
|
|
+ List<BaseMatch> result = new List<BaseMatch>();
|
|
|
+ foreach (var match in matches)
|
|
|
+ {
|
|
|
+ if (match.StartIndex > endCharacterIndex)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ int matchLineIndex = GetLineIndex(textGenerator, match.StartIndex);
|
|
|
+ if (matchLineIndex == lineIndex)
|
|
|
+ {
|
|
|
+ result.Add(match);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private BaseMatch GetMarginSpriteMatch(List<BaseMatch> matches, float margin, float replaceCharWidth)
|
|
|
+ {
|
|
|
+ foreach (var match in matches)
|
|
|
+ {
|
|
|
+ margin -= replaceCharWidth * match.Length;
|
|
|
+ if (margin <= 0)
|
|
|
+ {
|
|
|
+ return match;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ throw new Exception();
|
|
|
+ }
|
|
|
+
|
|
|
+ //private bool IsCharacterTruncated(TextGenerator textGenerator, int characterIndex)
|
|
|
+ //{
|
|
|
+ // print(textGenerator.characterCount - 1);
|
|
|
+ // print(characterIndex + 1);
|
|
|
+ // if (textGenerator.characterCount - 1 < characterIndex + 1)
|
|
|
+ // {
|
|
|
+ // return true;
|
|
|
+ // }
|
|
|
+ // else
|
|
|
+ // {
|
|
|
+ // return false;
|
|
|
+ // }
|
|
|
+ //}
|
|
|
+
|
|
|
+ private void HandleTransferSpaceMatch(VertexHelper toFill, List<UIVertex> vertices)
|
|
|
+ {
|
|
|
+ foreach (var transferSpaceMatch in TransferSpaceMatches)
|
|
|
+ {
|
|
|
+ int index0 = 0 + transferSpaceMatch.StartIndex * 4;
|
|
|
+ int index1 = 1 + transferSpaceMatch.EndIndex * 4;
|
|
|
+ int index2 = 2 + transferSpaceMatch.EndIndex * 4;
|
|
|
+ int index3 = 3 + transferSpaceMatch.StartIndex * 4;
|
|
|
+ UIVertex vertex0 = vertices[index0];
|
|
|
+ UIVertex vertex1 = vertices[index1];
|
|
|
+ UIVertex vertex2 = vertices[index2];
|
|
|
+ UIVertex vertex3 = vertices[index3];
|
|
|
+ vertex0.color = new Color32(0, 0, 0, 0);
|
|
|
+ vertex1.color = new Color32(0, 0, 0, 0);
|
|
|
+ vertex2.color = new Color32(0, 0, 0, 0);
|
|
|
+ vertex3.color = new Color32(0, 0, 0, 0);
|
|
|
+ vertices[index0] = vertex0;
|
|
|
+ vertices[index1] = vertex1;
|
|
|
+ vertices[index2] = vertex2;
|
|
|
+ vertices[index3] = vertex3;
|
|
|
+ toFill.SetUIVertex(vertex0, index0);
|
|
|
+ toFill.SetUIVertex(vertex1, index1);
|
|
|
+ toFill.SetUIVertex(vertex2, index2);
|
|
|
+ toFill.SetUIVertex(vertex3, index3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public string GetUnparsedText()
|
|
|
+ {
|
|
|
+ List<BaseMatch> matches = new List<BaseMatch>();
|
|
|
+ matches.AddRange(TransferSpaceMatches);
|
|
|
+ matches.AddRange(AvailableSpriteMatches);
|
|
|
+ matches.AddRange(UnderlineMatches);
|
|
|
+ matches.AddRange(SuperlinkMatches);
|
|
|
+ matches.MySort((match0, match1) => match1.StartIndex > match0.StartIndex);
|
|
|
+ string result = text;
|
|
|
+ foreach (var baseMatch in matches)
|
|
|
+ {
|
|
|
+ if (baseMatch is TransferSpaceMatch)
|
|
|
+ {
|
|
|
+ result = result.Insert(baseMatch.StartIndex, "\\");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ string openPattern = baseMatch.MatchData.OpenPattern;
|
|
|
+ string idPattern = IDPattern.Replace("\\d+", baseMatch.ID.ToString());
|
|
|
+ idPattern = idPattern.Replace("\\", "");
|
|
|
+ string closePattern = baseMatch.MatchData.ClosePattern;
|
|
|
+ result = result.Insert(baseMatch.StartIndex + baseMatch.EndIndex, idPattern + closePattern);
|
|
|
+ result = result.Insert(baseMatch.StartIndex, openPattern);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private Vector3[] GetLocalCorners()
|
|
|
+ {
|
|
|
+ Vector3[] corners = new Vector3[4];
|
|
|
+ rectTransform.GetLocalCorners(corners);
|
|
|
+ return corners;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Vector3[] GetWorldCorners()
|
|
|
+ {
|
|
|
+ Vector3[] corners = new Vector3[4];
|
|
|
+ rectTransform.GetWorldCorners(corners);
|
|
|
+ return corners;
|
|
|
+ }
|
|
|
+
|
|
|
+ private float GetKerning(char c0, char c1)
|
|
|
+ {
|
|
|
+ TextGenerator textGenerator = new TextGenerator(0);
|
|
|
+ textGenerator.Populate(string.Format("{0}{1}", c0, c1), GetGenerationSettings(rectTransform.rect.size));
|
|
|
+ //AdjustVerts(textGenerator.verts);
|
|
|
+ float kerning = textGenerator.verts[4].position.x - textGenerator.verts[1].position.x;
|
|
|
+ kerning /= canvas.scaleFactor;
|
|
|
+ return kerning;
|
|
|
+ //return textGenerator.verts[4].position.x - textGenerator.verts[1].position.x;
|
|
|
+ }
|
|
|
+
|
|
|
+ private float GetCharacterHeight(char c)
|
|
|
+ {
|
|
|
+ TextGenerator textGenerator = new TextGenerator(0);
|
|
|
+ textGenerator.Populate(c.ToString(), GetGenerationSettings(rectTransform.rect.size));
|
|
|
+ //AdjustVerts(textGenerator.verts);
|
|
|
+ float height = textGenerator.verts[0].position.y - textGenerator.verts[2].position.y;
|
|
|
+ height /= canvas.scaleFactor;
|
|
|
+ return height;
|
|
|
+ //return textGenerator.verts[0].position.y - textGenerator.verts[2].position.y;
|
|
|
+ }
|
|
|
+
|
|
|
+ private float GetCharacterWidth(char c)
|
|
|
+ {
|
|
|
+ TextGenerator textGenerator = new TextGenerator(0);
|
|
|
+ textGenerator.Populate(c.ToString(), GetGenerationSettings(rectTransform.rect.size));
|
|
|
+ //AdjustVerts(textGenerator.verts);
|
|
|
+ float width = textGenerator.verts[1].position.x - textGenerator.verts[0].position.x;
|
|
|
+ width /= canvas.scaleFactor;
|
|
|
+ return width;
|
|
|
+ //return textGenerator.verts[1].position.x - textGenerator.verts[0].position.x;
|
|
|
+ }
|
|
|
+
|
|
|
+ public float GetPenPositionY(int lineIndex, int lineCount)
|
|
|
+ {
|
|
|
+ StringBuilder stringBuilder = new StringBuilder();
|
|
|
+ for (int i = 0; i < lineCount; i++)
|
|
|
+ {
|
|
|
+ stringBuilder.Append(CalculateReferenceChar);
|
|
|
+ if (i < lineCount - 1)
|
|
|
+ {
|
|
|
+ stringBuilder.Append("\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ TextGenerator textGenerator = new TextGenerator();
|
|
|
+ textGenerator.Populate(stringBuilder.ToString(), GetGenerationSettings(rectTransform.rect.size));
|
|
|
+ AdjustVerts(textGenerator.verts);
|
|
|
+ return textGenerator.verts[2 + lineIndex*8].position.y;
|
|
|
+ }
|
|
|
+
|
|
|
+ public float GetLineCenterY(int lineIndex, int lineCount)
|
|
|
+ {
|
|
|
+ StringBuilder stringBuilder = new StringBuilder();
|
|
|
+ for (int i = 0; i < lineCount; i++)
|
|
|
+ {
|
|
|
+ stringBuilder.Append(CalculateReferenceChar);
|
|
|
+ if (i < lineCount - 1)
|
|
|
+ {
|
|
|
+ stringBuilder.Append("\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ TextGenerator textGenerator = new TextGenerator();
|
|
|
+ textGenerator.Populate(stringBuilder.ToString(), GetGenerationSettings(rectTransform.rect.size));
|
|
|
+ AdjustVerts(textGenerator.verts);
|
|
|
+ return (textGenerator.verts[0 + lineIndex*8].position.y + textGenerator.verts[2 + lineIndex*8].position.y)/2;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int GetLineIndex(TextGenerator textGenerator, int charIndex)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < textGenerator.lines.Count; i++)
|
|
|
+ {
|
|
|
+ if (charIndex >= textGenerator.lines.Back(i).startCharIdx)
|
|
|
+ {
|
|
|
+ return textGenerator.lines.Count - 1 - i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int GetMaxLineCount()
|
|
|
+ {
|
|
|
+ TextGenerationSettings settings = GetGenerationSettings(rectTransform.rect.size);
|
|
|
+ settings.textAnchor = alignment;
|
|
|
+ CalculateTextGenerator = new TextGenerator();
|
|
|
+ int lineCount = 0;
|
|
|
+ StringBuilder stringBuilder = new StringBuilder();
|
|
|
+ while (CalculateTextGenerator.GetPreferredHeight(stringBuilder.ToString(), settings) / canvas.scaleFactor < rectTransform.rect.height)
|
|
|
+ {
|
|
|
+ lineCount++;
|
|
|
+ stringBuilder.Append("\n");
|
|
|
+ }
|
|
|
+ return lineCount;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int GetLineEndCharacterIndex(TextGenerator textGenerator, int lineIndex, int realCharacterCount)
|
|
|
+ {
|
|
|
+ if (lineIndex >= textGenerator.lines.Count)
|
|
|
+ {
|
|
|
+ throw new Exception();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (textGenerator.lines.Count == 1 || lineIndex == textGenerator.lines.Count - 1)
|
|
|
+ {
|
|
|
+ if (textGenerator.characterCount - 1 == realCharacterCount) //TextGenerator会自动在结尾添加换行符
|
|
|
+ {
|
|
|
+ return realCharacterCount - 1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return textGenerator.characterCount - 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return textGenerator.lines[lineIndex + 1].startCharIdx - 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public int GetLineCharacterCount(TextGenerator textGenerator, int lineIndex)
|
|
|
+ {
|
|
|
+ if (lineIndex >= textGenerator.lines.Count)
|
|
|
+ {
|
|
|
+ throw new Exception();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (textGenerator.lines.Count == 1)
|
|
|
+ {
|
|
|
+ return textGenerator.characterCount;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (lineIndex == textGenerator.lines.Count - 1)
|
|
|
+ {
|
|
|
+ return textGenerator.characterCount - textGenerator.lines.Back(0).startCharIdx;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return textGenerator.lines[lineIndex + 1].startCharIdx - textGenerator.lines[lineIndex].startCharIdx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public float GetLineMaxY(TextGenerator textGenerator, int lineIndex)
|
|
|
+ {
|
|
|
+ float lineCenterY = GetLineCenterY(lineIndex, textGenerator.lineCount);
|
|
|
+ float lineHeight = textGenerator.lines[lineIndex].height;
|
|
|
+ return lineCenterY + lineHeight/2;
|
|
|
+ }
|
|
|
+
|
|
|
+ public float GetLineMinY(TextGenerator textGenerator, int lineIndex)
|
|
|
+ {
|
|
|
+ float lineCenterY = GetLineCenterY(lineIndex, textGenerator.lineCount);
|
|
|
+ float lineHeight = textGenerator.lines[lineIndex].height;
|
|
|
+ return lineCenterY - lineHeight/2;
|
|
|
+ }
|
|
|
+
|
|
|
+ public float GetLineTopY(TextGenerator textGenerator, int lineIndex)
|
|
|
+ {
|
|
|
+ return textGenerator.lines[lineIndex].topY;
|
|
|
+ }
|
|
|
+
|
|
|
+ public float GetLineBottomY(TextGenerator textGenerator, int lineIndex)
|
|
|
+ {
|
|
|
+ return textGenerator.lines[lineIndex].topY - textGenerator.lines[lineIndex].height;
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool IsSameLine(TextGenerator textGenerator, int charIndex0, int charIndex1)
|
|
|
+ {
|
|
|
+ if (textGenerator.lines.Count == 1)
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for (int i = 0; i < textGenerator.lines.Count - 1; i++)
|
|
|
+ {
|
|
|
+ if ((charIndex0 >= textGenerator.lines[i].startCharIdx && charIndex0 < textGenerator.lines[i + 1].startCharIdx) && charIndex1 >= textGenerator.lines[i + 1].startCharIdx)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void AdjustVerts(IList<UIVertex> verts) //取自UGUI源代码
|
|
|
+ {
|
|
|
+ float unitsPerPixel = 1/pixelsPerUnit;
|
|
|
+ int vertCount = verts.Count - 4;
|
|
|
+
|
|
|
+ Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y)*unitsPerPixel;
|
|
|
+ roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset;
|
|
|
+ if (roundingOffset != Vector2.zero)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < vertCount; ++i)
|
|
|
+ {
|
|
|
+ UIVertex vertex = verts[i];
|
|
|
+ vertex.position *= unitsPerPixel;
|
|
|
+ vertex.position.x += roundingOffset.x;
|
|
|
+ vertex.position.y += roundingOffset.y;
|
|
|
+ verts[i] = vertex;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for (int i = 0; i < vertCount; ++i)
|
|
|
+ {
|
|
|
+ UIVertex vertex = verts[i];
|
|
|
+ vertex.position *= unitsPerPixel;
|
|
|
+ verts[i] = vertex;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void AdjustIndicesByIndex(int indexOffset, BaseMatch referenceMatch, List<BaseMatch> adjusteeMatches)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < adjusteeMatches.Count; i++)
|
|
|
+ {
|
|
|
+ BaseMatch adjusteeMatch = adjusteeMatches[i];
|
|
|
+ if (referenceMatch == adjusteeMatch) continue;
|
|
|
+ if (referenceMatch.StartIndex < adjusteeMatch.StartIndex) //referenceIndex-adjusteeMatch-adjusteeMatch
|
|
|
+ {
|
|
|
+ adjusteeMatch.StartIndex += indexOffset;
|
|
|
+ adjusteeMatch.EndIndex += indexOffset;
|
|
|
+ }
|
|
|
+ else if (referenceMatch.StartIndex < adjusteeMatch.EndIndex) //adjusteeMatch-referenceIndex-adjusteeMatch
|
|
|
+ {
|
|
|
+ adjusteeMatch.EndIndex += indexOffset;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void AdjustIndicesByMatch(int extraOffset, BaseMatch referenceMatch, List<BaseMatch> adjusteeMatches)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < adjusteeMatches.Count; i++)
|
|
|
+ {
|
|
|
+ BaseMatch adjusteeMatch = adjusteeMatches[i];
|
|
|
+ if (referenceMatch == adjusteeMatch) continue;
|
|
|
+ if (referenceMatch.StartIndex < adjusteeMatch.EndIndex) //排除 adjusteeMatch...adjusteeMatch...refeMatch-refeMatch
|
|
|
+ {
|
|
|
+ if (referenceMatch.EndIndex < adjusteeMatch.StartIndex) //refeMatch-refeMatch...adjusteeMatch-adjusteeMatch
|
|
|
+ {
|
|
|
+ int indexOffset = -referenceMatch.MatchData.OpenPatternLength - referenceMatch.MatchData.ClosePatternLength + extraOffset;
|
|
|
+ adjusteeMatch.StartIndex += indexOffset;
|
|
|
+ adjusteeMatch.EndIndex += indexOffset;
|
|
|
+ }
|
|
|
+ else if (referenceMatch.EndIndex < adjusteeMatch.EndIndex) //refeMatch...adjusteeMatch...refeMatch...adjusteeMatch
|
|
|
+ {
|
|
|
+ int indexOffset = -referenceMatch.MatchData.ClosePatternLength + extraOffset;
|
|
|
+ adjusteeMatch.StartIndex += indexOffset;
|
|
|
+ adjusteeMatch.EndIndex += indexOffset;
|
|
|
+ }
|
|
|
+ else if (referenceMatch.EndIndex > adjusteeMatch.EndIndex) //adjusteeMatch...refeMatch...adjusteeMatch...refeMatch
|
|
|
+ {
|
|
|
+ int indexOffset = -referenceMatch.MatchData.OpenPatternLength + extraOffset;
|
|
|
+ adjusteeMatch.StartIndex += indexOffset;
|
|
|
+ adjusteeMatch.EndIndex += indexOffset;
|
|
|
+ }
|
|
|
+ //不应该出现的情况refeMatch...adjusteeMatch-adjusteeMatch...refeMatch adjusteeMatch...refeMatch...refeMatch...adjusteeMatch
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void GetSegments<T>(string newText, TextGenerator textGenerator, T match, List<char> excludeChars) where T : SegmentMatch
|
|
|
+ {
|
|
|
+ //print(excludeChars.Count);
|
|
|
+ if (textGenerator.lines.Count == 1)
|
|
|
+ {
|
|
|
+ match.Segments.Add(new List<int> {match.StartIndex, match.EndIndex});
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ int endLineIndex;
|
|
|
+ int startLineIndex;
|
|
|
+ for (int i = 0; i < textGenerator.lines.Count; i++)
|
|
|
+ {
|
|
|
+ startLineIndex = textGenerator.lines.Count - 1 - i;
|
|
|
+ if (match.StartIndex >= textGenerator.lines[startLineIndex].startCharIdx)
|
|
|
+ {
|
|
|
+ if (startLineIndex == textGenerator.lines.Count - 1)
|
|
|
+ {
|
|
|
+ match.Segments.Add(new List<int> {match.StartIndex, match.EndIndex});
|
|
|
+ goto jumpOut;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (match.EndIndex >= textGenerator.lines.Back(0).startCharIdx)
|
|
|
+ {
|
|
|
+ endLineIndex = textGenerator.lines.Count - 1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for (int j = startLineIndex; j < textGenerator.lines.Count; j++)
|
|
|
+ {
|
|
|
+ if (match.EndIndex < textGenerator.lines[j + 1].startCharIdx)
|
|
|
+ {
|
|
|
+ if (j == startLineIndex)
|
|
|
+ {
|
|
|
+ match.Segments.Add(new List<int> {match.StartIndex, match.EndIndex});
|
|
|
+ goto jumpOut;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ endLineIndex = j;
|
|
|
+ goto segment;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ throw new Exception();
|
|
|
+ }
|
|
|
+ segment:
|
|
|
+ int segmentCount = endLineIndex - startLineIndex + 1;
|
|
|
+ match.Segments.Add(new List<int> {match.StartIndex, textGenerator.lines[startLineIndex + 1].startCharIdx - 1}); //第一段
|
|
|
+ match.Segments.Add(new List<int> {textGenerator.lines[endLineIndex].startCharIdx, match.EndIndex}); //最后一段
|
|
|
+ for (int k = 0; k < segmentCount - 2; k++)
|
|
|
+ {
|
|
|
+ match.Segments.Add(new List<int> {textGenerator.lines[startLineIndex + 1 + k].startCharIdx, textGenerator.lines[startLineIndex + 2 + k].startCharIdx - 1});
|
|
|
+ }
|
|
|
+ goto jumpOut;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ jumpOut:
|
|
|
+
|
|
|
+ //for (int i = 0; i < match.Segments.Count; i++)
|
|
|
+ //{
|
|
|
+ // Debug.LogWarning(match.Segments[i][0] + "\t" + match.Segments[i][1]);
|
|
|
+ //}
|
|
|
+
|
|
|
+ exclude:
|
|
|
+ for (int i = 0; i < match.Segments.Count; i++)
|
|
|
+ {
|
|
|
+ int startIndex = match.Segments[i][0];
|
|
|
+ int endIndex = match.Segments[i][1];
|
|
|
+ for (int j = startIndex; j <= endIndex; j++)
|
|
|
+ {
|
|
|
+ //print((int)newText[j]);
|
|
|
+ if (excludeChars.Contains(newText[j]))
|
|
|
+ {
|
|
|
+ if (j == startIndex)
|
|
|
+ {
|
|
|
+ //Debug.Log("start " + match.Segments[i][0] + "\t" + match.Segments[i][1]);
|
|
|
+ //Debug.Log(j);
|
|
|
+ //newText = newText.Remove(startIndex, 1);
|
|
|
+ match.Segments[i][0] = startIndex + 1;
|
|
|
+ //Debug.Log("start " + match.Segments[i][0] + "\t" + match.Segments[i][1]);
|
|
|
+ }
|
|
|
+ else if (j == endIndex)
|
|
|
+ {
|
|
|
+ //Debug.Log("end " + match.Segments[i][0] + "\t" + match.Segments[i][1]);
|
|
|
+ //Debug.Log(j);
|
|
|
+ //newText = newText.Remove(endIndex, 1);
|
|
|
+ match.Segments[i][1] = endIndex - 1;
|
|
|
+ //Debug.Log("end " + match.Segments[i][0] + "\t" + match.Segments[i][1]);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //Debug.Log(j);
|
|
|
+ //newText = newText.Remove(j, 1);
|
|
|
+ //Debug.Log("remove " + match.Segments[i][0] + "\t" + match.Segments[i][1]);
|
|
|
+ match.Segments.RemoveAt(i);
|
|
|
+ match.Segments.Insert(0, new List<int> {startIndex, j - 1});
|
|
|
+ //Debug.Log("add " + match.Segments[0][0] + "\t" + match.Segments[0][1]);
|
|
|
+ match.Segments.Insert(0, new List<int> {j + 1, endIndex});
|
|
|
+ //Debug.Log("add " + match.Segments[0][0] + "\t" + match.Segments[0][1]);
|
|
|
+ }
|
|
|
+ goto exclude;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < match.Segments.Count; i++)
|
|
|
+ {
|
|
|
+ if (match.Segments[i][1] < match.Segments[i][0])
|
|
|
+ {
|
|
|
+ match.Segments.RemoveAt(i--);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //for (int i = 0; i < match.Segments.Count; i++)
|
|
|
+ //{
|
|
|
+ // Debug.Log(match.Segments[i][0] + "\t" + match.Segments[i][1]);
|
|
|
+ //}
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private int GetVerticalBestfitFontSize(string newText)
|
|
|
+ {
|
|
|
+ int antiCrush = 0;
|
|
|
+ TextGenerationSettings settings = GetGenerationSettings(rectTransform.rect.size);
|
|
|
+ List<int> leftSizes = new List<int> {resizeTextMinSize};
|
|
|
+ List<int> rightSizes = new List<int> {resizeTextMaxSize};
|
|
|
+ settings.fontSize = (leftSizes[0] + rightSizes[0])/2;
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ if (antiCrush++ > 300)
|
|
|
+ {
|
|
|
+ throw new Exception("Crush");
|
|
|
+ }
|
|
|
+
|
|
|
+ float preferredHeight = cachedTextGenerator.GetPreferredHeight(newText, settings);
|
|
|
+ if (preferredHeight > rectTransform.rect.size.y*canvas.scaleFactor)
|
|
|
+ {
|
|
|
+ rightSizes.Add(settings.fontSize);
|
|
|
+ settings.fontSize = (leftSizes[leftSizes.Count - 1] + settings.fontSize)/2;
|
|
|
+ }
|
|
|
+ else if (preferredHeight < rectTransform.rect.size.y*canvas.scaleFactor)
|
|
|
+ {
|
|
|
+ if (leftSizes.Contains(settings.fontSize))
|
|
|
+ {
|
|
|
+ return settings.fontSize;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ leftSizes.Add(settings.fontSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ settings.fontSize = (rightSizes[rightSizes.Count - 1] + settings.fontSize)/2;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return settings.fontSize;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void ApplyVerticalBestfitSize()
|
|
|
+ {
|
|
|
+ resizeTextMinSize = MinSize;
|
|
|
+ resizeTextMaxSize = MaxSize;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void DisableOriginBestfit()
|
|
|
+ {
|
|
|
+ resizeTextForBestFit = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void EnableVerticalBestfit()
|
|
|
+ {
|
|
|
+ UseOriginBestfit = resizeTextForBestFit;
|
|
|
+ MinSize = resizeTextMinSize;
|
|
|
+ MaxSize = resizeTextMaxSize;
|
|
|
+ UseVerticalBestfit = true;
|
|
|
+ VerticalBestfitDirty = true;
|
|
|
+ DisableOriginBestfit();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void DisableVerticalBestfit()
|
|
|
+ {
|
|
|
+ resizeTextForBestFit = UseOriginBestfit;
|
|
|
+ UseVerticalBestfit = false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private bool ParseAndFillMatches(ref string newText)
|
|
|
+ {
|
|
|
+ bool haveMatch = ParseMatches(ref newText);
|
|
|
+ if (haveMatch)
|
|
|
+ {
|
|
|
+ FillSpriteMatches(AvailableSpriteMatches, TruncateSpriteMatches, ref newText);
|
|
|
+ }
|
|
|
+ return haveMatch;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void EnableDebugMode()
|
|
|
+ {
|
|
|
+ //TextGenerationSettings settings = GetGenerationSettings(rectTransform.rect.size);
|
|
|
+ //settings.textAnchor = alignment;
|
|
|
+ //CalculateTextGenerator = new TextGenerator();
|
|
|
+ //print(CalculateTextGenerator.GetPreferredHeight("", settings) / canvas.scaleFactor);
|
|
|
+
|
|
|
+ //print(cachedTextGenerator.characterCount);
|
|
|
+ //print(cachedTextGenerator.lineCount);
|
|
|
+
|
|
|
+ Debug = true;
|
|
|
+ Content = text;
|
|
|
+ SetVerticesDirty();
|
|
|
+ SetLayoutDirty();
|
|
|
+ //string newText = Content;
|
|
|
+ //if (ParseAndFillMatches(ref newText))
|
|
|
+ //{
|
|
|
+ // AddNewOpenCloseMatch(newText);
|
|
|
+ //}
|
|
|
+ }
|
|
|
+
|
|
|
+ public void DisableDebugMode()
|
|
|
+ {
|
|
|
+ Debug = false;
|
|
|
+ text = Content;
|
|
|
+ ClearMatches();
|
|
|
+ ImageManager.ClearRenderTask();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public void OnPointerClick(PointerEventData eventData)
|
|
|
+ {
|
|
|
+ //Vector3 clickPosition = eventData.position;
|
|
|
+ //Debug.Log(clickPosition);
|
|
|
+ OnPointerClick(eventData.position);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Dictionary<int, List<List<Vector3>>> SuperlinkPositionsDictionary = new Dictionary<int, List<List<Vector3>>>();
|
|
|
+ public void OnPointerClick(Vector3 worldPosition)
|
|
|
+ {
|
|
|
+ SuperlinkPositionsDictionary = new Dictionary<int, List<List<Vector3>>>();
|
|
|
+ foreach (var match in SuperlinkMatches)
|
|
|
+ {
|
|
|
+ SuperlinkMatch superlinkMatch = (SuperlinkMatch) match;
|
|
|
+ SuperlinkPositionsDictionary.Add(superlinkMatch.ID, superlinkMatch.RectanglePositionsList);
|
|
|
+ }
|
|
|
+
|
|
|
+ Vector3 clickPosition = worldPosition;
|
|
|
+ //Vector3 clickPosition = rectTransform.InverseTransformPoint(worldPosition);
|
|
|
+ foreach (var kv in SuperlinkPositionsDictionary)
|
|
|
+ {
|
|
|
+ foreach (var positions in kv.Value)
|
|
|
+ {
|
|
|
+ float minX = positions.MyMin(vector => vector.x).x;
|
|
|
+ float maxX = positions.MyMax(vector => vector.x).x;
|
|
|
+ float minY = positions.MyMin(vector => vector.y).y;
|
|
|
+ float maxY = positions.MyMax(vector => vector.y).y;
|
|
|
+ //UnityEngine.Debug.Log(clickPosition);
|
|
|
+ //UnityEngine.Debug.Log(minX + " " + maxX + " " + minY + " " + maxY);
|
|
|
+ if ((minX <= clickPosition.x && clickPosition.x <= maxX) && (minY <= clickPosition.y && clickPosition.y <= maxY))
|
|
|
+ {
|
|
|
+ if (SuperlinkCallbackDictionary.ContainsKey(kv.Key))
|
|
|
+ {
|
|
|
+ SuperlinkCallbackDictionary[kv.Key].Invoke(kv.Key);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ UnityEngine.Debug.LogWarning(string.Format("没有找到事件 id : {0}", kv.Key));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|