From 83b3fbd9e0871eec25f91dad4ba225d956c62b86 Mon Sep 17 00:00:00 2001 From: cjsjy123 Date: Thu, 5 Jul 2018 10:30:44 +0800 Subject: [PATCH 01/12] back up --- Assets/TextInlineSprite/Scripts/InlineText.cs | 35 +++++----- Assets/TextInlineSprite/Scripts/Parser.meta | 9 +++ .../Scripts/Parser/IParser.cs | 13 ++++ .../Scripts/Parser/IParser.cs.meta | 12 ++++ .../Scripts/Parser/ParserTransmit.cs | 40 +++++++++++ .../Scripts/Parser/ParserTransmit.cs.meta | 12 ++++ .../TextInlineSprite/Scripts/PriorityQueue.cs | 67 +++++++++++++++++++ .../Scripts/PriorityQueue.cs.meta | 12 ++++ 8 files changed, 183 insertions(+), 17 deletions(-) create mode 100644 Assets/TextInlineSprite/Scripts/Parser.meta create mode 100644 Assets/TextInlineSprite/Scripts/Parser/IParser.cs create mode 100644 Assets/TextInlineSprite/Scripts/Parser/IParser.cs.meta create mode 100644 Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs create mode 100644 Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs.meta create mode 100644 Assets/TextInlineSprite/Scripts/PriorityQueue.cs create mode 100644 Assets/TextInlineSprite/Scripts/PriorityQueue.cs.meta diff --git a/Assets/TextInlineSprite/Scripts/InlineText.cs b/Assets/TextInlineSprite/Scripts/InlineText.cs index 4b7026e..c8eaea8 100644 --- a/Assets/TextInlineSprite/Scripts/InlineText.cs +++ b/Assets/TextInlineSprite/Scripts/InlineText.cs @@ -325,7 +325,7 @@ protected override void OnPopulateMesh(VertexHelper toFill) roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset; toFill.Clear(); - ClearQuadUVs(verts); + //ClearQuadUVs(verts); if(RenderTagList != null && RenderTagList.Count >0) { @@ -476,8 +476,9 @@ private void ClearQuadUVs(IList verts) void CalcQuadInfo() { if(RenderTagList != null) - { - for(int i =0; i < RenderTagList.Count;++i) + { + Rect rect = rectTransform.rect; + for(int i = RenderTagList.Count -1; i >= 0;--i) { SpriteTagInfo info = RenderTagList[i]; int pos = info.GetPositionIdx(); @@ -651,8 +652,7 @@ bool ParseEmoji(string newInfo,int Index, int Id, string TagName, Match match, r _textBuilder.Append(newInfo.Substring(_textIndex, match.Index - _textIndex)); int _tempIndex = _textBuilder.Length * 4; - float h = Mathf.Max(1, this.rectTransform.rect.height - 8); - float autosize = Mathf.Min(h, tagSprites.size); + if (_SpaceGen == null) { _SpaceGen = new TextGenerator(); @@ -668,7 +668,10 @@ bool ParseEmoji(string newInfo,int Index, int Id, string TagName, Match match, r IList spaceverts = _SpaceGen.verts; float spacewid = spaceverts[1].position.x - spaceverts[0].position.x; - float spaceheight = spaceverts[0].position.y - spaceverts[3].position.y; + float spaceheight = spaceverts[0].position.y - spaceverts[3].position.y; + + + float autosize = Mathf.Min( tagSprites.size,Mathf.Max(spacewid,spaceheight)); float spacesize = Mathf.Max(spacewid, spaceheight); int fillspacecnt = Mathf.CeilToInt(autosize / spacesize); @@ -676,21 +679,19 @@ bool ParseEmoji(string newInfo,int Index, int Id, string TagName, Match match, r for (int i = 0; i < fillspacecnt; i++) { _textBuilder.Append(palceholder); - } + } + Debug.LogError(autosize); //_textBuilder.AppendFormat("", tagSprites.x, tagSprites.y, autosize, tagSprites.width); if (RenderTagList.Count > Index) { SpriteTagInfo _tempSpriteTag = RenderTagList[Index]; - if(Id != _tempSpriteTag._ID || TagName != _tempSpriteTag._Tag || _tempIndex != _tempSpriteTag.GetPositionIdx()) - { - _tempSpriteTag._ID = Id; - _tempSpriteTag._Tag = TagName; - _tempSpriteTag._Size = new Vector2(autosize * tagSprites.width, autosize); - _tempSpriteTag.FillIdxAndPlaceHolder(_tempIndex, fillspacecnt); - _tempSpriteTag._UV = tagSprites.spritegroups[0].uv; - } + _tempSpriteTag._ID = Id; + _tempSpriteTag._Tag = TagName; + _tempSpriteTag._Size = new Vector2(autosize, autosize); + _tempSpriteTag.FillIdxAndPlaceHolder(_tempIndex, fillspacecnt); + _tempSpriteTag._UV = tagSprites.spritegroups[0].uv; } else { @@ -698,7 +699,7 @@ bool ParseEmoji(string newInfo,int Index, int Id, string TagName, Match match, r { _ID = Id, _Tag = TagName, - _Size = new Vector2(autosize * tagSprites.width, autosize), + _Size = new Vector2(autosize , autosize), _Pos = new Vector3[4], _UV = tagSprites.spritegroups[0].uv }; @@ -718,7 +719,7 @@ bool ParseEmoji(string newInfo,int Index, int Id, string TagName, Match match, r } else if(Manager) { - Debug.LogErrorFormat("not found that atlas:{0} or Tag:{1}", Id, TagName); + //Debug.LogErrorFormat("not found that atlas:{0} or Tag:{1}", Id, TagName); } return false; } diff --git a/Assets/TextInlineSprite/Scripts/Parser.meta b/Assets/TextInlineSprite/Scripts/Parser.meta new file mode 100644 index 0000000..5560624 --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/Parser.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5ef8e4143beba470bbbd3e91315a9102 +folderAsset: yes +timeCreated: 1530756887 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs new file mode 100644 index 0000000..1bfebbb --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs @@ -0,0 +1,13 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace EmojiUI +{ + public interface IParser + { + + } + +} + diff --git a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs.meta b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs.meta new file mode 100644 index 0000000..80bb31d --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6a86b08a896ce4bf090b52ec18622d23 +timeCreated: 1530756905 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs new file mode 100644 index 0000000..3736e89 --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs @@ -0,0 +1,40 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace EmojiUI +{ + public class ParserTransmit + { + + private static ParserTransmit _mins; + + public static ParserTransmit mIns{ + get + { + if(_mins == null) + { + _mins = new ParserTransmit(); + } + return _mins; + } + } + + private struct ParserHistory + { + + } + + public void AddParser(IParser parser) + { + + } + + public void RemoveParser(IParser parser) + { + + } + } +} + + diff --git a/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs.meta b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs.meta new file mode 100644 index 0000000..30d6aab --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 72360e5bd485a4588bd1579231598207 +timeCreated: 1530757609 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TextInlineSprite/Scripts/PriorityQueue.cs b/Assets/TextInlineSprite/Scripts/PriorityQueue.cs new file mode 100644 index 0000000..13088de --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/PriorityQueue.cs @@ -0,0 +1,67 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System; + +namespace EmojiUI +{ + public class PriorityQueue + { + IComparer comparer; + T[] heap; + + public int Count { get; private set; } + + public PriorityQueue() : this(null) { } + public PriorityQueue(int capacity) : this(capacity, null) { } + public PriorityQueue(IComparer comparer) : this(16, comparer) { } + + public PriorityQueue(int capacity, IComparer comparer) + { + this.comparer = (comparer == null) ? Comparer.Default : comparer; + this.heap = new T[capacity]; + } + + public void Push(T v) + { + if (Count >= heap.Length) Array.Resize(ref heap, Count * 2); + heap[Count] = v; + SiftUp(Count++); + } + + public T Pop() + { + var v = Top(); + heap[0] = heap[--Count]; + if (Count > 0) SiftDown(0); + return v; + } + + public T Top() + { + if (Count > 0) return heap[0]; + throw new InvalidOperationException("empty queue"); + } + + void SiftUp(int n) + { + var v = heap[n]; + for (var n2 = n / 2; n > 0 && comparer.Compare(v, heap[n2]) > 0; n = n2, n2 /= 2) heap[n] = heap[n2]; + heap[n] = v; + } + + void SiftDown(int n) + { + var v = heap[n]; + for (var n2 = n * 2; n2 < Count; n = n2, n2 *= 2) + { + if (n2 + 1 < Count && comparer.Compare(heap[n2 + 1], heap[n2]) > 0) n2++; + if (comparer.Compare(v, heap[n2]) >= 0) break; + heap[n] = heap[n2]; + } + heap[n] = v; + } + } +} + + diff --git a/Assets/TextInlineSprite/Scripts/PriorityQueue.cs.meta b/Assets/TextInlineSprite/Scripts/PriorityQueue.cs.meta new file mode 100644 index 0000000..ab47cdb --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/PriorityQueue.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bb748da643a7244768585668a85faed7 +timeCreated: 1530757633 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 9a012b031c9aac0c7e3d1c3196ea5d09721dd672 Mon Sep 17 00:00:00 2001 From: cjsjy123 Date: Thu, 5 Jul 2018 10:58:24 +0800 Subject: [PATCH 02/12] back up --- .../TextInlineSprite/Scripts/AutoContainer.cs | 50 +++++++++++++++++++ .../Scripts/AutoContainer.cs.meta | 12 +++++ .../Scripts/Parser/IParser.cs | 2 + 3 files changed, 64 insertions(+) create mode 100644 Assets/TextInlineSprite/Scripts/AutoContainer.cs create mode 100644 Assets/TextInlineSprite/Scripts/AutoContainer.cs.meta diff --git a/Assets/TextInlineSprite/Scripts/AutoContainer.cs b/Assets/TextInlineSprite/Scripts/AutoContainer.cs new file mode 100644 index 0000000..d6b333a --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/AutoContainer.cs @@ -0,0 +1,50 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace EmojiUI +{ + public class AutoContainer + { +#if UNITY_EDITOR + public static int hot = 100; +#else + public const int hot = 100; +#endif + + private List parsers = new List(8); + + + public void Add(IParser data) + { +#if UNITY_EDITOR + if(parsers.Contains(data)) + { + Debug.LogErrorFormat("has contains it :{0}", data); + } +#endif + + parsers.Add(data); + } + + public bool Remove(IParser data) + { + return parsers.Remove(data); + } + + public void DoStep() + { + bool needfix = false; + for (int i = 0; i < parsers.Count;++i) + { + var data = parsers[i]; + + } + + //reset + + } + } + +} + diff --git a/Assets/TextInlineSprite/Scripts/AutoContainer.cs.meta b/Assets/TextInlineSprite/Scripts/AutoContainer.cs.meta new file mode 100644 index 0000000..5eebec4 --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/AutoContainer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1e2d0e698e7d942d4b680da5027c5384 +timeCreated: 1530758038 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs index 1bfebbb..3755dbf 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs @@ -6,7 +6,9 @@ namespace EmojiUI { public interface IParser { + int Hot { get; set; } + bool ParsetContent(string data); } } From 2d13e3ae6ddd6cc5c5ed91cbd72d07b76826ec10 Mon Sep 17 00:00:00 2001 From: cjsjy123 Date: Thu, 5 Jul 2018 21:21:43 +0800 Subject: [PATCH 03/12] bakup --- .../TextInlineSprite/Scripts/AutoContainer.cs | 18 ++++++++++-------- .../TextInlineSprite/Scripts/Parser/IParser.cs | 3 +++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Assets/TextInlineSprite/Scripts/AutoContainer.cs b/Assets/TextInlineSprite/Scripts/AutoContainer.cs index d6b333a..9afd5b6 100644 --- a/Assets/TextInlineSprite/Scripts/AutoContainer.cs +++ b/Assets/TextInlineSprite/Scripts/AutoContainer.cs @@ -1,7 +1,7 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; - +using System.Text.RegularExpressions; namespace EmojiUI { public class AutoContainer @@ -11,9 +11,11 @@ public class AutoContainer #else public const int hot = 100; #endif - private List parsers = new List(8); + private Regex TagRegex = new Regex(@"{\S+}"); + + private List tagList; public void Add(IParser data) { @@ -23,7 +25,6 @@ public void Add(IParser data) Debug.LogErrorFormat("has contains it :{0}", data); } #endif - parsers.Add(data); } @@ -32,17 +33,18 @@ public bool Remove(IParser data) return parsers.Remove(data); } - public void DoStep() + public void DoParser(string content) { - bool needfix = false; + if (tagList == null) + tagList = new List(8); + else + tagList.Clear(); + for (int i = 0; i < parsers.Count;++i) { var data = parsers[i]; } - - //reset - } } diff --git a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs index 3755dbf..f85e368 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs @@ -1,6 +1,7 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +using System.Text.RegularExpressions; namespace EmojiUI { @@ -8,6 +9,8 @@ public interface IParser { int Hot { get; set; } + Regex regex { get; } + bool ParsetContent(string data); } From 84d3fe4ea999376767751171d8c60f025754b0d8 Mon Sep 17 00:00:00 2001 From: cjsjy123 Date: Fri, 6 Jul 2018 02:56:59 +0800 Subject: [PATCH 04/12] back up --- Assets/Examples/Prefabs/ChatItem.prefab | Bin 16432 -> 8441 bytes Assets/Examples/Prefabs/Text.prefab | Bin 8472 -> 2668 bytes Assets/Examples/Resources/emoji.asset | Bin 6044 -> 7354 bytes Assets/Examples/Resources/emoji_lxh.asset | Bin 18672 -> 50492 bytes Assets/Examples/Scene/Chat.unity | Bin 60208 -> 46831 bytes Assets/Examples/Scene/Text.unity | Bin 29392 -> 40337 bytes Assets/TextInlineSprite/.DS_Store | Bin 6148 -> 6148 bytes .../TextInlineSprite/Scripts/AutoContainer.cs | 52 ----------- .../Scripts/AutoContainer.cs.meta | 12 --- Assets/TextInlineSprite/Scripts/InlineText.cs | 32 ++++++- .../Scripts/Parser/IParser.cs | 2 +- .../Scripts/Parser/ParserTransmit.cs | 83 ++++++++++++++++-- .../TextInlineSprite/Scripts/PriorityQueue.cs | 67 -------------- .../Scripts/PriorityQueue.cs.meta | 12 --- 14 files changed, 109 insertions(+), 151 deletions(-) delete mode 100644 Assets/TextInlineSprite/Scripts/AutoContainer.cs delete mode 100644 Assets/TextInlineSprite/Scripts/AutoContainer.cs.meta delete mode 100644 Assets/TextInlineSprite/Scripts/PriorityQueue.cs delete mode 100644 Assets/TextInlineSprite/Scripts/PriorityQueue.cs.meta diff --git a/Assets/Examples/Prefabs/ChatItem.prefab b/Assets/Examples/Prefabs/ChatItem.prefab index d80449c793b1d1297fd20509d8d7c55b686776fb..5160cbcce77c6cbe6dcc22200dc708ff807ac84e 100644 GIT binary patch literal 8441 zcmeHMZExE)5dQ98p?+w;)Xqpr)Qiy+aNIO87B@kXZWxBape5R7BZ-D2yK##B_Z>;e zmL(@>mv(W`rH$;6$K&x{p1Y%7{?Qwr8TbIVUS9W3j2DX+Moy>QMZ)uy6&?g4Zkq_> zZmZMj$XSdKHeSgml0U7BluhWk+cJ!JbUyyXg8Y<+?0rP1S=YcYoUxSCh~KgBHnHIjXBeopdwBWyG`iQuu6d)cAGR>$I5U&*@ zwF1Q0^GwIYu5X*I3SYIjp&+D&s~j6*sDr~Hl%5Ak&eDWNRWVCbNcnaso2V_;YLS}m z7+_Ydr3xd{w6TRu6I-t5y4W%u$?-l~6BEa?Kt+~ixyV&g?xw}qHeJgDF-^~xI<>VX z&*+M!T|>+F0W8opj!u-Y*K~T7r#zW;I|^nosiESnYVv_`LT zaI4@rX9#6^x{+r+dzrQmywVcWKkJl7|#O?>}; zWAtY92o5VCtVj~-w*!Ce-eDZKC zA&4Qz_g%~Mz}zZE-x@Nce6PeDzfC>(>05v@yKR+1siD@AKEij4=I(`rak>j~G z*cZ8kz=`jt1=Cu#&ww3YoSsU2s@E zVLqOWacKFbGa#x%t4cBG{y>b#}wq<8E`G|L7d6d+LC$o!_} zh7|HPltInx)fbTfsxR=1KnC?3t0#q{=uIx^Dxg_@P17j@*=1D)#a7Z^M3GE%43Ij3 z99b4o7qZUEauA_UqbSqEa*6(PQ!-t{N%R3e%5v{Gnev1kd>kAMX?7#Ed6Lrkj0dml zI~^~9c^i^*byXY0l0QY6cZd&={MR;Mb-qa1VZs)9N~5-Mu^2}@_?4}$#SKdi6F7%D z(tDBQ?`TfTgUG)t8pBX?nx&nT(JBvC`7Xbfc2W^34=l~o$FADsrm5h6ZKeaOd zQTWqw9pWL!#$M^!6BiLeCfK$^4=MucnPh@IWHaOkj*ElRvwr{rVTC~O1O$TT&xb%) z^OWZR2lXC9B4r7@(1}5twPd|)4&AN}R)7~CMSZ{k3Hdr6<;albGXYt}hDgvfy;v+H zQfz4YkqB-+^K89=TzH;x0AtC#78kV|Vz1(&R`)$BE?j6)5P{10|FHOJ5;K-z^391E zmwEWX%v`c=Wae`9CNs;>lu~@>%={*hrQYE+j@-GI`qAY@!Czv zqhcI8uJ2gTAIr*DSKmJ*_YJ0rNE!6VVzI_+sOx^`VLs~`9Sy}WaLV{}1{B4JymDh{ z%EE2J^>9f}qzeJMN9>kE(Y#Gvj+Vs0yFhg4`;AxdsCAI7K24T1yJShoQphHXcjMwv z%d9U2e`KrGfb^R1wOhdb624KV)r7BIyX=?njV5<3JT&OdyV}+z6eH{F^C$M2hT>&> zoC)Y;E`_|ARoA$;5NHti&>YE+JN*I8Pto)$@(Ypi4Y{V)#Hz0=m|g*6S+oI1s9I&W zrT7($`ZFGd@HU}%R{()Z^O-Eu)8OLKv1so|5T!5wWzFOe2<^a@C;1 zzB@$gCBaOj04rLuf>43lj2IH;lK zI<>>@mFw)xFHi0|0K%Ouf7$t_r0P&R?+~{Ln)kyyT(fX<`I72C@x(1x(q8)Qo~UoI z;U=)+iU&kRCORMucdXr%@0B|?Q25y+nSS~Dgh)oVe5?j#9eAy*9YrJE*SgU5js0G^ wP@{yp$AyY>tJDSG_cash%JVz;k3<5gidrr#)UZAKEf`dK5PUX$Xahq303D~+7XSbN literal 16432 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 diff --git a/Assets/Examples/Prefabs/Text.prefab b/Assets/Examples/Prefabs/Text.prefab index 42a33835302e8be0935b37ae59d7c809633d0f8f..89a5c12b16b8abf98f3a0ad557fbb7a9495be573 100644 GIT binary patch literal 2668 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 literal 6044 zcmeI0>u(fQ7{=eFrKKQOc&iS2p z-!o@-PDP6T6`6ZXL}rT2fQU5KG}Y7(*U5ilV`GsBjHI%qr}Mz+<6Ug!Ux+p2ImbL9DNA&O}dtFQ>@kdpX6fACU%dcG?`y z(WdVC<0SW5Fd7qhFx-r5M9_X3-w5s zZ}ab?Z&{4f$Dd6laZOe;G6^{)b)PpPzF2D9jr< z%s)8`X9T#n>R6M<|Z!j)ss6iFa#-y*;4{zSF;TO!wQANuWw8>Jn`pR=m|x-xvBK;8QO z;I(6So}ae%v)i*@dF`E+&DvGB@_+If$Y&s*fqVw?8OUcKpMiV^_+G_Ab>6LbzK#zj zcJ%WG%J??ly{vQkG{7?=U(r$_Ae{wP*ZvP@=PJp9sT@J5@Vh; z9KCk59qsNYHP@eS_2KOD0J~N+d%$LX>8fTA7=AWS2I1_A0K3j+j~a6~rV(eU>F5iW z+t400sJXa#x(H`43b5-nJGM|Wtxi|}n7+~!_|zPmCzNn@Re;@KvwO@>r!nq5u2!U0 zfZbzKb8Mb+!r9dUcB5uXMRZM1E7&cDqd!+qMY|$O&9Qk>3TH0~u$yf5R-^aZ<)&C) zxcbzeQ^4M8P;+daw!+yp0roPReM>V(=9_8`=-maA!M}H!?p_#EY zu2%0YVNOhHj?GhFIJ+*uZqaOOz0J(JI(iB@fluX`QSZxIY|Lsvx^Xu}9XMD$iEd)x?q0 IQGrkWA94_rJpcdz diff --git a/Assets/Examples/Resources/emoji_lxh.asset b/Assets/Examples/Resources/emoji_lxh.asset index 37d33f2153a8950c18ba3e702c6860841b119d7e..265ab392748da441421e0e5602bfa325ceefa1ea 100644 GIT binary patch literal 50492 zcmcJYO>-l+5r*&kD<%i$w5tM!pVG~V9cQcJ#8u8ECl_})+NHylR21d)#^wK>8O#9v zf<&|7YPJrkSp6%6~v_2$i+q3Zp-`E&n2Zuoii{o}*qU%HQ*Uv`f#hr3rz^XaF5z5BU)fBgGy z+x>07`S5(#xbW*A4&D9c-4B~X_i!8|cg=72yM6cen?CY8WZpg;yTij~e_sD?^Qq(h z?Y9q`cl&O8*ZA;K-)?uu$HUoC{P_N`dpg1^d%p-RdEI#_49LgJpU&Hf#Il+-LF6P7~l7=n8>v2?C{+Ex<87x+jf4{b?f>4yX|JZ zU2WU>e7)T+eRg>J-ShFsr^D{peRp_#c^bOsP3YWa^YG#DrT@>S`Mld6KaOwTG|#*L z_3ynHI;?4a9eb{6zQq6Y9A4|g@LJEqiw!R~{tge=&zx&lZ3Oyu^vv{?^S`%Xa9B;b$t|_;yhpn78Z2$}dh{BL4HN$~Sg?jm8cm zVE8#}tlS={y;RQ{R3w%q_$Du}(d3qGG97Wbi)SmLiy@G;h}ukVkp=iBudmVM8QWwy z;&PjX7N>I79BMDTewJVxyzW0{<4IBT8J@EZP6u3W?vgr43}g+WCZ~7E>U@K*a?)C` z4HjD@4Qi@q4Wb6aJ7fvI$yYgbE!ig15tsXL{RaYBi>S@?3R!?}@>NbiLd;RIQyN3_cv}rT5&z$l@a&nY~`7Q#277p`bVRjc2?sn16 z*1kNuL-Ca0I2T(HRGwE8!75{57}3d93IL{ZH$dQ&<2b?FaBOdt6LR8Mqah3>Zc?S; zN(tbEAX863{gmTq4OSeLC&a|D%54~s<*Ax5#yUVkh(*e$6h{@YqNton6U7Q)Vi zKT)Iv!?A$*l;Y?&Rur!_yHr^i!;vux!k7XK#UkcYj-xbLalF<(j;Zp+BFM{57^@7xBH>8z@nCI>-fKV4c#OO&F2m32#PeX`L=KE= zN%NDJm|S!T)tsKCDfX+Zy1&5Rjr3|fkpYzCM63fL{D{+99M90w61~^j&B(CA5gA0J zCUSs*NWB1od>mRDqW9Xf;K;DX4;e<$OQbUJ!BGf(0EwKSr5*ZKJ0Fh(WjAC1k&(y& zAcPE47eGBHXlaJNz0OQhj*B1P6y5Nnn|tr2x8xa^e{1RoEZLhSZ}XQN~C7 zsSab$QvKXQIb{s=YP^qw6Rkt66B-}2EP$dGMRBnS@DOYo@- z>@0Q9Ev_(E)VLnUCTWHoAUMbl@KXTjS&E)pUSY#V>Rbzsd`>J^d^2aw#N}lwjl5J(K zpl_9@Lp(&@4lg|saH+Of1+83`jS#CDF;gL&DNlYQu^J!5>$5m!l7@(Zaq0CGA6$ip zKt|A124~8@=0<`QF39mA36T>(sMrTk&j^}|;7oba8wu8UAO|QKh*SqWh>v;z0vSJ3 z37jcKdgRAD;JklEt#G3X5?Hq4#~30&310->2ND@aQxTk9W%j7?KyI9goKpY*AwtqX z2xJ6JC2)R~*`&e&Ie;V}asmh;!V=<)ps4`PuQHp|_+J@N^uNnh1|89dz{GC1wO$*% zRic9<oJq&&5##Yf|Bf&r6B0w%DGoNl#~3C?Yvi3A|NKz=2$i19J4zW1ke{gn-YO^Hz^}ppIXdJYasv1uz|;d!M}DRPsD08V@T>7Z4o}n@sSa=u9`T0& z(zDdR)+s05K##XSi47?SM~@PK2l>UffHKmvl)hH`ykVeM<9r;QBf>oIUhHN*hWL3{~6)RCU0={fDSwm`4O^cXtPG=wssL39Kk0?5wN^PKhyTVN-9 z9)pG~Lks{Mq!-yk8QED{p3`1e3+ygfo~Nmh!Lypv=&6VRBxJaRH-ZRqw6s09Qrb%3 zSYdk%A(1i#fDQsot_O9bXX$!wrCeYR^lDtMh%c(%#UfxqY(=gUw}+R*@x}a6-?NQ_YY1>e8Z-4y%UD&8AD6;n`!^pAci&m$6!hVBG!Qu z4n~siizF>IaORXBWg=POf($5{P~-rElKKJyXJgV*31?opd_^Q{ypSOk-9#z_B^;5^ z6OcILXsL%Y?N$iHQFcTI6FH(B08U6Ubp+JUI9jUWOuH!palGJ*^tmhUAV$w8Fd&o0 z;297(LRVZOX(@{{?bZlHvceb{P$VvL06-ziBI~m;X(^5~?FI=%vc?{Zq@q1uE;0zA z7a%b)eA?_DOjin9?X&%GguFGv5-5%yk`*~H3qRb2VW=WGOJQua`$`0IHLl3ON#{wi z4s;m&kU)Nxn%HVTxPf1VAu@Q#OXL9HL4ec)5I}yGa@cC8kif6T3mHC9N2D^aL3qF) z5=hTd30tko1bVU!GH^&i)(JlZke{jV zX&BKq%uSgf^nfjjgQKUex z!uJ?cGw8;CCj7YJ z$bs^%GL!D%6W2)2()YY}3$Z}1#`hRFNjAiKnH^k|=lEIrUjGGtx*fCwzY5=D@Q`lE z0R|xT00eOSS^A#WZk`zU)%YI6C;Em|1~&NN2mX*idX~P|f3@TlMxX3^3>>lzIRJE! zU&0S{q-W`SUb|gv7<)Co$KXk_A=ZHo(t{3w1oE@=JwI383mEuS_#T6YltT^x9t21| z00HD@>3e>Djk%-7_lkU??p-bd7X%0FA(6=K_olw*wBHA2k7sP?i1ji%@I8*7rSG}5`ZL>)yb9lA@Q`oF z0R|xT00eOSS^Az^tLKcKUybiEe4=njWnhEnJ>U-sq-W`S{r7}xeXpk{`yK;_bVCjR z9psnrLmlZ^`d+`$?-l6P_#T5N*@jpLI!F&X020X0()XNpe~mDARQMi)hnzzW03HNL zJpcjZXX$%RyURx4SL1s{KGF9s7l8|c1NM+e3gkyjiBdO<9iIBC>&B5*x-2&_(KBeS^8e9U!m&h$-c+HA>EJzKnM9H z{7^@FmcG~OS4Vq#HNMB-Nwy)@fezAx4uAymv-G`Izc%0VtMEMr4>^Y%06YkgdH@2* z&(il={k5T))X>30ZB(>7L-l;skQ({4Z+NXZs(24$McxZks^(2~Y`t^!TuWw|8d zwEMsWUZO;tVTp4gTi}5uY2e0}ZyU-Pgc=RAR<%W}!ZX&<@@ zv?PT&gAylVwvf}nKh>hLaAV7IiN$Fj@e8zM13JSpP2=3}d0G*4p1{#%xuoK>kCX;p zqClNti7vnvavV6kk}z@O%W?_DX&+z?yk!46;WBzx@s~WP$T&~Lk+tu-C)0bP`u)U| z!Uc!O8JD{mckej+Qd4k(ibQcqDqbeTjfgXPmJ;T*cUC+Hda{M_1d}9i04Y%BhkXEv zjG?8NdF{PDBSX>5c!Z=5979L|B0S#}DQ65VWzB2vFB=)kw#Gw@KEWYObp~J=aYoQm z;Jo$@$C039a6CUU42~cq7=|Ur89_^_^V+*>M}o4|@eGr6a0n^D5G*s!7+Q*+*Y5N> zG89dZM@TxtF@yvIu}C>%XeobQyVvl@P_{n~VqAVJ158y0UK#I1@AGDF`$%M~-Dn+- zkhej+B?l)_x-KLqhA&50oqcQSv>*pXBxk9Dt#*U|K(59FIW|c_!~oza;8$aS9G++&QXSwRJmL=lq-Uvr?NWJ3 zF3^+hk7GmLAtwM2@{9PPjPxwkuU#q^5dys$^W*3wH* zus)6sNr#*OJ_s=N0MwD6rSi4f?Fa(D8sjVDiB5O93SbZ%v4=n+ckB+Iy8UCkHOc7S zDeZQdpEoDR$-5t}2O|b@zly}Td-d<(cCvKoI$n&W;yFc219aL=TY+MY2XdT}g~$Oy z#dHM)&RJU8pwn(33@j_0kRwG-Qjs852$On)>gOyi&CqGLu?Chke#oJUf+E%l6oQ1l zpujmvOG|Xx4I+W0?1~&GQk9AXp+c6aE2w-<($W~6cEdg(S>ufysbnp3fKVYx=nM*+ zv$V8F*D7xo1(p>K$&n(DsYnnjgh{db%Ch4>raRSR4pDd$_J}FcQ5<-N2puj}& z%jUDONov2+9FCB8NZi5!n@$cXCzj!7Rdz@yA~{og)P9+HAXnp!9Ghe+VgT@z@k0Rl zSsJ6)-Z>ihRk$KYhx|lN03QUHdI0Lk&(adT_I}d9uf`8KJW)!dI>14A#2*4k&(aLN z_U_U^Pj*6%4QYs+06fSq;)gQQv$R34z1K9*tMNdNPBITM0C^`(nHd5#RbSDpx&KV+)4##DkhV52Ma z51G5?nCgCcZ?2BRSoGuZxb!cS_8@t({~+_cFpiSf7(XZIUnZOr<@Ex6&v9-($W)Ii z=ip#`$e9=Phn)Gof5@y7&h^TH#<}*r=6ntb`a{m4zJJKvDf9e{a4^4jfFU54hmT1= zJ{LZ-oBs~ceN}beDgAg1Nk+o?A7=a5AL_o#_Yax%qI-{UkbfN2p~{XQS}ys-6a8|) z%}|N{IhKE{#9%&)&~Kk}%qL{*b@IgPcl&l^+wf!Og zy}qCPrScl{JX%^A-r~Pcx>NH%2L1Ngod2=Df5?8`74mwnJdcwn9yl(mrM*C&I3~x- z6OTCmC)hsrhxvye-ErI~e_t(6%)gK}HUIbf{$_p_qhB7#8#u^6I3GY~h5otr_>Rj< z^e^%K2RHJ6lJqk_^BTwZWc1tTyvFf8#rMxO-w`F8_H*Tl@)~)NdTAdr&j$ZY-{0h)74$zV9OMDD>TKIzi1wlOc)8>9k*MDtmv!2|Y14Fn z-Gy66rziRs?wRh5PmNBDcg)UfE*c%{ZMZ=G*fcV|L;g5-YN|KAab#!D$O{{^0SL^$4vM3TspC)}TV~hwHm~KI_t}}_pZ%I7=G&MT_Wsbmhwl>e((5curZIF zYyXsguztn(Gv;1sC2>t|$6j-W!Ldp`$F6C`uGCl;V}^Ck!_*}Mb3U^byUNX3V+!BuoGk;fXSZTk zYpjbYHMUgU!pE*_#jep<7t__)uEvr9-A*fZt;V{TN@FXHCF4+u-7?neZ5r)yso*IsA^f(wfF3_M>LjxDH13t$^DGeE~ zxl(rFTRk3DtD%7l;{h5Mq%>qaH5|KCjZ!~H(bm94_5h9ZQW`Rz8jjsnjjn1?tMNJP z1$)}NWlBTFQ^T<<)u>d1TBw0rCi;4Ir1@W;!}=JG)#G69*>{?F#B^Ny%H9+3+Mo@_ zi_6pOTifjA%2sCOTV;15wzxaZzOBt(LAGPgD0{{-g%h*I)oJ!O+U%8NJEj@doD6f` z)Ch7SZcekm*=DcOoG7#Kt>(mP1Z;6}n*FUddo|gPSt`5Kc^5HT+?!^9yUkuhwqtgc z-BmUMnfPF>8##qgXG7H~oPOOGw+mb$jePzVPSh5|nRCcNJE*flG$_KEo zir5%Sb~*fojqpj=w+|l=pOnLB-MqQyn)dhA5gTL4?hfDg$18 z^tX>$i>KK$$_~eBzRi}S=LySnTzk&%-?Zynw88j+_4}7?wy)o0R?4nA%C>F59$3F0 zZL@v-CVNKNGs>n$z#dq?f7NFD`mMPbb}i>kjetF{em~Y``}$30q3mK}nsLE;f4_fT{`jl+9E~%7F4cs3vx|P*?5c>sXhhv?;AK3Yf-Jfu+TnE|ujn_XYbww`SlC~5YqFY4&R|TgH;@n3b|CWm5y}oxPFi+}=w!V7sxJ zZxgPG1ts1)-_~!mo}KacmY5y*n{2L$jrd&Iw)O0czqiKhz~AATnEuARso~ife{YM~ zfxp8wvE)SZ4K~i9ASW4r?}*ufzscsBnEtl;wiP}inPX6NsW44LyfL#poIptni@Dc(i&GMHR|;ZH7eCW3k_0z{$+q|G+lN;69rxKah#jA)|No8ILH#Ea-UJ(af|hMt zKkrQa|4+;g>OYzAB-b8fQ^T_}_5a^7JE;F;8sry2_@8XJ_jF{+J!qe=;j& zSIVY_Wsi;U@^rxYWAyw9$2xz9o`cU%+Hfn5sra@JMcG|g|gi~qp=#E zo$>dNV|L(gvP)%`I&W%tcE;cL$Lzr0WW#gFNmtp_@a&Age-yI=f0J1$yHYka$Q~QZ z`Fpa#=2+)%S?kDru|8ot{>&P@HfTLN=|WK!?QE~zCLCL{wCAN_odCrFy~DT&(8RJPs|SdO=h9&LfOW)o}Kac4KX|LH`%4K zOJ!5Tvorp_F=hw;CcCTbuCl4&*%^O-K4u60Cc9F0rEF@DJ*7W@rq}m}2j30-366FC z=63<=w_TUW?<`YxeS+4rGyYx_vjcyViTVvTe!H=3+j@4!-$%ymz~5w|euItQZosC7 zXJ`C? zm2tMrJ8$1``*vHqU8}!m+u!^VdtMX^n`>-`F_mxK{Q+nZdqETn8#C6$%xEn3tMS`0 z_QV-`Q4|ZCGS#uUC~tg#HlUL3{3W{h<)rN)-3Tlm;Z zqFC67u`Z^ov0aTN1G*cdSlEQIE~e7hN@K}@uck)xYtus6;aJUwM8h)%b-}iB9-}pA z{rF66TO6~4+D2xjY+HA{hG%DL+me_a)Hbqblx^#du&LqMnc8-8%noXs<^nv-7w4L^ z)bQ*~ZCe_%gW5)Bq3lB0)bQ*~Z96Sy2epmtQrV@lso~j~+ID)(4r&|OU1fKbO%2b^ z)V5_YJE(1BBiDQ~-_*eGj#F~)>ZGk&c)z}P+1-ozyt2cw&fnqv7J|~>+Kkkw#BaZlF5eW-h>Yw+qN|u22Zn}Zn5hcD-jzW})mt+0>}nFnF5%mlnI;D<&JB!@NsnQ=?|X;A!@s zTI_m{m`r#M?5?t@QL|z2H2V)NcD*-DW~J;(+0?+fvwLJLySK0`SQoglwZEru40Ua1 zufg!z-m~x7nfiTt%ns_eoQJ}KzuC$f+iIcp>`eVWEoKMxn@so{Y`eV$60?K)O?Ij5Qs+$#&(75E z#W6dm-(+`{-BmU zOYOHlx2>-I4B9A09Guozk=F3{>dEK8cMv>jTh*{@)JQ{|oYq*C*6{c2k!^i18g4Di z^>Cyij!tW=No)9f_o!iTJdi70H&QFo5ND?~&P;3gd-%vMRHIN0YDF62@U+I+X$^lb zA2mwVC{=@6k%l-ut+6hx;qU3AMpreuszI$tLmZ#h=%h9Ly?xZERHIT2YT?}5JF+|b z+hC>qaI8Bo!u>FuA9}yN{XYqQe5U??A!Y~lpKQ11hTrY#|L5S@nfiZI%ns^*xF3e| zfNW}bcBcN{9J7P^uQ|~@AR~MFm^U>%J5&F^7_)==Pj=z=#WW{Y!?QE>|4T7DsQ+Yh uKMd;|vWq4=Q~$pbvxE9iHuuA@z9E|$e%_h-|J9fs)PJ%o%}J$fYWyEp2Hto8 diff --git a/Assets/Examples/Scene/Chat.unity b/Assets/Examples/Scene/Chat.unity index 5ed7a8df3b81307d8f7025052fbf43bcd4ccf453..85b74d0da8432404070b2dc3047801adf371bce6 100644 GIT binary patch literal 46831 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

MI&&So|Z^m1s{K}u>trCBZmng3MIo@s>u6%L|S- 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 L^u0&oezN}ti%XtG diff --git a/Assets/Examples/Scene/Text.unity b/Assets/Examples/Scene/Text.unity index f402f08c58413d71aaf08ba206fabaa57e3b6f6e..54314e39080a1c6137d7723ed6b12af83c262206 100644 GIT binary patch literal 40337 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 literal 29392 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 UKzW7)kiy9(Jj$D6L{=~Z04%N#AOHXW delta 397 zcmZoMXfc=|#>B)qF;Q%yo}wrd0|Nsi1A_nqLn%WMLo!1uLvd31#>C}}^&lBeh9Hm# zLq4)>aY0f}eiBgjYf?c@W^svu!3{%bl#+~))I8Um)Uwn(|018nlGLJTkm8X1{2ZVH2s<$;EVDkfJYGP= zIX|x?F*7f<2y7t4keKkyyp;TMr~J~qlwz<3sOeyKKw?P-&>#+Fhx7+PHv;{@!5J?g zQC)3hYN4ZGWNKEcqfl*bZlI%JVr*7h%gMnZsqPjOSK8D!Yxa_*%a$KH4A#Y9!w3u( zFc5^&FzN`9fhAzdf{XHU^7GPxvWy!O53x)(5MkNO&B4t94D5}G-!0##wM Mp@{V60Ff=s0I08OP5=M^ diff --git a/Assets/TextInlineSprite/Scripts/AutoContainer.cs b/Assets/TextInlineSprite/Scripts/AutoContainer.cs deleted file mode 100644 index 9afd5b6..0000000 --- a/Assets/TextInlineSprite/Scripts/AutoContainer.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using System.Text.RegularExpressions; -namespace EmojiUI -{ - public class AutoContainer - { -#if UNITY_EDITOR - public static int hot = 100; -#else - public const int hot = 100; -#endif - private List parsers = new List(8); - - private Regex TagRegex = new Regex(@"{\S+}"); - - private List tagList; - - public void Add(IParser data) - { -#if UNITY_EDITOR - if(parsers.Contains(data)) - { - Debug.LogErrorFormat("has contains it :{0}", data); - } -#endif - parsers.Add(data); - } - - public bool Remove(IParser data) - { - return parsers.Remove(data); - } - - public void DoParser(string content) - { - if (tagList == null) - tagList = new List(8); - else - tagList.Clear(); - - for (int i = 0; i < parsers.Count;++i) - { - var data = parsers[i]; - - } - } - } - -} - diff --git a/Assets/TextInlineSprite/Scripts/AutoContainer.cs.meta b/Assets/TextInlineSprite/Scripts/AutoContainer.cs.meta deleted file mode 100644 index 5eebec4..0000000 --- a/Assets/TextInlineSprite/Scripts/AutoContainer.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 1e2d0e698e7d942d4b680da5027c5384 -timeCreated: 1530758038 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/TextInlineSprite/Scripts/InlineText.cs b/Assets/TextInlineSprite/Scripts/InlineText.cs index c8eaea8..39a7d9e 100644 --- a/Assets/TextInlineSprite/Scripts/InlineText.cs +++ b/Assets/TextInlineSprite/Scripts/InlineText.cs @@ -636,6 +636,37 @@ bool ParseHref(string newInfo,int hrefCnt, int Id,string TagName, Match match,re return false; } + internal void FillSpriteTag( SpriteTagInfo tagInfo) + { + if (_SpaceGen == null) + { + _SpaceGen = new TextGenerator(); + } + + if (updatespace) + { + Vector2 extents = rectTransform.rect.size; + TextGenerationSettings settings = GetGenerationSettings(extents); + _SpaceGen.Populate(palceholder, settings); + updatespace = false; + } + + IList spaceverts = _SpaceGen.verts; + float spacewid = spaceverts[1].position.x - spaceverts[0].position.x; + float spaceheight = spaceverts[0].position.y - spaceverts[3].position.y; + + + float autosize = Mathf.Min(tagSprites.size, Mathf.Max(spacewid, spaceheight)); + float spacesize = Mathf.Max(spacewid, spaceheight); + + int fillspacecnt = Mathf.CeilToInt(autosize / spacesize); + + for (int i = 0; i < fillspacecnt; i++) + { + _textBuilder.Append(palceholder); + } + } + bool ParseEmoji(string newInfo,int Index, int Id, string TagName, Match match, ref int _textIndex) { if (Manager != null && Manager.CanRendering(Id) && Manager.CanRendering(TagName)) @@ -680,7 +711,6 @@ bool ParseEmoji(string newInfo,int Index, int Id, string TagName, Match match, r { _textBuilder.Append(palceholder); } - Debug.LogError(autosize); //_textBuilder.AppendFormat("", tagSprites.x, tagSprites.y, autosize, tagSprites.width); diff --git a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs index f85e368..293e7b6 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs @@ -11,7 +11,7 @@ public interface IParser Regex regex { get; } - bool ParsetContent(string data); + bool ParsetContent(Match data,out SpriteTagInfo info); } } diff --git a/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs index 3736e89..69c5d21 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs @@ -1,6 +1,9 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +using System.Text; +using System.Text.RegularExpressions; + namespace EmojiUI { @@ -20,19 +23,87 @@ public static ParserTransmit mIns{ } } - private struct ParserHistory + private const string palceholder = "1"; + + public static int hot = 100; + + private List parsers = new List(8); + + private Regex TagRegex = new Regex(@"{\S+}"); + + public void AddParser(IParser parser) + { + if (Application.isEditor && parsers.Contains(parser)) + { + Debug.LogErrorFormat("has contains it :{0}", parser); + } + + parsers.Add(parser); + } + + public bool RemoveParser(IParser parser) { - + return parsers.Remove(parser); } - public void AddParser(IParser parser) + public void DoParser(InlineText text, StringBuilder fillbuilder, string content) { - + if (parsers.Count > 0) + { + MatchCollection matches = TagRegex.Matches(content); + if (matches.Count > 0) + { + bool needfix = false; + int index = 0; + for (int m = 0; m < matches.Count; ++m) + { + Match matchstr = matches[m]; + + fillbuilder.Append(content.Substring(index, matchstr.Index)); + + index = matchstr.Index + matchstr.Length; + + for (int i = 0; i < parsers.Count; ++i) + { + var parser = parsers[i]; + + SpriteTagInfo tagInfo; + if (parser.ParsetContent(matchstr, out tagInfo)) + { + parser.Hot++; + text.FillSpriteTag(tagInfo); + + if(parser.Hot > hot) + { + needfix = true; + } + } + } + } + + //reset and fix + if (needfix) + this.parsers.Sort(SortList); + + // + for (int i = 0; i < parsers.Count; ++i) + { + var parser = parsers[i]; + parser.Hot = 0; + } + } + } + else + { + Debug.LogError("no parse job"); + } + + } - public void RemoveParser(IParser parser) + int SortList(IParser lf,IParser rt) { - + return -lf.Hot + rt.Hot; } } } diff --git a/Assets/TextInlineSprite/Scripts/PriorityQueue.cs b/Assets/TextInlineSprite/Scripts/PriorityQueue.cs deleted file mode 100644 index 13088de..0000000 --- a/Assets/TextInlineSprite/Scripts/PriorityQueue.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using System; - -namespace EmojiUI -{ - public class PriorityQueue - { - IComparer comparer; - T[] heap; - - public int Count { get; private set; } - - public PriorityQueue() : this(null) { } - public PriorityQueue(int capacity) : this(capacity, null) { } - public PriorityQueue(IComparer comparer) : this(16, comparer) { } - - public PriorityQueue(int capacity, IComparer comparer) - { - this.comparer = (comparer == null) ? Comparer.Default : comparer; - this.heap = new T[capacity]; - } - - public void Push(T v) - { - if (Count >= heap.Length) Array.Resize(ref heap, Count * 2); - heap[Count] = v; - SiftUp(Count++); - } - - public T Pop() - { - var v = Top(); - heap[0] = heap[--Count]; - if (Count > 0) SiftDown(0); - return v; - } - - public T Top() - { - if (Count > 0) return heap[0]; - throw new InvalidOperationException("empty queue"); - } - - void SiftUp(int n) - { - var v = heap[n]; - for (var n2 = n / 2; n > 0 && comparer.Compare(v, heap[n2]) > 0; n = n2, n2 /= 2) heap[n] = heap[n2]; - heap[n] = v; - } - - void SiftDown(int n) - { - var v = heap[n]; - for (var n2 = n * 2; n2 < Count; n = n2, n2 *= 2) - { - if (n2 + 1 < Count && comparer.Compare(heap[n2 + 1], heap[n2]) > 0) n2++; - if (comparer.Compare(v, heap[n2]) >= 0) break; - heap[n] = heap[n2]; - } - heap[n] = v; - } - } -} - - diff --git a/Assets/TextInlineSprite/Scripts/PriorityQueue.cs.meta b/Assets/TextInlineSprite/Scripts/PriorityQueue.cs.meta deleted file mode 100644 index ab47cdb..0000000 --- a/Assets/TextInlineSprite/Scripts/PriorityQueue.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: bb748da643a7244768585668a85faed7 -timeCreated: 1530757633 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 6817054003fa53394fe54e250249fbb17b27eefb Mon Sep 17 00:00:00 2001 From: cjsjy123 Date: Thu, 19 Jul 2018 22:19:39 +0800 Subject: [PATCH 05/12] back up --- Assets/TextInlineSprite/.DS_Store | Bin 6148 -> 6148 bytes .../TextInlineSprite/Scripts/AutoContainer.cs | 52 - .../TextInlineSprite/Scripts/EmojiMeshData.cs | 241 +++ .../Scripts/EmojiMeshData.cs.meta | 12 + Assets/TextInlineSprite/Scripts/EmojiTools.cs | 196 +-- .../TextInlineSprite/Scripts/EmojiUIData.cs | 345 +--- .../TextInlineSprite/Scripts/InlineManager.cs | 1071 ++++++------ .../Scripts/InlineRender/EmojiRenderGroup.cs | 1488 ++++++++--------- .../Scripts/InlineRender/IEmojiRender.cs | 58 +- .../Scripts/InlineRender/UnitRender.cs | 1313 ++++++++------- Assets/TextInlineSprite/Scripts/InlineText.cs | 1230 +++++--------- Assets/TextInlineSprite/Scripts/ParseData.cs | 71 + .../Scripts/ParseData.cs.meta | 12 + .../Scripts/Parser/EmojiParser.cs | 78 + .../EmojiParser.cs.meta} | 4 +- .../Scripts/Parser/HrefParser.cs | 36 + .../HrefParser.cs.meta} | 4 +- .../Scripts/Parser/IParser.cs | 17 +- .../Scripts/Parser/ParserTransmit.cs | 148 +- Assets/TextInlineSprite/Scripts/Pool.cs | 184 +- .../TextInlineSprite/Scripts/PriorityQueue.cs | 67 - .../TextInlineSprite/Scripts/SpriteAsset.cs | 32 +- .../TextInlineSprite/Scripts/SpriteGraphic.cs | 110 +- 23 files changed, 3265 insertions(+), 3504 deletions(-) delete mode 100644 Assets/TextInlineSprite/Scripts/AutoContainer.cs create mode 100644 Assets/TextInlineSprite/Scripts/EmojiMeshData.cs create mode 100644 Assets/TextInlineSprite/Scripts/EmojiMeshData.cs.meta create mode 100644 Assets/TextInlineSprite/Scripts/ParseData.cs create mode 100644 Assets/TextInlineSprite/Scripts/ParseData.cs.meta create mode 100644 Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs rename Assets/TextInlineSprite/Scripts/{AutoContainer.cs.meta => Parser/EmojiParser.cs.meta} (76%) create mode 100644 Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs rename Assets/TextInlineSprite/Scripts/{PriorityQueue.cs.meta => Parser/HrefParser.cs.meta} (76%) delete mode 100644 Assets/TextInlineSprite/Scripts/PriorityQueue.cs diff --git a/Assets/TextInlineSprite/.DS_Store b/Assets/TextInlineSprite/.DS_Store index 15b351e5c2505fca4cc382177f123781d81231c9..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 100644 GIT binary patch delta 70 zcmZoMXfc=|#>AjHu~2NHo+1YW5HK<@2y6~y-o~;yf%zBHW_AvK4xj>{$am(+{342+ UKzW7)kiy9(Jj$D6L{=~Z04%N#AOHXW delta 397 zcmZoMXfc=|#>B)qF;Q%yo}wrd0|Nsi1A_nqLn%WMLo!1uLvd31#>C}}^&lBeh9Hm# zLq4)>aY0f}eiBgjYf?c@W^svu!3{%bl#+~))I8Um)Uwn(|018nlGLJTkm8X1{2ZVH2s<$;EVDkfJYGP= zIX|x?F*7f<2y7t4keKkyyp;TMr~J~qlwz<3sOeyKKw?P-&>#+Fhx7+PHv;{@!5J?g zQC)3hYN4ZGWNKEcqfl*bZlI%JVr*7h%gMnZsqPjOSK8D!Yxa_*%a$KH4A#Y9!w3u( zFc5^&FzN`9fhAzdf{XHU^7GPxvWy!O53x)(5MkNO&B4t94D5}G-!0##wM Mp@{V60Ff=s0I08OP5=M^ diff --git a/Assets/TextInlineSprite/Scripts/AutoContainer.cs b/Assets/TextInlineSprite/Scripts/AutoContainer.cs deleted file mode 100644 index 9afd5b6..0000000 --- a/Assets/TextInlineSprite/Scripts/AutoContainer.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using System.Text.RegularExpressions; -namespace EmojiUI -{ - public class AutoContainer - { -#if UNITY_EDITOR - public static int hot = 100; -#else - public const int hot = 100; -#endif - private List parsers = new List(8); - - private Regex TagRegex = new Regex(@"{\S+}"); - - private List tagList; - - public void Add(IParser data) - { -#if UNITY_EDITOR - if(parsers.Contains(data)) - { - Debug.LogErrorFormat("has contains it :{0}", data); - } -#endif - parsers.Add(data); - } - - public bool Remove(IParser data) - { - return parsers.Remove(data); - } - - public void DoParser(string content) - { - if (tagList == null) - tagList = new List(8); - else - tagList.Clear(); - - for (int i = 0; i < parsers.Count;++i) - { - var data = parsers[i]; - - } - } - } - -} - diff --git a/Assets/TextInlineSprite/Scripts/EmojiMeshData.cs b/Assets/TextInlineSprite/Scripts/EmojiMeshData.cs new file mode 100644 index 0000000..ea10fe6 --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/EmojiMeshData.cs @@ -0,0 +1,241 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; +using System; + +namespace EmojiUI +{ + public class UnitMeshInfo : IEquatable + { + private SpriteAsset atlas; + private List _Vertices = new List(); + private List _UV = new List(); + + public Texture getTexture() + { + if (atlas != null) + return atlas.texSource; + return null; + } + + public SpriteAsset GetAtlas() + { + return atlas; + } + + public void SetAtlas(SpriteAsset data) + { + atlas = data; + } + + public void Clear() + { + atlas = null; + _Vertices.Clear(); + _UV.Clear(); + } + + public void AddCopy(UnitMeshInfo mesh) + { + if (atlas != null && atlas != mesh.atlas) + { + throw new ArgumentException(); + } + atlas = mesh.atlas; + + for (int i = 0; i < mesh._Vertices.Count; ++i) + _Vertices.Add(mesh._Vertices[i]); + + for (int i = 0; i < mesh._UV.Count; ++i) + _UV.Add(mesh._UV[i]); + } + + public void Copy(UnitMeshInfo mesh) + { + atlas = mesh.atlas; + + if (_Vertices.Count < mesh._Vertices.Count) + { + for (int i = 0; i < _Vertices.Count; ++i) + _Vertices[i] = mesh._Vertices[i]; + + for (int i = _Vertices.Count; i < mesh._Vertices.Count; ++i) + _Vertices.Add(mesh._Vertices[i]); + } + else + { + for (int i = 0; i < mesh._Vertices.Count; ++i) + _Vertices[i] = mesh._Vertices[i]; + + for (int i = _Vertices.Count - 1; i >= mesh._Vertices.Count; --i) + _Vertices.RemoveAt(i); + } + + + if (_UV.Count < mesh._UV.Count) + { + for (int i = 0; i < _UV.Count; ++i) + _UV[i] = mesh._UV[i]; + + for (int i = _UV.Count; i < mesh._UV.Count; ++i) + _UV.Add(mesh._UV[i]); + } + else + { + for (int i = 0; i < mesh._UV.Count; ++i) + _UV[i] = mesh._UV[i]; + + for (int i = _UV.Count - 1; i >= mesh._UV.Count; --i) + _UV.RemoveAt(i); + } + } + + public int VertCnt() + { + return _Vertices.Count; + } + + public int UVCnt() + { + return _UV.Count; + } + + public void AddVert(Vector3 v) + { + _Vertices.Add(v); + } + + public void AddUV(Vector2 uv) + { + _UV.Add(uv); + } + + public void SetVertLen(int l) + { + if (l > _Vertices.Count) + { + for (int i = _Vertices.Count; i < l; ++i) + { + _Vertices.Add(Vector3.zero); + } + } + else + { + for (int i = _Vertices.Count - 1; i >= l; --i) + { + _Vertices.RemoveAt(i); + } + } + } + + public void SetUVLen(int l) + { + if (l > _UV.Count) + { + for (int i = _UV.Count; i < l; ++i) + { + _UV.Add(Vector2.zero); + } + } + else + { + for (int i = _UV.Count - 1; i >= l; --i) + { + _UV.RemoveAt(i); + } + } + } + + public void SetVert(int index, Vector3 v) + { + if (index < _Vertices.Count) + { + _Vertices[index] = v; + } + else + throw new System.IndexOutOfRangeException(); + } + + public void SetUV(int index, Vector2 v) + { + if (index < _UV.Count) + { + _UV[index] = v; + } + else + throw new System.IndexOutOfRangeException(); + } + + public Vector3 GetVert(int index) + { + if (index < _Vertices.Count) + { + return _Vertices[index]; + } + throw new System.IndexOutOfRangeException(); + } + + public Vector2 GetUV(int index) + { + if (index < _UV.Count) + { + return _UV[index]; + } + throw new System.IndexOutOfRangeException(); + } + + public bool Equals(UnitMeshInfo other) + { + if (atlas != other.atlas || _Vertices.Count != other._Vertices.Count) + return false; + + for (int i = 0; i < _Vertices.Count; i++) + if (_Vertices[i] != other._Vertices[i]) + return false; + + for (int i = 0; i < _UV.Count; i++) + if (_UV[i] != other._UV[i]) + return false; + return true; + } + } + + public class MeshInfo + { + public List _Tag = new List(); + public List _Vertices = new List(); + public List _UV = new List(); + + public void Clear() + { + _Tag.Clear(); + _Vertices.Clear(); + _UV.Clear(); + } + + public void Copy(MeshInfo other) + { + Clear(); + _Tag.AddRange(other._Tag); + _Vertices.AddRange(other._Vertices); + _UV.AddRange(other._UV); + } + + //比较数据是否一样 + public bool Equals(MeshInfo _value) + { + if (_Tag.Count != _value._Tag.Count || _Vertices.Count != _value._Vertices.Count) + return false; + + for (int i = 0; i < _Tag.Count; i++) + if (_Tag[i] != _value._Tag[i]) + return false; + for (int i = 0; i < _Vertices.Count; i++) + if (_Vertices[i] != _value._Vertices[i]) + return false; + return true; + } + } + +} diff --git a/Assets/TextInlineSprite/Scripts/EmojiMeshData.cs.meta b/Assets/TextInlineSprite/Scripts/EmojiMeshData.cs.meta new file mode 100644 index 0000000..4fa56df --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/EmojiMeshData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e539b72a94565fa4baeaf8a0adc751e2 +timeCreated: 1532007087 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TextInlineSprite/Scripts/EmojiTools.cs b/Assets/TextInlineSprite/Scripts/EmojiTools.cs index 4ffc2b7..6bca2ab 100644 --- a/Assets/TextInlineSprite/Scripts/EmojiTools.cs +++ b/Assets/TextInlineSprite/Scripts/EmojiTools.cs @@ -10,120 +10,120 @@ namespace EmojiUI { - internal static class EmojiTools - { + internal static class EmojiTools + { #if DebugInfo - - private static long unitymemorysize; - - private static long? last; - - private static DumpClass dumptarget; - - private class DumpClass:MonoBehaviour - { - private void OnGUI() - { - GUILayout.Label(DumpDebugInfo()); - } - } - + + private static long unitymemorysize; + + private static long? last; + + private static DumpClass dumptarget; + + private class DumpClass : MonoBehaviour + { + private void OnGUI() + { + GUILayout.Label(DumpDebugInfo()); + } + } + #endif - - public static void StartDumpGUI() - { - + + public static void StartDumpGUI() + { + #if DebugInfo - if(dumptarget == null) - { - Camera camera = GameObject.FindObjectOfType(); - if(camera != null) - { - dumptarget = camera.GetComponent(); - if (dumptarget == null) - dumptarget = camera.gameObject.AddComponent(); - else - dumptarget.enabled = true; - } - } + if (dumptarget == null) + { + Camera camera = GameObject.FindObjectOfType(); + if (camera != null) + { + dumptarget = camera.GetComponent(); + if (dumptarget == null) + dumptarget = camera.gameObject.AddComponent(); + else + dumptarget.enabled = true; + } + } #endif - } - - public static void EndDumpGUI() - { - + } + + public static void EndDumpGUI() + { + #if DebugInfo - if (dumptarget != null) - { - Camera camera = GameObject.FindObjectOfType(); - if (camera != null) - { - dumptarget = camera.GetComponent(); - if (dumptarget != null) - { - dumptarget.enabled = false; - } - } - } + if (dumptarget != null) + { + Camera camera = GameObject.FindObjectOfType(); + if (camera != null) + { + dumptarget = camera.GetComponent(); + if (dumptarget != null) + { + dumptarget.enabled = false; + } + } + } #endif - } - - static String[] units = new String[] { "B", "KB", "MB", "GB", "TB", "PB" }; - static String Getsize(double size) - { - double mod = 1024; - int i = 0; - while (size >= mod) - { - size /= mod; - i++; - } - return String.Format("{0:0.##} {1}", size, units[i]); - } - - public static string DumpDebugInfo() - { - + } + + static String[] units = new String[] { "B", "KB", "MB", "GB", "TB", "PB" }; + static String Getsize(double size) + { + double mod = 1024; + int i = 0; + while (size >= mod) + { + size /= mod; + i++; + } + return String.Format("{0:0.##} {1}", size, units[i]); + } + + public static string DumpDebugInfo() + { + #if DebugInfo - string result = string.Format("c# sharpMemroy :{0} Unity emoji ManagedMemory:{1}\n", - Getsize(GC.GetTotalMemory(false)), - Getsize(unitymemorysize)); - Debug.Log(result); - return result; + string result = string.Format("c# sharpMemroy :{0} Unity emoji ManagedMemory:{1}\n", + Getsize(GC.GetTotalMemory(false)), + Getsize(unitymemorysize)); + Debug.Log(result); + return result; #endif - } - - public static void AddUnityMemory(UnityEngine.Object obj) - { + } + + public static void AddUnityMemory(UnityEngine.Object obj) + { #if DebugInfo - if (obj != null) - unitymemorysize += Profiler.GetRuntimeMemorySizeLong(obj); + if (obj != null) + unitymemorysize += Profiler.GetRuntimeMemorySizeLong(obj); #endif - - } - - public static void RemoveUnityMemory(UnityEngine.Object obj) - { + + } + + public static void RemoveUnityMemory(UnityEngine.Object obj) + { #if DebugInfo - if (obj != null) - unitymemorysize -= Profiler.GetRuntimeMemorySizeLong(obj); + if (obj != null) + unitymemorysize -= Profiler.GetRuntimeMemorySizeLong(obj); #endif - } - - public static void BeginSample(string key) - { + } + + public static void BeginSample(string key) + { #if UNITY_EDITOR - Profiler.BeginSample(key); + Profiler.BeginSample(key); #endif - } - - public static void EndSample() - { + } + + public static void EndSample() + { #if UNITY_EDITOR - Profiler.EndSample(); + Profiler.EndSample(); #endif - } - } + } + } } diff --git a/Assets/TextInlineSprite/Scripts/EmojiUIData.cs b/Assets/TextInlineSprite/Scripts/EmojiUIData.cs index 1951dbb..16e30b0 100644 --- a/Assets/TextInlineSprite/Scripts/EmojiUIData.cs +++ b/Assets/TextInlineSprite/Scripts/EmojiUIData.cs @@ -6,317 +6,38 @@ namespace EmojiUI { - [System.Serializable] - public class SpriteInfo - { - ///

- /// 精灵 - /// - public Sprite sprite; - /// - /// 标签 - /// - public string tag; - /// - /// uv - /// - public Vector2[] uv; - } - - [System.Serializable] - public class SpriteInfoGroup - { - public string tag = ""; - - public float width = 1.0f; - public float size = 24.0f; - - public float x; - public float y; - - public List spritegroups = new List(); - } - - public class SpriteTagInfo - { - //图集ID - public int _ID; - //标签标签 - public string _Tag; - //标签大小 - public Vector2 _Size; - //表情位置 - public Vector3[] _Pos; - //位置索引 - private int _Position =-1; - //uv - public Vector2[] _UV; - - private const int dv = 100000; - - public void FillIdxAndPlaceHolder(int idx,int cnt) - { - _Position = cnt * dv + idx; - } - - public int GetPlaceHolderCnt() - { - return _Position / dv; - } - - public int GetPositionIdx() - { - return _Position % dv; - } - } - - public class UnitMeshInfo:IEquatable - { - private SpriteAsset atlas; - private List _Vertices = new List(); - private List _UV = new List(); - - public Texture getTexture() - { - if(atlas != null) - return atlas.texSource; - return null; - } - - public SpriteAsset GetAtlas() - { - return atlas; - } - - public void SetAtlas(SpriteAsset data) - { - atlas = data; - } - - public void Clear() - { - atlas = null; - _Vertices.Clear(); - _UV.Clear(); - } - - public void AddCopy(UnitMeshInfo mesh) - { - if(atlas != null && atlas!= mesh.atlas) - { - throw new ArgumentException(); - } - atlas = mesh.atlas; - - for (int i = 0; i < mesh._Vertices.Count; ++i) - _Vertices.Add( mesh._Vertices[i]); - - for (int i = 0; i < mesh._UV.Count; ++i) - _UV.Add(mesh._UV[i]); - } - - public void Copy(UnitMeshInfo mesh) - { - atlas = mesh.atlas; - - if(_Vertices.Count < mesh._Vertices.Count) - { - for (int i = 0; i < _Vertices.Count; ++i) - _Vertices[i] = mesh._Vertices[i]; - - for(int i = _Vertices.Count;i < mesh._Vertices.Count;++i) - _Vertices.Add(mesh._Vertices[i]); - } - else - { - for (int i = 0; i < mesh._Vertices.Count; ++i) - _Vertices[i] = mesh._Vertices[i]; - - for (int i = _Vertices.Count - 1; i >= mesh._Vertices.Count; --i) - _Vertices.RemoveAt(i); - } - - - if (_UV.Count < mesh._UV.Count) - { - for (int i = 0; i < _UV.Count; ++i) - _UV[i] = mesh._UV[i]; - - for (int i = _UV.Count; i < mesh._UV.Count; ++i) - _UV.Add(mesh._UV[i]); - } - else - { - for (int i = 0; i < mesh._UV.Count; ++i) - _UV[i] = mesh._UV[i]; - - for (int i = _UV.Count - 1; i >= mesh._UV.Count; --i) - _UV.RemoveAt(i); - } - } - - public int VertCnt() - { - return _Vertices.Count; - } - - public int UVCnt() - { - return _UV.Count; - } - - public void AddVert(Vector3 v) - { - _Vertices.Add(v); - } - - public void AddUV(Vector2 uv) - { - _UV.Add(uv); - } - - public void SetVertLen(int l) - { - if(l > _Vertices.Count) - { - for (int i = _Vertices.Count ; i < l; ++i) - { - _Vertices.Add(Vector3.zero); - } - } - else - { - for(int i =_Vertices.Count-1;i >=l;--i ) - { - _Vertices.RemoveAt(i); - } - } - } - - public void SetUVLen(int l) - { - if (l > _UV.Count) - { - for (int i = _UV.Count ; i < l; ++i) - { - _UV.Add(Vector2.zero); - } - } - else - { - for (int i = _UV.Count - 1; i >= l; --i) - { - _UV.RemoveAt(i); - } - } - } - - public void SetVert(int index, Vector3 v) - { - if (index < _Vertices.Count) - { - _Vertices[index] = v; - } - else - throw new System.IndexOutOfRangeException(); - } - - public void SetUV(int index,Vector2 v) - { - if (index < _UV.Count) - { - _UV[index] = v; - } - else - throw new System.IndexOutOfRangeException(); - } - - public Vector3 GetVert(int index) - { - if(index < _Vertices.Count) - { - return _Vertices[index]; - } - throw new System.IndexOutOfRangeException(); - } - - public Vector2 GetUV(int index) - { - if (index < _UV.Count) - { - return _UV[index]; - } - throw new System.IndexOutOfRangeException(); - } - - public bool Equals(UnitMeshInfo other) - { - if (atlas != other.atlas || _Vertices.Count != other._Vertices.Count) - return false; - - for (int i = 0; i < _Vertices.Count; i++) - if (_Vertices[i] != other._Vertices[i]) - return false; - - for (int i = 0; i < _UV.Count; i++) - if (_UV[i] != other._UV[i]) - return false; - return true; - } - } - - public class MeshInfo - { - public List _Tag = new List(); - public List _Vertices = new List(); - public List _UV = new List(); - - public void Clear() - { - _Tag.Clear(); - _Vertices.Clear(); - _UV.Clear(); - } - - public void Copy(MeshInfo other) - { - - - Clear(); - - _Tag.AddRange(other._Tag); - _Vertices.AddRange(other._Vertices); - _UV.AddRange(other._UV); - } - - //比较数据是否一样 - public bool Equals(MeshInfo _value) - { - if (_Tag.Count != _value._Tag.Count || _Vertices.Count != _value._Vertices.Count) - return false; - - for (int i = 0; i < _Tag.Count; i++) - if (_Tag[i] != _value._Tag[i]) - return false; - for (int i = 0; i < _Vertices.Count; i++) - if (_Vertices[i] != _value._Vertices[i]) - return false; - return true; - } - } - - public class HrefInfo - { - public int id; - - public int startIndex; - - public int endIndex; - - public string name; - - public readonly List boxes = new List(); - } - + #region sprites + [System.Serializable] + public class SpriteInfo + { + /// + /// 精灵 + /// + public Sprite sprite; + /// + /// 标签 + /// + public string tag; + /// + /// uv + /// + public Vector2[] uv; + } + + [System.Serializable] + public class SpriteInfoGroup + { + public string tag = ""; + + public float width = 1.0f; + public float size = 24.0f; + + public float x; + public float y; + + public List spritegroups = new List(); + } + + #endregion } diff --git a/Assets/TextInlineSprite/Scripts/InlineManager.cs b/Assets/TextInlineSprite/Scripts/InlineManager.cs index 7ef3419..1b23aa6 100644 --- a/Assets/TextInlineSprite/Scripts/InlineManager.cs +++ b/Assets/TextInlineSprite/Scripts/InlineManager.cs @@ -5,586 +5,587 @@ /// date: /// version:v1.0 /// ======================================================== - + using System.Collections; using System.Collections.Generic; using UnityEngine; -using System; +using System; #if UNITY_EDITOR -using UnityEditor; +using UnityEditor; #endif - -namespace EmojiUI -{ - public class InlineManager : MonoBehaviour - { - private List sharedAtlases = new List(); - private Dictionary alltags = new Dictionary(); +namespace EmojiUI +{ + [DefaultExecutionOrder(-99999)] + public class InlineManager : MonoBehaviour + { + private List sharedAtlases = new List(); - private IEmojiRender _Render; + private Dictionary alltags = new Dictionary(); - public List PreparedAtlas = new List(); + private IEmojiRender _Render; + + public List PreparedAtlas = new List(); #if UNITY_EDITOR - [SerializeField] - private bool _openDebug; - public bool OpenDebug - { - get - { - return _openDebug; - } - set - { - if(_openDebug != value) - { - _openDebug = value; - if(Application.isPlaying) - { - if (value) - { - EmojiTools.StartDumpGUI(); - } - else - { - EmojiTools.EndDumpGUI(); - } - } - } - } - } - - private List unityallAtlases; - - private List lostAssets; -#endif - [SerializeField] - private float _animationspeed =5f; - public float AnimationSpeed - { - get - { - return _animationspeed; - } - set - { - if(_Render != null) - { - _Render.Speed = value; - } - _animationspeed = value; - } - } - - [SerializeField] - private EmojiRenderType _renderType = EmojiRenderType.RenderUnit; - public EmojiRenderType renderType - { - get - { - return _renderType; - } - set - { - if (_renderType != value) - { - _renderType = value; - InitRender(); - } - } - } - - void Awake() - { + [SerializeField] + private bool _openDebug; + public bool OpenDebug + { + get + { + return _openDebug; + } + set + { + if (_openDebug != value) + { + _openDebug = value; + if (Application.isPlaying) + { + if (value) + { + EmojiTools.StartDumpGUI(); + } + else + { + EmojiTools.EndDumpGUI(); + } + } + } + } + } + + private List unityallAtlases; + + private List lostAssets; +#endif + [SerializeField] + private float _animationspeed = 5f; + public float AnimationSpeed + { + get + { + return _animationspeed; + } + set + { + if (_Render != null) + { + _Render.Speed = value; + } + _animationspeed = value; + } + } + + [SerializeField] + private EmojiRenderType _renderType = EmojiRenderType.RenderUnit; + public EmojiRenderType renderType + { + get + { + return _renderType; + } + set + { + if (_renderType != value) + { + _renderType = value; + InitRender(); + } + } + } + + void Awake() + { #if UNITY_EDITOR - if(OpenDebug) - { - EmojiTools.StartDumpGUI(); - } + if (OpenDebug) + { + EmojiTools.StartDumpGUI(); + } #endif - - EmojiTools.BeginSample("Emoji_Init"); - Initialize(); - EmojiTools.EndSample(); - - EmojiTools.AddUnityMemory(this); - } - - void Initialize() - { -#if UNITY_EDITOR - string[] result = AssetDatabase.FindAssets(string.Format("t:{0}",typeof(SpriteAsset).FullName)); - - if (result.Length > 0 && unityallAtlases == null) - { - unityallAtlases = new List(result.Length); - for (int i = 0; i < result.Length; ++i) - { - string path = AssetDatabase.GUIDToAssetPath(result[i]); - SpriteAsset asset = AssetDatabase.LoadAssetAtPath(path); - if (asset) - { - unityallAtlases.Add(asset); - } - } - } - Debug.LogFormat("find :{0} atlas resource", result.Length); - Debug.LogWarning("if your asset not in the resources please override InstantiateSpriteAsset"); + + EmojiTools.BeginSample("Emoji_Init"); + Initialize(); + EmojiTools.EndSample(); + + EmojiTools.AddUnityMemory(this); + } + + void Initialize() + { +#if UNITY_EDITOR + string[] result = AssetDatabase.FindAssets(string.Format("t:{0}", typeof(SpriteAsset).FullName)); + + if (result.Length > 0 && unityallAtlases == null) + { + unityallAtlases = new List(result.Length); + for (int i = 0; i < result.Length; ++i) + { + string path = AssetDatabase.GUIDToAssetPath(result[i]); + SpriteAsset asset = AssetDatabase.LoadAssetAtPath(path); + if (asset) + { + unityallAtlases.Add(asset); + } + } + } + Debug.LogFormat("find :{0} atlas resource", result.Length); + Debug.LogWarning("if your asset not in the resources please override InstantiateSpriteAsset"); #endif - - EmojiTools.BeginSample("Emoji_Init"); - InitRender(); - EmojiTools.EndSample(); - - EmojiTools.BeginSample("Emoji_preLoad"); - PreLoad(); - EmojiTools.EndSample(); - RebuildTagList(); + EmojiTools.BeginSample("Emoji_Init"); + InitRender(); + EmojiTools.EndSample(); - ForceRebuild(); - } + EmojiTools.BeginSample("Emoji_preLoad"); + PreLoad(); + EmojiTools.EndSample(); - void LateUpdate() - { - EmojiTools.BeginSample("Emoji_LateUpdate"); - if(_Render != null) - { - _Render.LateUpdate(); - } - EmojiTools.EndSample(); - } + RebuildTagList(); + + ForceRebuild(); + } + + void LateUpdate() + { + EmojiTools.BeginSample("Emoji_LateUpdate"); + if (_Render != null) + { + _Render.LateUpdate(); + } + EmojiTools.EndSample(); + } - private void OnDestroy() - { + private void OnDestroy() + { #if UNITY_EDITOR - if (lostAssets != null) - { - for (int i = 0; i < lostAssets.Count; ++i) - { - string asset = lostAssets[i]; - Debug.LogError(string.Format("not prepred atlasAsset named :{0}", asset)); - } - } + if (lostAssets != null) + { + for (int i = 0; i < lostAssets.Count; ++i) + { + string asset = lostAssets[i]; + Debug.LogError(string.Format("not prepred atlasAsset named :{0}", asset)); + } + } #endif - if (_Render != null) + if (_Render != null) + { + _Render.Dispose(); + } + + _Render = null; + EmojiTools.RemoveUnityMemory(this); + } + + protected virtual SpriteAsset InstantiateSpriteAsset(string filepath) + { + return Resources.Load(filepath); + } + + void InitRender() + { + if (_Render == null || _Render.renderType != renderType) + { + + if (renderType == EmojiRenderType.RenderGroup) + { + EmojiRenderGroup newRender = new EmojiRenderGroup(this); + newRender.Speed = AnimationSpeed; + + if (_Render != null) + { + List list = _Render.GetAllRenders(); + if (list != null) + { + for (int i = 0; i < list.Count; ++i) + { + InlineText text = list[i]; + if (text != null) + newRender.TryRendering(text); + } + } + + List atlaslist = _Render.GetAllRenderAtlas(); + if (atlaslist != null) + { + for (int i = 0; i < atlaslist.Count; ++i) + { + SpriteAsset atlas = atlaslist[i]; + if (atlas != null) + newRender.PrepareAtlas(atlas); + } + } + _Render.Dispose(); + } + + _Render = newRender; + + } + else if (renderType == EmojiRenderType.RenderUnit) + { + UnitRender newRender = new UnitRender(this); + newRender.Speed = AnimationSpeed; + + if (_Render != null) + { + List list = _Render.GetAllRenders(); + if (list != null) + { + for (int i = 0; i < list.Count; ++i) + { + InlineText text = list[i]; + if (text != null) + newRender.TryRendering(text); + } + } + + List atlaslist = _Render.GetAllRenderAtlas(); + if (atlaslist != null) + { + for (int i = 0; i < atlaslist.Count; ++i) + { + SpriteAsset atlas = atlaslist[i]; + if (atlas != null) + newRender.PrepareAtlas(atlas); + } + } + + _Render.Dispose(); + } + + _Render = newRender; + } + else + { + Debug.LogError("not support yet"); + this.enabled = false; + } + } + } + + void PreLoad() + { + for (int i = 0; i < PreparedAtlas.Count; ++i) + { + string atlasname = PreparedAtlas[i]; + string fixname = System.IO.Path.GetFileNameWithoutExtension(atlasname); + SpriteAsset _spriteAsset = FindAtlas(fixname); + PushRenderAtlas(_spriteAsset); + } + } + + void RebuildTagList() + { + EmojiTools.BeginSample("Emoji_rebuildTags"); + alltags.Clear(); +#if UNITY_EDITOR + if (unityallAtlases != null) + { + for (int i = 0; i < unityallAtlases.Count; ++i) + { + SpriteAsset asset = unityallAtlases[i]; + for (int j = 0; j < asset.listSpriteGroup.Count; ++j) + { + SpriteInfoGroup infogroup = asset.listSpriteGroup[j]; + SpriteInfoGroup group; + if (alltags.TryGetValue(infogroup.tag, out group)) + { + Debug.LogErrorFormat("already exist :{0} ", infogroup.tag); + } + + alltags[infogroup.tag] = infogroup; + } + } + } + +#else + for (int i = 0; i < sharedAtlases.Count; ++i) { - _Render.Dispose(); - } - - _Render = null; - EmojiTools.RemoveUnityMemory(this); - } - - protected virtual SpriteAsset InstantiateSpriteAsset(string filepath) - { - return Resources.Load(filepath); - } - - void InitRender() - { - if (_Render == null || _Render.renderType != renderType) - { - - if (renderType == EmojiRenderType.RenderGroup) + SpriteAsset asset = sharedAtlases[i]; + for (int j = 0; j < asset.listSpriteGroup.Count; ++j) { - EmojiRenderGroup newRender = new EmojiRenderGroup(this); - newRender.Speed = AnimationSpeed; - - if(_Render != null) + SpriteInfoGroup infogroup = asset.listSpriteGroup[j]; + SpriteInfoGroup group; + if (alltags.TryGetValue(infogroup.tag, out group)) { - List list = _Render.GetAllRenders(); - if(list != null) - { - for (int i = 0; i < list.Count; ++i) - { - InlineText text = list[i]; - if(text != null) - newRender.TryRendering(text); - } - } - - List atlaslist = _Render.GetAllRenderAtlas(); - if (atlaslist != null) - { - for (int i = 0; i < atlaslist.Count; ++i) - { - SpriteAsset atlas = atlaslist[i]; - if (atlas != null) - newRender.PrepareAtlas(atlas); - } - } - _Render.Dispose(); + Debug.LogErrorFormat("already exist :{0} ", infogroup.tag); } + + alltags[infogroup.tag] = infogroup; + } + } +#endif + EmojiTools.EndSample(); + } + + public IEmojiRender Register(InlineText _key) + { + EmojiTools.BeginSample("Emoji_Register"); + if (_Render != null) + { + if (_Render.TryRendering(_key)) + { + EmojiTools.EndSample(); + return _Render; + } + } + EmojiTools.EndSample(); + return null; + } + + + /// + /// 移除文本 + /// + /// + /// + public void UnRegister(InlineText _key) + { + EmojiTools.BeginSample("Emoji_UnRegister"); + if (_Render != null) + { + _Render.DisRendering(_key); + } + EmojiTools.EndSample(); + } + + public void ForceRebuild() + { + EmojiTools.BeginSample("Emoji_ForceRebuild"); + InlineText[] alltexts = GetComponentsInChildren(); + for (int i = 0; i < alltexts.Length; i++) + { + alltexts[i].SetVerticesDirty(); + } + EmojiTools.EndSample(); + } + + /// + /// 清除所有的精灵 + /// + public void ClearAllSprites() + { + EmojiTools.BeginSample("Emoji_ClearAll"); + if (_Render != null) + { + _Render.Clear(); + } + EmojiTools.EndSample(); + } + + public bool isRendering(SpriteAsset _spriteAsset) + { + return _spriteAsset != null && _Render != null && _Render.isRendingAtlas(_spriteAsset); + } + + public bool CanRendering(string tagName) + { + return alltags != null && alltags.ContainsKey(tagName); + } + + public bool CanRendering(int atlasId) + { - _Render = newRender; +#if UNITY_EDITOR + if (unityallAtlases != null) + { + for (int i = 0; i < unityallAtlases.Count; ++i) + { + SpriteAsset asset = unityallAtlases[i]; + if (asset.ID == atlasId) + { + return true; + } + } + } + + return false; +#else + for (int i = 0; i < sharedAtlases.Count; ++i) + { + SpriteAsset asset = sharedAtlases[i]; + if (asset.ID == atlasId) + { + return true; + } + } + return false; +#endif + } + + public void PushRenderAtlas(SpriteAsset _spriteAsset) + { + EmojiTools.BeginSample("Emoji_PushRenderAtlas"); + if (!isRendering(_spriteAsset) && _spriteAsset != null) + { + _Render.PrepareAtlas(_spriteAsset); + + if (!sharedAtlases.Contains(_spriteAsset)) + { + sharedAtlases.Add(_spriteAsset); + } + } + EmojiTools.EndSample(); + } + + public SpriteInfoGroup FindSpriteGroup(string TagName, out SpriteAsset resultatlas) + { + EmojiTools.BeginSample("Emoji_FindSpriteGroup"); +#if UNITY_EDITOR - } - else if (renderType == EmojiRenderType.RenderUnit) - { - UnitRender newRender = new UnitRender(this); - newRender.Speed = AnimationSpeed; + resultatlas = null; + + SpriteInfoGroup result = null; + if (unityallAtlases != null) + { + for (int i = 0; i < unityallAtlases.Count; ++i) + { + SpriteAsset asset = unityallAtlases[i]; + for (int j = 0; j < asset.listSpriteGroup.Count; ++j) + { + SpriteInfoGroup group = asset.listSpriteGroup[j]; + if (group.tag.Equals(TagName)) + { + result = group; + resultatlas = asset; + break; + } + } + } + } + + if (lostAssets == null) + lostAssets = new List(); + + if (resultatlas != null && !PreparedAtlas.Contains(resultatlas.AssetName)) + { + if (!lostAssets.Contains(resultatlas.AssetName)) + lostAssets.Add(resultatlas.AssetName); + } + EmojiTools.EndSample(); + return result; +#else + resultatlas = null; - if (_Render != null) + SpriteInfoGroup result = null; + if(sharedAtlases != null) + { + for (int i = 0; i < sharedAtlases.Count; ++i) + { + SpriteAsset asset = sharedAtlases[i]; + for (int j = 0; j < asset.listSpriteGroup.Count; ++j) { - List list = _Render.GetAllRenders(); - if (list != null) - { - for (int i = 0; i < list.Count; ++i) - { - InlineText text = list[i]; - if (text != null) - newRender.TryRendering(text); - } - } - - List atlaslist = _Render.GetAllRenderAtlas(); - if (atlaslist != null) + SpriteInfoGroup group = asset.listSpriteGroup[j]; + if (group.tag.Equals(TagName)) { - for (int i = 0; i < atlaslist.Count; ++i) - { - SpriteAsset atlas = atlaslist[i]; - if (atlas != null) - newRender.PrepareAtlas(atlas); - } + result = group; + resultatlas = asset; + break; } - - _Render.Dispose(); } - - _Render = newRender; - } - else - { - Debug.LogError("not support yet"); - this.enabled = false; - } - } - } - - void PreLoad() - { - for (int i = 0; i < PreparedAtlas.Count; ++i) - { - string atlasname = PreparedAtlas[i]; - string fixname = System.IO.Path.GetFileNameWithoutExtension(atlasname); - SpriteAsset _spriteAsset = FindAtlas(fixname); - PushRenderAtlas(_spriteAsset); - } - } - - void RebuildTagList() - { - EmojiTools.BeginSample("Emoji_rebuildTags"); - alltags.Clear(); -#if UNITY_EDITOR - if(unityallAtlases != null) - { - for (int i = 0; i < unityallAtlases.Count; ++i) - { - SpriteAsset asset = unityallAtlases[i]; - for (int j = 0; j < asset.listSpriteGroup.Count; ++j) - { - SpriteInfoGroup infogroup = asset.listSpriteGroup[j]; - SpriteInfoGroup group; - if (alltags.TryGetValue(infogroup.tag, out group)) - { - Debug.LogErrorFormat("already exist :{0} ", infogroup.tag); - } - - alltags[infogroup.tag] = infogroup; - } - } - } - -#else - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - for (int j = 0; j < asset.listSpriteGroup.Count; ++j) - { - SpriteInfoGroup infogroup = asset.listSpriteGroup[j]; - SpriteInfoGroup group; - if (alltags.TryGetValue(infogroup.tag, out group)) - { - Debug.LogErrorFormat("already exist :{0} ", infogroup.tag); - } - - alltags[infogroup.tag] = infogroup; - } - } -#endif - EmojiTools.EndSample(); - } - - public IEmojiRender Register(InlineText _key) - { - EmojiTools.BeginSample("Emoji_Register"); - if (_Render != null) - { - if (_Render.TryRendering(_key)) - { - EmojiTools.EndSample(); - return _Render; - } - } - EmojiTools.EndSample(); - return null; - } - - - /// - /// 移除文本 - /// - /// - /// - public void UnRegister(InlineText _key) - { - EmojiTools.BeginSample("Emoji_UnRegister"); - if (_Render != null) - { - _Render.DisRendering(_key); - } - EmojiTools.EndSample(); - } - - public void ForceRebuild() - { - EmojiTools.BeginSample("Emoji_ForceRebuild"); - InlineText[] alltexts = GetComponentsInChildren(); - for (int i = 0; i < alltexts.Length; i++) - { - alltexts[i].SetVerticesDirty(); - } - EmojiTools.EndSample(); - } - - /// - /// 清除所有的精灵 - /// - public void ClearAllSprites() - { - EmojiTools.BeginSample("Emoji_ClearAll"); - if(_Render!= null) - { - _Render.Clear(); - } - EmojiTools.EndSample(); - } - - public bool isRendering(SpriteAsset _spriteAsset) - { - return _spriteAsset != null && _Render != null && _Render.isRendingAtlas(_spriteAsset); - } - - public bool CanRendering(string tagName) - { - return alltags.ContainsKey(tagName); - } - - public bool CanRendering(int atlasId) - { - -#if UNITY_EDITOR - if (unityallAtlases != null) - { - for (int i = 0; i < unityallAtlases.Count; ++i) - { - SpriteAsset asset = unityallAtlases[i]; - if (asset.ID == atlasId) - { - return true; - } - } - } - - return false; -#else - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - if (asset.ID == atlasId) - { - return true; - } - } - return false; -#endif - } - - public void PushRenderAtlas(SpriteAsset _spriteAsset) - { - EmojiTools.BeginSample("Emoji_PushRenderAtlas"); - if (!isRendering(_spriteAsset) && _spriteAsset != null) - { - _Render.PrepareAtlas(_spriteAsset); - - if (!sharedAtlases.Contains(_spriteAsset)) - { - sharedAtlases.Add(_spriteAsset); - } + } } - EmojiTools.EndSample(); - } + EmojiTools.EndSample(); + return result; +#endif + } - public SpriteInfoGroup FindSpriteGroup(string TagName,out SpriteAsset resultatlas) - { - EmojiTools.BeginSample("Emoji_FindSpriteGroup"); -#if UNITY_EDITOR - - resultatlas = null; - - SpriteInfoGroup result = null; - if (unityallAtlases != null) - { - for (int i = 0; i < unityallAtlases.Count; ++i) - { - SpriteAsset asset = unityallAtlases[i]; - for (int j = 0; j < asset.listSpriteGroup.Count; ++j) - { - SpriteInfoGroup group = asset.listSpriteGroup[j]; - if (group.tag.Equals(TagName)) - { - result = group; - resultatlas = asset; - break; - } - } - } - } - - if (lostAssets == null) - lostAssets = new List(); - - if (resultatlas!= null && !PreparedAtlas.Contains(resultatlas.AssetName) ) - { - if(!lostAssets.Contains(resultatlas.AssetName)) - lostAssets.Add(resultatlas.AssetName); - } - EmojiTools.EndSample(); - return result; -#else - resultatlas = null; - - SpriteInfoGroup result = null; - if(sharedAtlases != null) - { - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - for (int j = 0; j < asset.listSpriteGroup.Count; ++j) - { - SpriteInfoGroup group = asset.listSpriteGroup[j]; - if (group.tag.Equals(TagName)) - { - result = group; - resultatlas = asset; - break; - } - } - } - } - EmojiTools.EndSample(); - return result; -#endif - } - - public SpriteAsset FindAtlas(int atlasID) - { - EmojiTools.BeginSample("Emoji_FindAtlas"); + public SpriteAsset FindAtlas(int atlasID) + { + EmojiTools.BeginSample("Emoji_FindAtlas"); #if UNITY_EDITOR - SpriteAsset result = null; - if(unityallAtlases != null) - { - for (int i = 0; i < unityallAtlases.Count; ++i) - { - SpriteAsset asset = unityallAtlases[i]; - if (asset.ID.Equals(atlasID)) - { - result = asset; - break; - } - } - } - - if (lostAssets == null) - lostAssets = new List(); - - if (result != null && !PreparedAtlas.Contains(result.AssetName)) - { - if (!lostAssets.Contains(result.AssetName)) - lostAssets.Add(result.AssetName); - } - EmojiTools.EndSample(); - return result; -#else - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - if (asset.ID.Equals(atlasID)) + SpriteAsset result = null; + if (unityallAtlases != null) + { + for (int i = 0; i < unityallAtlases.Count; ++i) + { + SpriteAsset asset = unityallAtlases[i]; + if (asset.ID.Equals(atlasID)) + { + result = asset; + break; + } + } + } + + if (lostAssets == null) + lostAssets = new List(); + + if (result != null && !PreparedAtlas.Contains(result.AssetName)) + { + if (!lostAssets.Contains(result.AssetName)) + lostAssets.Add(result.AssetName); + } + EmojiTools.EndSample(); + return result; +#else + for (int i = 0; i < sharedAtlases.Count; ++i) + { + SpriteAsset asset = sharedAtlases[i]; + if (asset.ID.Equals(atlasID)) { - EmojiTools.EndSample(); - return asset; - } + EmojiTools.EndSample(); + return asset; + } } EmojiTools.EndSample(); - return null; + return null; #endif - } + } - public SpriteAsset FindAtlas(string atlasname) - { - EmojiTools.BeginSample("FindAtlas"); + public SpriteAsset FindAtlas(string atlasname) + { + EmojiTools.BeginSample("FindAtlas"); #if UNITY_EDITOR - SpriteAsset result = null; - if (unityallAtlases != null) - { - for (int i = 0; i < unityallAtlases.Count; ++i) - { - SpriteAsset asset = unityallAtlases[i]; - if (asset.AssetName.Equals(atlasname)) - { - result = asset; - break; - } - } - } - - if (lostAssets == null) - lostAssets = new List(); - - if (!PreparedAtlas.Contains(atlasname)) - { - if (!lostAssets.Contains(atlasname)) - lostAssets.Add(atlasname); - } - EmojiTools.EndSample(); - return result; -#else - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - if (asset.AssetName.Equals(atlasname)) + SpriteAsset result = null; + if (unityallAtlases != null) + { + for (int i = 0; i < unityallAtlases.Count; ++i) + { + SpriteAsset asset = unityallAtlases[i]; + if (asset.AssetName.Equals(atlasname)) + { + result = asset; + break; + } + } + } + + if (lostAssets == null) + lostAssets = new List(); + + if (!PreparedAtlas.Contains(atlasname)) + { + if (!lostAssets.Contains(atlasname)) + lostAssets.Add(atlasname); + } + EmojiTools.EndSample(); + return result; +#else + for (int i = 0; i < sharedAtlases.Count; ++i) + { + SpriteAsset asset = sharedAtlases[i]; + if (asset.AssetName.Equals(atlasname)) { - EmojiTools.EndSample(); - return asset; - } - } + EmojiTools.EndSample(); + return asset; + } + } - SpriteAsset newasset = InstantiateSpriteAsset(atlasname); - if(newasset != null) - { - sharedAtlases.Add(newasset); + SpriteAsset newasset = InstantiateSpriteAsset(atlasname); + if(newasset != null) + { + sharedAtlases.Add(newasset); } - EmojiTools.EndSample(); - return newasset; + EmojiTools.EndSample(); + return newasset; #endif - - } - } + + } + } } diff --git a/Assets/TextInlineSprite/Scripts/InlineRender/EmojiRenderGroup.cs b/Assets/TextInlineSprite/Scripts/InlineRender/EmojiRenderGroup.cs index 1b327c4..793bba9 100644 --- a/Assets/TextInlineSprite/Scripts/InlineRender/EmojiRenderGroup.cs +++ b/Assets/TextInlineSprite/Scripts/InlineRender/EmojiRenderGroup.cs @@ -6,766 +6,762 @@ namespace EmojiUI { - public class EmojiRenderGroup : IEmojiRender - { + public class EmojiRenderGroup : IEmojiRender + { - private class ListenerData - { - public Vector3 worldpos; + private class ListenerData + { + public Vector3 worldpos; - public Quaternion worldquat; + public Quaternion worldquat; - public Vector3 scale; + public Vector3 scale; - public void Set(InlineText text) - { - if(text != null) - { - Transform trans = text.transform; - this.worldpos = trans.position; - this.worldquat = trans.rotation; - this.scale = trans.localScale; - } - } + public void Set(InlineText text) + { + if (text != null) + { + Transform trans = text.transform; + this.worldpos = trans.position; + this.worldquat = trans.rotation; + this.scale = trans.localScale; + } + } - public bool Dirty(InlineText text) - { - if(text != null) - { - Transform trans = text.transform; - return trans.position != worldpos || trans.rotation != worldquat || trans.localScale != scale; - } - return false; - } - } + public bool Dirty(InlineText text) + { + if (text != null) + { + Transform trans = text.transform; + return trans.position != worldpos || trans.rotation != worldquat || trans.localScale != scale; + } + return false; + } + } - private class CanvasGraphicGroup - { - public Canvas canvas; + private class CanvasGraphicGroup + { + public Canvas canvas; - public int AtlasID; + public int AtlasID; - public SpriteGraphic graphic; + public SpriteGraphic graphic; - public UnitMeshInfo mesh; + public UnitMeshInfo mesh; - public bool isDirty; - } + public bool isDirty; + } - public EmojiRenderType renderType { get { return EmojiRenderType.RenderGroup; } } - - public float Speed { get; set; } + public EmojiRenderType renderType { get { return EmojiRenderType.RenderGroup; } } + + public float Speed { get; set; } - private InlineManager manager; - - private List allatlas; + private InlineManager manager; + + private List allatlas; - private List alltexts; - - /// - /// 因为一般一个canvas下就数个spritegrahphic,用list足够,查询追求不高,同时减少内存占用 - /// - private List GraphicTasks; - - private List rebuildqueue; + private List alltexts; + + /// + /// 因为一般一个canvas下就数个spritegrahphic,用list足够,查询追求不高,同时减少内存占用 + /// + private List GraphicTasks; + + private List rebuildqueue; - private Dictionary listeners; - - private UnitMeshInfo tempMesh; - - private float? _time; - - private static GameObject PoolObj; - - public EmojiRenderGroup(InlineManager target) - { - manager = target; - } - - public List GetAllRenders() - { - return alltexts; - } - - public List GetAllRenderAtlas() - { - return allatlas; - } - - public void Clear() - { - if (alltexts != null) - { - alltexts.Clear(); - } - - if (allatlas != null) - { - allatlas.Clear(); - } - - if (rebuildqueue != null) - { - rebuildqueue.Clear(); - } - - if(GraphicTasks != null) - { - GraphicTasks.Clear(); - } - - if(listeners != null) - { - listeners.Clear(); - } - - } - - public bool isRendingAtlas(SpriteAsset asset) - { - if (allatlas != null) - return allatlas.Contains(asset); - return false; - } - - public void PrepareAtlas(SpriteAsset asset) - { - if (allatlas == null) - { - allatlas = ListPool.Get(); - } - - if (!allatlas.Contains(asset)) - { - allatlas.Add(asset); - } - } - - public bool TryRendering(InlineText text) - { - AddInText(text); - - if (rebuildqueue == null) - { - rebuildqueue = ListPool.Get(); - } - - if (!rebuildqueue.Contains(text)) - { - rebuildqueue.Add(text); - return true; - } - - return false; - } - - public void DisRendering(InlineText text) - { - RemoveInText(text); - - if (rebuildqueue != null && !rebuildqueue.Contains(text)) - { - rebuildqueue.Add(text); - } - - if(listeners != null) - { - listeners.Remove(text); - } - } - - public Texture getRenderTexture(SpriteGraphic graphic) - { - if (graphic != null && GraphicTasks != null) - { - CanvasGraphicGroup group = FindGraphicGroup(graphic); - if(group != null ) - { - UnitMeshInfo info = group.mesh; - if(info != null) - { - return info.getTexture(); - } - } - } - return null; - } - - public void Dispose() - { - if (allatlas != null) - { - ListPool.Release(allatlas); - allatlas = null; - } - - if (alltexts != null) - { - ListPool.Release(alltexts); - alltexts = null; - } - - if (tempMesh != null) - { - UnitMeshInfoPool.Release(tempMesh); - tempMesh = null; - } - - if (GraphicTasks != null) - { - for (int i = 0; i < GraphicTasks.Count;++i) - { - CanvasGraphicGroup group = GraphicTasks[i]; - SpriteGraphic target = group.graphic; - if (target != null) - { - target.Draw(null); - target.SetVerticesDirty(); - } - - if(group.mesh != null) - { - UnitMeshInfoPool.Release(group.mesh); - } - } - - GraphicTasks.Clear(); - GraphicTasks = null; - } - - if (rebuildqueue != null) - { - ListPool.Release(rebuildqueue); - rebuildqueue = null; - } - - - if(listeners != null) - { - listeners.Clear(); - listeners = null; - } - - if (tempMesh != null) - { - UnitMeshInfoPool.Release(tempMesh); - tempMesh = null; - } - - _time = null; - } - - public void Release(Graphic graphic) - { - - if (graphic is SpriteGraphic && PoolObj != null) - { - SpriteGraphic spriteGraphic = graphic as SpriteGraphic; - spriteGraphic.Draw(null); - - if (GraphicTasks != null) - { - for (int i = 0; i < GraphicTasks.Count; ++i) - { - CanvasGraphicGroup group = GraphicTasks[i]; - - if (group != null && UnityEngine.Object.ReferenceEquals(group.graphic,graphic)) - { - GraphicTasks.RemoveAt(i); - break; - } - } - } - } - - } - - - public void LateUpdate() - { - if (Application.isPlaying) - { - MarkDirtyStaticEmoji(); - - RenderRebuild(); - PlayAnimation(); - - } - - } - - void MarkDirtyStaticEmoji() - { - if(alltexts != null && alltexts.Count >0) - { - if (listeners == null) - listeners = new Dictionary(); - - for (int i = 0; i < alltexts.Count; ++i) - { - InlineText text = alltexts[i]; - List emojidata = text.PopEmojiData(); - if (text != null && emojidata != null && emojidata.Count > 0 && allatlas != null && allatlas.Count > 0) - { - bool isdirty = false; - ListenerData data = null; - if (listeners.TryGetValue(text,out data)) - { - isdirty = data.Dirty(text); - if(isdirty) - { - data.Set(text); - } - } - else - { - data = new ListenerData(); - data.Set(text); - - listeners.Add(text, data); - } - - int staticcnt = 0; - for (int j = 0; j < emojidata.Count; ++j) - { - SpriteTagInfo taginfo = emojidata[j]; - SpriteAsset asset = null; - SpriteInfoGroup groupinfo = manager.FindSpriteGroup(taginfo._Tag, out asset); - if (groupinfo != null && groupinfo.spritegroups.Count == 1) - { - staticcnt++; - } - } - - if(staticcnt > 0 && isdirty) - { - this.TryRendering(text); - } - } - } - } - } - - void RenderRebuild() - { - EmojiTools.BeginSample("Emoji_GroupRebuild"); - if (rebuildqueue != null && rebuildqueue.Count > 0) - { - List joblist = ListPool.Get(); - - this.SetAllGroupDirty(false); - - for (int i = 0; i < alltexts.Count; ++i) - { - InlineText text = alltexts[i]; - - List emojidata = text.PopEmojiData(); - if (text != null && emojidata != null && emojidata.Count > 0 && allatlas != null && allatlas.Count > 0) - { - if (tempMesh == null) - tempMesh = UnitMeshInfoPool.Get(); - - for (int j = 0; j < emojidata.Count; ++j) - { - SpriteTagInfo taginfo = emojidata[j]; - Graphic job = Parse(text, taginfo, joblist); - if (job) - { - joblist.Add(taginfo._Tag); - } - - } - } - } - - if (GraphicTasks != null) - { - for (int i = 0; i < GraphicTasks.Count; ++i) - { - CanvasGraphicGroup group = GraphicTasks[i]; - if (group != null && group.graphic != null ) - { - if(group.isDirty) - group.graphic.SetVerticesDirty(); - else - { - group.graphic.Draw(null); - group.graphic.SetVerticesDirty(); - } - } - } - } - - ListPool.Release(joblist); - rebuildqueue.Clear(); - } - EmojiTools.EndSample(); - } - - void PlayAnimation() - { - EmojiTools.BeginSample("Emoji_GroupAnimation"); - if (alltexts != null) - { - if (_time == null) - { - _time = Time.timeSinceLevelLoad; - } - else - { - float deltatime = Time.timeSinceLevelLoad - _time.Value; - - int framecnt = Mathf.RoundToInt(deltatime * Speed); - if (framecnt > 0) - { - List joblist = ListPool.Get(); - for (int i = 0; i < alltexts.Count; ++i) - { - InlineText text = alltexts[i]; - List emojidata = text.PopEmojiData(); - if (emojidata != null && emojidata.Count > 0 && allatlas != null && allatlas.Count > 0) - { - for (int j = 0; j < emojidata.Count; ++j) - { - SpriteTagInfo taginfo = emojidata[j]; - SpriteAsset asset = null; - SpriteInfoGroup groupinfo = manager.FindSpriteGroup(taginfo._Tag, out asset); - if (groupinfo != null && groupinfo.spritegroups.Count > 1) - { - int index = framecnt % groupinfo.spritegroups.Count; - SpriteInfo sprInfo = groupinfo.spritegroups[index]; - taginfo._UV = sprInfo.uv; - - //render next - CanvasGraphicGroup group = FindGraphicGroup(text.canvas, asset.ID); - - if (group != null) - { - if (tempMesh == null) - tempMesh = UnitMeshInfoPool.Get(); - - RefreshSubUIMesh(text, group, asset, taginfo._Pos, taginfo._UV, joblist); - - if(group.isDirty) - { - group.graphic.SetVerticesDirty(); - } - joblist.Add(taginfo._Tag); - } - } - } - } - } - - //reset - - ListPool.Release(joblist); - } - } - } - - EmojiTools.EndSample(); - } - - Graphic Parse(InlineText text, SpriteTagInfo taginfo, List joblist) - { - if (taginfo != null) - { - return ParsePosAndUV(text, taginfo._ID, taginfo._Pos, taginfo._UV, joblist); - } - return null; - } - - Graphic ParsePosAndUV(InlineText text, int ID, Vector3[] Pos, Vector2[] UV, List joblist) - { - EmojiTools.BeginSample("Emoji_GroupParsePosAndUV"); - SpriteAsset matchAsset = null; - for (int i = 0; i < allatlas.Count; ++i) - { - SpriteAsset asset = allatlas[i]; - if (asset != null && asset.ID == ID) - { - matchAsset = asset; - break; - } - } - - if (matchAsset && matchAsset.texSource != null) - { - CanvasGraphicGroup group = FindGraphicGroup(text.canvas, matchAsset.ID); - if(group == null) - { - group = new CanvasGraphicGroup(); - group.AtlasID = matchAsset.ID; - group.canvas = text.canvas; - group.mesh = UnitMeshInfoPool.Get(); - group.isDirty = false; - group.graphic = CreateSpriteRender(); - - if (GraphicTasks == null) - GraphicTasks = new List(); - - GraphicTasks.Add(group); - } - - RefreshSubUIMesh(text, group, matchAsset, Pos, UV, joblist); - - EmojiTools.EndSample(); - return group.graphic; - } - else - { - Debug.LogErrorFormat("missing {0} atlas", ID); - } - EmojiTools.EndSample(); - return null; - } - - void RefreshSubUIMesh(InlineText text, CanvasGraphicGroup group, SpriteAsset matchAsset, Vector3[] Pos, Vector2[] UV, List joblist) - { - // set mesh - tempMesh.SetAtlas(matchAsset); - tempMesh.SetUVLen(UV.Length); - tempMesh.SetVertLen(Pos.Length); - - SpriteGraphic graphic = group.graphic; - //think about culling and screen coordinate....... - for (int i = 0; i < Pos.Length; ++i) - { - //text object pos - Vector3 value = Pos[i]; - Vector3 worldpos = text.transform.TransformPoint(value); - Vector3 localpos = group.graphic.transform.InverseTransformPoint(worldpos); - tempMesh.SetVert(i, localpos); - } - - for (int i = 0; i < UV.Length; ++i) - { - Vector2 value = UV[i]; - tempMesh.SetUV(i, value); - } - - //rendermesh - UnitMeshInfo currentMesh = group.mesh; - - if (!currentMesh.Equals(tempMesh)) - { - if (joblist != null && joblist.Count >0) - { - currentMesh.AddCopy(tempMesh); - tempMesh.Clear(); - } - else - { - currentMesh.Copy(tempMesh); - } - } - - if (currentMesh.VertCnt() > 3 && currentMesh.UVCnt() > 3) - { - graphic.Draw(this); - } - else - { - graphic.Draw(null); - } - - group.isDirty = true; - } - - public void FillMesh(Graphic graphic, VertexHelper vh) - { - CanvasGraphicGroup group = FindGraphicGroup(graphic); - if (group != null) - { - UnitMeshInfo rendermesh = group.mesh; - if (rendermesh != null && rendermesh.getTexture() != null) - { - int vertcnt = rendermesh.VertCnt(); - int uvcnt = rendermesh.UVCnt(); - if (vertcnt != uvcnt) - { - Debug.LogError("data error"); - } - else - { - for (int i = 0; i < vertcnt; ++i) - { - vh.AddVert(rendermesh.GetVert(i), graphic.color, rendermesh.GetUV(i)); - } - - int cnt = vertcnt / 4; - for (int i = 0; i < cnt; ++i) - { - int m = i * 4; - - vh.AddTriangle(m, m + 1, m + 2); - vh.AddTriangle(m + 2, m + 3, m); - } - - //vh.AddTriangle(0, 1, 2); - //vh.AddTriangle(2, 3, 0); - } - } - } - } - - public void DrawGizmos(Graphic graphic) - { - CanvasGraphicGroup group = FindGraphicGroup(graphic); - if (group != null) - { - UnitMeshInfo rendermesh = group.mesh; - if (rendermesh != null && rendermesh.getTexture() != null) - { - Gizmos.color = Color.red; - int vertcnt = rendermesh.VertCnt(); - int uvcnt = rendermesh.UVCnt(); - if (vertcnt != uvcnt) - { - Debug.LogError("data error"); - } - else - { - for (int i = 0; i < vertcnt; i += 4) - { - Vector3 p1 = getPoint(graphic, rendermesh.GetVert(i)); - Vector3 p2 = getPoint(graphic, rendermesh.GetVert(i + 1)); - Vector3 p3 = getPoint(graphic, rendermesh.GetVert(i + 2)); - Vector3 p4 = getPoint(graphic, rendermesh.GetVert(i + 3)); - - Gizmos.DrawLine(p1, p2); - Gizmos.DrawLine(p2, p3); - Gizmos.DrawLine(p3, p4); - Gizmos.DrawLine(p4, p1); - } - } - } - } - - } - - Vector3 getPoint(Graphic graphic, Vector3 v) - { - Vector3 worldpos = graphic.transform.TransformPoint(v); - return worldpos; - } - - #region 考虑到后面测试和调整的时候数据类型的转换 - void SetAllGroupDirty(bool value) - { - if (GraphicTasks != null) - { - for (int i = 0; i < GraphicTasks.Count; ++i) - { - CanvasGraphicGroup group = GraphicTasks[i]; - if (group != null) - { - group.isDirty = value; - } - } - } - } - - CanvasGraphicGroup FindGraphicGroup(Canvas canvas, int atlasId) - { - if (GraphicTasks != null) - { - for (int i = 0; i < GraphicTasks.Count; ++i) - { - CanvasGraphicGroup group = GraphicTasks[i]; - if (group != null && group.canvas == canvas && group.AtlasID == atlasId) - { - return group; - } - } - } - return null; - } - - CanvasGraphicGroup FindGraphicGroup(Graphic graphic) - { - if (GraphicTasks != null) - { - for (int i = 0; i < GraphicTasks.Count; ++i) - { - CanvasGraphicGroup group = GraphicTasks[i]; - if (group != null && group.graphic == graphic) - { - return group; - } - } - } - return null; - } - - void AddInText(InlineText text) - { - if (alltexts == null) - { - alltexts = ListPool.Get(); - } - - if (!alltexts.Contains(text)) - { - alltexts.Add(text); - } - } - - void RemoveInText(InlineText text) - { - if (alltexts != null) - { - alltexts.Remove(text); - } - } - - #endregion - - SpriteGraphic CreateSpriteRender() - { - if (PoolObj == null) - { - PoolObj = new GameObject("GroupRenderPool"); - SpriteGraphic target = null; - for (int i = 0; i < 4; i++) - { - target = CreateInstance(PoolObj.transform); - } - - target.transform.SetParent(manager.transform); - return target; - } - else - { - int childcnt = PoolObj.transform.childCount; - if (childcnt > 0) - { - Transform trans = PoolObj.transform.GetChild(0); - trans.SetParent(manager.transform); - return trans.GetComponent(); - } - - return CreateInstance(manager.transform); - } - } - - SpriteGraphic CreateInstance(Transform targetTrans) - { - GameObject newobject = new GameObject("pre_Sprite"); - newobject.transform.SetParent(targetTrans); - newobject.transform.localPosition = Vector3.zero; - newobject.transform.localScale = Vector3.one; - newobject.transform.localRotation = Quaternion.identity; - newobject.transform.gameObject.layer = targetTrans.gameObject.layer; - newobject.transform.tag = targetTrans.gameObject.tag; - //newobject.transform.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector; - - SpriteGraphic spritegrahic = newobject.AddComponent(); - spritegrahic.raycastTarget = false; - return spritegrahic; - } - } + private Dictionary listeners; + + private UnitMeshInfo tempMesh; + + private float? _time; + + private static GameObject PoolObj; + + public EmojiRenderGroup(InlineManager target) + { + manager = target; + } + + public List GetAllRenders() + { + return alltexts; + } + + public List GetAllRenderAtlas() + { + return allatlas; + } + + public void Clear() + { + if (alltexts != null) + { + alltexts.Clear(); + } + + if (allatlas != null) + { + allatlas.Clear(); + } + + if (rebuildqueue != null) + { + rebuildqueue.Clear(); + } + + if (GraphicTasks != null) + { + GraphicTasks.Clear(); + } + + if (listeners != null) + { + listeners.Clear(); + } + + } + + public bool isRendingAtlas(SpriteAsset asset) + { + if (allatlas != null) + return allatlas.Contains(asset); + return false; + } + + public void PrepareAtlas(SpriteAsset asset) + { + if (allatlas == null) + { + allatlas = ListPool.Get(); + } + + if (!allatlas.Contains(asset)) + { + allatlas.Add(asset); + } + } + + public bool TryRendering(InlineText text) + { + AddInText(text); + + if (rebuildqueue == null) + { + rebuildqueue = ListPool.Get(); + } + + if (!rebuildqueue.Contains(text)) + { + rebuildqueue.Add(text); + return true; + } + + return false; + } + + public void DisRendering(InlineText text) + { + RemoveInText(text); + + if (rebuildqueue != null && !rebuildqueue.Contains(text)) + { + rebuildqueue.Add(text); + } + + if (listeners != null) + { + listeners.Remove(text); + } + } + + public Texture getRenderTexture(SpriteGraphic graphic) + { + if (graphic != null && GraphicTasks != null) + { + CanvasGraphicGroup group = FindGraphicGroup(graphic); + if (group != null) + { + UnitMeshInfo info = group.mesh; + if (info != null) + { + return info.getTexture(); + } + } + } + return null; + } + + public void Dispose() + { + if (allatlas != null) + { + ListPool.Release(allatlas); + allatlas = null; + } + + if (alltexts != null) + { + ListPool.Release(alltexts); + alltexts = null; + } + + if (tempMesh != null) + { + UnitMeshInfoPool.Release(tempMesh); + tempMesh = null; + } + + if (GraphicTasks != null) + { + for (int i = 0; i < GraphicTasks.Count; ++i) + { + CanvasGraphicGroup group = GraphicTasks[i]; + SpriteGraphic target = group.graphic; + if (target != null) + { + target.Draw(null); + target.SetVerticesDirty(); + } + + if (group.mesh != null) + { + UnitMeshInfoPool.Release(group.mesh); + } + } + + GraphicTasks.Clear(); + GraphicTasks = null; + } + + if (rebuildqueue != null) + { + ListPool.Release(rebuildqueue); + rebuildqueue = null; + } + + + if (listeners != null) + { + listeners.Clear(); + listeners = null; + } + + if (tempMesh != null) + { + UnitMeshInfoPool.Release(tempMesh); + tempMesh = null; + } + + _time = null; + } + + public void Release(Graphic graphic) + { + + if (graphic is SpriteGraphic && PoolObj != null) + { + SpriteGraphic spriteGraphic = graphic as SpriteGraphic; + spriteGraphic.Draw(null); + + if (GraphicTasks != null) + { + for (int i = 0; i < GraphicTasks.Count; ++i) + { + CanvasGraphicGroup group = GraphicTasks[i]; + + if (group != null && UnityEngine.Object.ReferenceEquals(group.graphic, graphic)) + { + GraphicTasks.RemoveAt(i); + break; + } + } + } + } + + } + + + public void LateUpdate() + { + if (Application.isPlaying) + { + MarkDirtyStaticEmoji(); + + RenderRebuild(); + PlayAnimation(); + + } + + } + + void MarkDirtyStaticEmoji() + { + if (alltexts != null && alltexts.Count > 0) + { + if (listeners == null) + listeners = new Dictionary(); + + for (int i = 0; i < alltexts.Count; ++i) + { + InlineText text = alltexts[i]; + List emojidata = text.PopEmojiData(); + if (text != null && emojidata != null && emojidata.Count > 0 && allatlas != null && allatlas.Count > 0) + { + bool isdirty = false; + ListenerData data = null; + if (listeners.TryGetValue(text, out data)) + { + isdirty = data.Dirty(text); + if (isdirty) + { + data.Set(text); + } + } + else + { + data = new ListenerData(); + data.Set(text); + + listeners.Add(text, data); + } + + int staticcnt = 0; + for (int j = 0; j < emojidata.Count; ++j) + { + IFillData taginfo = emojidata[j]; + SpriteAsset asset = null; + SpriteInfoGroup groupinfo = manager.FindSpriteGroup(taginfo.Tag, out asset); + if (groupinfo != null && groupinfo.spritegroups.Count == 1) + { + staticcnt++; + } + } + + if (staticcnt > 0 && isdirty) + { + this.TryRendering(text); + } + } + } + } + } + + void RenderRebuild() + { + EmojiTools.BeginSample("Emoji_GroupRebuild"); + if (rebuildqueue != null && rebuildqueue.Count > 0) + { + List joblist = ListPool.Get(); + + this.SetAllGroupDirty(false); + + for (int i = 0; i < alltexts.Count; ++i) + { + InlineText text = alltexts[i]; + + List emojidata = text.PopEmojiData(); + if (text != null && emojidata != null && emojidata.Count > 0 && allatlas != null && allatlas.Count > 0) + { + if (tempMesh == null) + tempMesh = UnitMeshInfoPool.Get(); + + for (int j = 0; j < emojidata.Count; ++j) + { + IFillData taginfo = emojidata[j]; + Graphic job = Parse(text, taginfo, joblist); + if (job) + { + joblist.Add(taginfo.Tag); + } + } + } + } + + if (GraphicTasks != null) + { + for (int i = 0; i < GraphicTasks.Count; ++i) + { + CanvasGraphicGroup group = GraphicTasks[i]; + if (group != null && group.graphic != null) + { + if (group.isDirty) + group.graphic.SetVerticesDirty(); + else + { + group.graphic.Draw(null); + group.graphic.SetVerticesDirty(); + } + } + } + } + + ListPool.Release(joblist); + rebuildqueue.Clear(); + } + EmojiTools.EndSample(); + } + + void PlayAnimation() + { + EmojiTools.BeginSample("Emoji_GroupAnimation"); + if (alltexts != null) + { + if (_time == null) + { + _time = Time.timeSinceLevelLoad; + } + else + { + float deltatime = Time.timeSinceLevelLoad - _time.Value; + + int framecnt = Mathf.RoundToInt(deltatime * Speed); + if (framecnt > 0) + { + List joblist = ListPool.Get(); + for (int i = 0; i < alltexts.Count; ++i) + { + InlineText text = alltexts[i]; + List emojidata = text.PopEmojiData(); + if (emojidata != null && emojidata.Count > 0 && allatlas != null && allatlas.Count > 0) + { + for (int j = 0; j < emojidata.Count; ++j) + { + IFillData taginfo = emojidata[j]; + SpriteAsset asset = null; + SpriteInfoGroup groupinfo = manager.FindSpriteGroup(taginfo.Tag, out asset); + if (groupinfo != null && groupinfo.spritegroups.Count > 1) + { + int index = framecnt % groupinfo.spritegroups.Count; + SpriteInfo sprInfo = groupinfo.spritegroups[index]; + taginfo.uv = sprInfo.uv; + + //render next + CanvasGraphicGroup group = FindGraphicGroup(text.canvas, asset.ID); + + if (group != null) + { + if (tempMesh == null) + tempMesh = UnitMeshInfoPool.Get(); + + RefreshSubUIMesh(text, group, asset, taginfo.pos, taginfo.uv, joblist); + + if (group.isDirty) + { + group.graphic.SetVerticesDirty(); + } + joblist.Add(taginfo.Tag); + } + } + } + } + } + ListPool.Release(joblist); + } + } + } + + EmojiTools.EndSample(); + } + + Graphic Parse(InlineText text, IFillData taginfo, List joblist) + { + if (taginfo != null) + { + return ParsePosAndUV(text, taginfo.ID, taginfo.pos, taginfo.uv, joblist); + } + return null; + } + + Graphic ParsePosAndUV(InlineText text, int ID, Vector3[] Pos, Vector2[] UV, List joblist) + { + EmojiTools.BeginSample("Emoji_GroupParsePosAndUV"); + SpriteAsset matchAsset = null; + for (int i = 0; i < allatlas.Count; ++i) + { + SpriteAsset asset = allatlas[i]; + if (asset != null && asset.ID == ID) + { + matchAsset = asset; + break; + } + } + + if (matchAsset && matchAsset.texSource != null) + { + CanvasGraphicGroup group = FindGraphicGroup(text.canvas, matchAsset.ID); + if (group == null) + { + group = new CanvasGraphicGroup(); + group.AtlasID = matchAsset.ID; + group.canvas = text.canvas; + group.mesh = UnitMeshInfoPool.Get(); + group.isDirty = false; + group.graphic = CreateSpriteRender(); + + if (GraphicTasks == null) + GraphicTasks = new List(); + + GraphicTasks.Add(group); + } + + RefreshSubUIMesh(text, group, matchAsset, Pos, UV, joblist); + + EmojiTools.EndSample(); + return group.graphic; + } + else + { + Debug.LogErrorFormat("missing {0} atlas", ID); + } + EmojiTools.EndSample(); + return null; + } + + void RefreshSubUIMesh(InlineText text, CanvasGraphicGroup group, SpriteAsset matchAsset, Vector3[] Pos, Vector2[] UV, List joblist) + { + // set mesh + tempMesh.SetAtlas(matchAsset); + tempMesh.SetUVLen(UV.Length); + tempMesh.SetVertLen(Pos.Length); + + SpriteGraphic graphic = group.graphic; + //think about culling and screen coordinate....... + for (int i = 0; i < Pos.Length; ++i) + { + //text object pos + Vector3 value = Pos[i]; + Vector3 worldpos = text.transform.TransformPoint(value); + Vector3 localpos = group.graphic.transform.InverseTransformPoint(worldpos); + tempMesh.SetVert(i, localpos); + } + + for (int i = 0; i < UV.Length; ++i) + { + Vector2 value = UV[i]; + tempMesh.SetUV(i, value); + } + + //rendermesh + UnitMeshInfo currentMesh = group.mesh; + + if (!currentMesh.Equals(tempMesh)) + { + if (joblist != null && joblist.Count > 0) + { + currentMesh.AddCopy(tempMesh); + tempMesh.Clear(); + } + else + { + currentMesh.Copy(tempMesh); + } + } + + if (currentMesh.VertCnt() > 3 && currentMesh.UVCnt() > 3) + { + graphic.Draw(this); + } + else + { + graphic.Draw(null); + } + + group.isDirty = true; + } + + public void FillMesh(Graphic graphic, VertexHelper vh) + { + CanvasGraphicGroup group = FindGraphicGroup(graphic); + if (group != null) + { + UnitMeshInfo rendermesh = group.mesh; + if (rendermesh != null && rendermesh.getTexture() != null) + { + int vertcnt = rendermesh.VertCnt(); + int uvcnt = rendermesh.UVCnt(); + if (vertcnt != uvcnt) + { + Debug.LogError("data error"); + } + else + { + for (int i = 0; i < vertcnt; ++i) + { + vh.AddVert(rendermesh.GetVert(i), graphic.color, rendermesh.GetUV(i)); + } + + int cnt = vertcnt / 4; + for (int i = 0; i < cnt; ++i) + { + int m = i * 4; + + vh.AddTriangle(m, m + 1, m + 2); + vh.AddTriangle(m + 2, m + 3, m); + } + + //vh.AddTriangle(0, 1, 2); + //vh.AddTriangle(2, 3, 0); + } + } + } + } + + public void DrawGizmos(Graphic graphic) + { + CanvasGraphicGroup group = FindGraphicGroup(graphic); + if (group != null) + { + UnitMeshInfo rendermesh = group.mesh; + if (rendermesh != null && rendermesh.getTexture() != null) + { + Gizmos.color = Color.red; + int vertcnt = rendermesh.VertCnt(); + int uvcnt = rendermesh.UVCnt(); + if (vertcnt != uvcnt) + { + Debug.LogError("data error"); + } + else + { + for (int i = 0; i < vertcnt; i += 4) + { + Vector3 p1 = getPoint(graphic, rendermesh.GetVert(i)); + Vector3 p2 = getPoint(graphic, rendermesh.GetVert(i + 1)); + Vector3 p3 = getPoint(graphic, rendermesh.GetVert(i + 2)); + Vector3 p4 = getPoint(graphic, rendermesh.GetVert(i + 3)); + + Gizmos.DrawLine(p1, p2); + Gizmos.DrawLine(p2, p3); + Gizmos.DrawLine(p3, p4); + Gizmos.DrawLine(p4, p1); + } + } + } + } + + } + + Vector3 getPoint(Graphic graphic, Vector3 v) + { + Vector3 worldpos = graphic.transform.TransformPoint(v); + return worldpos; + } + + #region 考虑到后面测试和调整的时候数据类型的转换 + void SetAllGroupDirty(bool value) + { + if (GraphicTasks != null) + { + for (int i = 0; i < GraphicTasks.Count; ++i) + { + CanvasGraphicGroup group = GraphicTasks[i]; + if (group != null) + { + group.isDirty = value; + } + } + } + } + + CanvasGraphicGroup FindGraphicGroup(Canvas canvas, int atlasId) + { + if (GraphicTasks != null) + { + for (int i = 0; i < GraphicTasks.Count; ++i) + { + CanvasGraphicGroup group = GraphicTasks[i]; + if (group != null && group.canvas == canvas && group.AtlasID == atlasId) + { + return group; + } + } + } + return null; + } + + CanvasGraphicGroup FindGraphicGroup(Graphic graphic) + { + if (GraphicTasks != null) + { + for (int i = 0; i < GraphicTasks.Count; ++i) + { + CanvasGraphicGroup group = GraphicTasks[i]; + if (group != null && group.graphic == graphic) + { + return group; + } + } + } + return null; + } + + void AddInText(InlineText text) + { + if (alltexts == null) + { + alltexts = ListPool.Get(); + } + + if (!alltexts.Contains(text)) + { + alltexts.Add(text); + } + } + + void RemoveInText(InlineText text) + { + if (alltexts != null) + { + alltexts.Remove(text); + } + } + + #endregion + + SpriteGraphic CreateSpriteRender() + { + if (PoolObj == null) + { + PoolObj = new GameObject("GroupRenderPool"); + SpriteGraphic target = null; + for (int i = 0; i < 4; i++) + { + target = CreateInstance(PoolObj.transform); + } + + target.transform.SetParent(manager.transform); + return target; + } + else + { + int childcnt = PoolObj.transform.childCount; + if (childcnt > 0) + { + Transform trans = PoolObj.transform.GetChild(0); + trans.SetParent(manager.transform); + return trans.GetComponent(); + } + + return CreateInstance(manager.transform); + } + } + + SpriteGraphic CreateInstance(Transform targetTrans) + { + GameObject newobject = new GameObject("pre_Sprite"); + newobject.transform.SetParent(targetTrans); + newobject.transform.localPosition = Vector3.zero; + newobject.transform.localScale = Vector3.one; + newobject.transform.localRotation = Quaternion.identity; + newobject.transform.gameObject.layer = targetTrans.gameObject.layer; + newobject.transform.tag = targetTrans.gameObject.tag; + //newobject.transform.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector; + + SpriteGraphic spritegrahic = newobject.AddComponent(); + spritegrahic.raycastTarget = false; + return spritegrahic; + } + } } diff --git a/Assets/TextInlineSprite/Scripts/InlineRender/IEmojiRender.cs b/Assets/TextInlineSprite/Scripts/InlineRender/IEmojiRender.cs index 7d87294..f1716d2 100644 --- a/Assets/TextInlineSprite/Scripts/InlineRender/IEmojiRender.cs +++ b/Assets/TextInlineSprite/Scripts/InlineRender/IEmojiRender.cs @@ -5,45 +5,45 @@ namespace EmojiUI { - public enum EmojiRenderType - { - RenderGroup, - RenderUnit, - RenderBoth, - } - - public interface IEmojiRender - { - EmojiRenderType renderType { get; } - - float Speed { get; set; } - - List GetAllRenders(); - - List GetAllRenderAtlas(); + public enum EmojiRenderType + { + RenderGroup, + RenderUnit, + RenderBoth, + } - Texture getRenderTexture(SpriteGraphic graphic); + public interface IEmojiRender + { + EmojiRenderType renderType { get; } - bool isRendingAtlas(SpriteAsset asset); + float Speed { get; set; } - void PrepareAtlas(SpriteAsset asset); + List GetAllRenders(); - bool TryRendering(InlineText text); + List GetAllRenderAtlas(); - void DisRendering(InlineText text); + Texture getRenderTexture(SpriteGraphic graphic); - void Clear(); + bool isRendingAtlas(SpriteAsset asset); - void Release(Graphic graphic); + void PrepareAtlas(SpriteAsset asset); - void FillMesh(Graphic graphic, VertexHelper vh); + bool TryRendering(InlineText text); - void LateUpdate(); + void DisRendering(InlineText text); - void DrawGizmos(Graphic graphic); - - void Dispose(); - } + void Clear(); + + void Release(Graphic graphic); + + void FillMesh(Graphic graphic, VertexHelper vh); + + void LateUpdate(); + + void DrawGizmos(Graphic graphic); + + void Dispose(); + } } diff --git a/Assets/TextInlineSprite/Scripts/InlineRender/UnitRender.cs b/Assets/TextInlineSprite/Scripts/InlineRender/UnitRender.cs index 6988b6a..82746d1 100644 --- a/Assets/TextInlineSprite/Scripts/InlineRender/UnitRender.cs +++ b/Assets/TextInlineSprite/Scripts/InlineRender/UnitRender.cs @@ -6,664 +6,663 @@ namespace EmojiUI { - public class UnitRender : IEmojiRender - { - public EmojiRenderType renderType { get { return EmojiRenderType.RenderUnit; } } - - public float Speed { get; set; } + public class UnitRender : IEmojiRender + { + public EmojiRenderType renderType { get { return EmojiRenderType.RenderUnit; } } - private InlineManager manager; - - private List allatlas; - - private List alltexts; - - private Dictionary> textGraphics; - - private Dictionary renderData; - - private List rebuildqueue; - - private UnitMeshInfo tempMesh; - - private float? _time; - - private static GameObject PoolObj; - - public UnitRender(InlineManager target) - { - manager = target; - } - - public List GetAllRenders() - { - return alltexts; - } - - public List GetAllRenderAtlas() - { - return allatlas; - } - - public void Clear() - { - if(alltexts != null) - { - alltexts.Clear(); - } - - if(renderData != null) - { - renderData.Clear(); - } - - if(allatlas != null) - { - allatlas.Clear(); - } - - if(rebuildqueue != null) - { - rebuildqueue.Clear(); - } - - } - - public bool isRendingAtlas(SpriteAsset asset) - { - if (allatlas != null) - return allatlas.Contains(asset); - return false; - } - - public void PrepareAtlas(SpriteAsset asset) - { - if(allatlas == null) - { - allatlas = ListPool.Get(); - } - - if(!allatlas.Contains(asset)) - { - allatlas.Add(asset); - } - } - - public bool TryRendering(InlineText text) - { - AddInText(text); - - if(rebuildqueue == null) - { - rebuildqueue = ListPool.Get(); - } - - if(!rebuildqueue.Contains(text)) - { - rebuildqueue.Add(text); - return true; - } - - return false; - } - - public void DisRendering(InlineText text) - { - RemoveInText(text); - - if (rebuildqueue != null && !rebuildqueue.Contains(text)) - { - rebuildqueue.Add(text); - } - } - - public Texture getRenderTexture(SpriteGraphic graphic) - { - if(graphic != null && renderData != null) - { - UnitMeshInfo info; - if(renderData.TryGetValue(graphic,out info)) - { - return info.getTexture(); - } - } - return null; - } - - public void Dispose() - { - if (allatlas != null) - { - ListPool.Release(allatlas); - allatlas = null; - } - - if (alltexts != null) - { - ListPool.Release(alltexts); - alltexts = null; - } - - if (tempMesh != null) - { - UnitMeshInfoPool.Release(tempMesh); - tempMesh = null; - } - - if (textGraphics != null) - { - var en = textGraphics.GetEnumerator(); - while (en.MoveNext()) - { - var list = en.Current.Value; - for (int i = 0; i < list.Count;++i) - { - var target = list[i]; - if(target != null) - { - target.Draw(null); - target.SetVerticesDirty(); - } - } - - ListPool.Release(en.Current.Value); - } - textGraphics = null; - } - - if (rebuildqueue != null) - { - ListPool.Release(rebuildqueue); - rebuildqueue = null; - } - - if (renderData != null) - { - renderData.Clear(); - renderData = null; - } - - if(tempMesh != null) - { - UnitMeshInfoPool.Release(tempMesh); - tempMesh = null; - } - - _time = null; - } - - public void Release(Graphic graphic) - { - - if (graphic is SpriteGraphic ) - { - SpriteGraphic spriteGraphic = graphic as SpriteGraphic; - if (renderData != null) - renderData.Remove(spriteGraphic); - - if(textGraphics != null) - { - var en = textGraphics.GetEnumerator(); - while(en.MoveNext()) - { - var list = en.Current.Value; - for (int i = list.Count - 1; i >= 0; --i) - { - var target = list[i]; - - if(UnityEngine.Object.ReferenceEquals(target,graphic)) - { - list.RemoveAt(i); - break; - } - } - } - } - } - - } - - - public void LateUpdate() - { - if(Application.isPlaying) - { - RenderRebuild(); - PlayAnimation(); - } - - } - - void RenderRebuild() - { - EmojiTools.BeginSample("Emoji_UnitRebuild"); - if(rebuildqueue != null && rebuildqueue.Count >0) - { - for(int i =0; i < rebuildqueue.Count;++i) - { - InlineText text = rebuildqueue[i]; - List emojidata = text.PopEmojiData(); - if(emojidata != null && emojidata.Count >0 && allatlas!= null && allatlas.Count >0) - { - if (tempMesh == null) - tempMesh = UnitMeshInfoPool.Get(); - - if (renderData == null) - renderData = new Dictionary(emojidata.Count); - - List joblist = ListPool.Get(); - - for(int j =0; j < emojidata.Count;++j) - { - SpriteTagInfo taginfo = emojidata[j]; - SpriteGraphic job = Parse(text,taginfo,joblist); - if (job) - joblist.Add(job); - } - - List list; - if (textGraphics != null && textGraphics.TryGetValue(text, out list)) - { - for (int j = 0; j < list.Count; ++j) - { - SpriteGraphic graphic = list[j]; - //not render - if (graphic != null && !joblist.Contains(graphic)) - { - graphic.Draw(null); - graphic.SetVerticesDirty(); - } - } - } - - ListPool.Release(joblist); - - } - else - { - List list; - if (textGraphics != null && textGraphics.TryGetValue(text, out list)) - { - for (int j = 0; j < list.Count; ++j) - { - SpriteGraphic graphic = list[j]; - //not render - if (graphic != null ) - { - graphic.Draw(null); - graphic.SetVerticesDirty(); - } - } - } - } - } - - rebuildqueue.Clear(); - } - EmojiTools.EndSample(); - } - - void PlayAnimation() - { - EmojiTools.BeginSample("Emoji_UnitAnimation"); - if (alltexts != null) - { - if (_time == null) - { - _time = Time.timeSinceLevelLoad; - } - else - { - float deltatime = Time.timeSinceLevelLoad - _time.Value; - //at least one frame - int framecnt = Mathf.RoundToInt(deltatime * Speed); - if (framecnt > 0) - { - for (int i = 0; i < alltexts.Count; ++i) - { - InlineText text = alltexts[i]; - List emojidata = text.PopEmojiData(); - if (emojidata != null && emojidata.Count > 0 && allatlas != null && allatlas.Count > 0) - { - List joblist = ListPool.Get(); - for (int j = 0; j < emojidata.Count; ++j) - { - SpriteTagInfo taginfo = emojidata[j]; - SpriteAsset asset = null; - SpriteInfoGroup groupinfo = manager.FindSpriteGroup(taginfo._Tag, out asset); - if (groupinfo != null && groupinfo.spritegroups.Count > 1) - { - int index = framecnt % groupinfo.spritegroups.Count; - SpriteInfo sprInfo = groupinfo.spritegroups[index]; - taginfo._UV = sprInfo.uv; - - List list = null; - SpriteGraphic target = FindGraphic(text, asset,out list); - if (target) - { - if (tempMesh == null) - tempMesh = UnitMeshInfoPool.Get(); - - if (renderData == null) - renderData = new Dictionary(emojidata.Count); - - RefreshSubUIMesh(text, target, asset, taginfo._Pos, taginfo._UV, joblist); - joblist.Add(target); - } - } - } - - ListPool.Release(joblist); - } - } - } - } - } - - EmojiTools.EndSample(); - } - - SpriteGraphic Parse(InlineText text, SpriteTagInfo taginfo, List joblist) - { - if (taginfo != null) - { - return ParsePosAndUV(text, taginfo._ID, taginfo._Pos, taginfo._UV, joblist); - } - return null; - } - - SpriteGraphic ParsePosAndUV(InlineText text,int ID, Vector3[] Pos,Vector2[] UV, List joblist) - { - EmojiTools.BeginSample("Emoji_UnitParsePosAndUV"); - SpriteAsset matchAsset = null; - for (int i = 0; i < allatlas.Count; ++i) - { - SpriteAsset asset = allatlas[i]; - if (asset != null && asset.ID == ID) - { - matchAsset = asset; - break; - } - } - - if (matchAsset && matchAsset.texSource != null) - { - List list = null; - SpriteGraphic target = FindGraphic(text, matchAsset, out list); - if (!target) - { - target = CreateSpriteRender(text.transform); - list.Add(target); - } - - RefreshSubUIMesh(text, target, matchAsset, Pos, UV, joblist); - - EmojiTools.EndSample(); - return target; - } - else - { - Debug.LogErrorFormat("missing {0} atlas", ID); - } - EmojiTools.EndSample(); - return null; - } - - void RefreshSubUIMesh(InlineText text,SpriteGraphic target, SpriteAsset matchAsset,Vector3[] Pos, Vector2[] UV, List joblist) - { - // set mesh - tempMesh.SetAtlas(matchAsset); - tempMesh.SetUVLen(UV.Length); - tempMesh.SetVertLen(Pos.Length); - - for (int i = 0; i < Pos.Length; ++i) - { - //text object pos - Vector3 value = Pos[i]; - Vector3 worldpos = text.transform.TransformPoint(value); - Vector3 localpos = target.transform.InverseTransformPoint(worldpos); - tempMesh.SetVert(i, localpos); - } - - for (int i = 0; i < UV.Length; ++i) - { - Vector2 value = UV[i]; - tempMesh.SetUV(i, value); - } - - //rendermesh - UnitMeshInfo currentMesh = null; - if (!this.renderData.TryGetValue(target, out currentMesh)) - { - currentMesh = new UnitMeshInfo(); - renderData[target] = currentMesh; - } - - if (!currentMesh.Equals(tempMesh)) - { - if (joblist != null && joblist.Contains(target)) - { - currentMesh.AddCopy(tempMesh); - tempMesh.Clear(); - } - else - { - currentMesh.Copy(tempMesh); - } - } - - if (currentMesh.VertCnt() > 3 && currentMesh.UVCnt() > 3) - { - target.Draw(this); - target.SetVerticesDirty(); - } - else - { - target.Draw(null); - target.SetVerticesDirty(); - } - } - - public void FillMesh(Graphic graphic, VertexHelper vh) - { - UnitMeshInfo rendermesh; - if(renderData != null && renderData.Count >0 && renderData.TryGetValue(graphic ,out rendermesh)) - { - if(rendermesh != null && rendermesh.getTexture() != null) - { - int vertcnt = rendermesh.VertCnt(); - int uvcnt = rendermesh.UVCnt(); - if(vertcnt !=uvcnt) - { - Debug.LogError("data error"); - } - else - { - for (int i = 0; i < vertcnt; ++i) - { - vh.AddVert(rendermesh.GetVert(i), graphic.color, rendermesh.GetUV(i)); - } - - int cnt = vertcnt / 4; - for (int i = 0; i < cnt; ++i) - { - int m = i* 4; - - vh.AddTriangle(m, m + 1, m + 2); - vh.AddTriangle(m + 2, m + 3, m); - } - - //vh.AddTriangle(0, 1, 2); - //vh.AddTriangle(2, 3, 0); - } - } - } - } - - public void DrawGizmos(Graphic graphic) - { - UnitMeshInfo rendermesh; - if (renderData != null && renderData.Count > 0 && renderData.TryGetValue(graphic, out rendermesh)) - { - if (rendermesh != null && rendermesh.getTexture() != null) - { - Gizmos.color = Color.red; - int vertcnt = rendermesh.VertCnt(); - int uvcnt = rendermesh.UVCnt(); - if (vertcnt != uvcnt) - { - Debug.LogError("data error"); - } - else - { - for (int i = 0; i < vertcnt; i += 4) - { - Vector3 p1 = getPoint(graphic, rendermesh.GetVert(i)); - Vector3 p2 = getPoint(graphic, rendermesh.GetVert(i+1)); - Vector3 p3 = getPoint(graphic, rendermesh.GetVert(i+2)); - Vector3 p4 = getPoint(graphic, rendermesh.GetVert(i+3)); - - Gizmos.DrawLine(p1, p2); - Gizmos.DrawLine(p2, p3); - Gizmos.DrawLine(p3, p4); - Gizmos.DrawLine(p4, p1); - } - } - } - } - - } - - Vector3 getPoint(Graphic graphic, Vector3 v) - { - Vector3 worldpos = graphic.transform.TransformPoint(v); - return worldpos; - } - - #region 考虑到后面测试和调整的时候数据类型的转换 - - SpriteGraphic FindGraphic(InlineText text, int atlasID,out SpriteAsset matchAsset ) - { - matchAsset = null; - for (int i = 0; i < allatlas.Count; ++i) - { - SpriteAsset asset = allatlas[i]; - if (asset != null && asset.ID == atlasID) - { - matchAsset = asset; - break; - } - } - - if (matchAsset && matchAsset.texSource != null) - { - List list = null; - SpriteGraphic target = FindGraphic(text, matchAsset, out list); - if (!target) - { - target = CreateSpriteRender(text.transform); - list.Add(target); - } - return target; - } - return null; - } - - - SpriteGraphic FindGraphic(InlineText text, SpriteAsset matchAsset,out List list) - { - EmojiTools.BeginSample("Emoji_UnitFindGraphic"); - if (textGraphics == null) - textGraphics = new Dictionary>(); - - if (!textGraphics.TryGetValue(text, out list)) - { - list = ListPool.Get(); - textGraphics[text] = list; - } - - SpriteGraphic target = null; - for (int i = 0; i < list.Count; ++i) - { - SpriteGraphic graphic = list[i]; - if (graphic && UnityEngine.Object.ReferenceEquals(graphic.mainTexture, matchAsset.texSource)) - { - target = graphic; - break; - } - } - EmojiTools.EndSample(); - return target; - } - - void AddInText(InlineText text) - { - if (alltexts == null) - { - alltexts = ListPool.Get(); - } - - if (!alltexts.Contains(text)) - { - alltexts.Add(text); - } - } - - void RemoveInText(InlineText text) - { - if (alltexts != null) - { - alltexts.Remove(text); - } - } - - #endregion - - SpriteGraphic CreateSpriteRender(Transform targetTrans) - { - if(PoolObj == null) - { - PoolObj = new GameObject("UnitRenderPool"); - SpriteGraphic target = null; - for (int i =0; i < 10;i ++) - { - target = CreateInstance(PoolObj.transform); - } - - target.transform.SetParent(targetTrans); - return target; - } - else - { - int childcnt = PoolObj.transform.childCount; - if(childcnt >0) - { - Transform trans = PoolObj.transform.GetChild(0); - trans.SetParent(targetTrans); - return trans.GetComponent(); - } - - return CreateInstance(targetTrans); - } - } - - SpriteGraphic CreateInstance(Transform targetTrans) - { - GameObject newobject = new GameObject("pre_Sprite"); - newobject.transform.SetParent(targetTrans); - newobject.transform.localPosition = Vector3.zero; - newobject.transform.localScale = Vector3.one; - newobject.transform.localRotation = Quaternion.identity; - newobject.transform.gameObject.layer = targetTrans.gameObject.layer; - newobject.transform.tag = targetTrans.gameObject.tag; - //newobject.transform.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector; - - SpriteGraphic spritegrahic = newobject.AddComponent(); - spritegrahic.raycastTarget = false; - return spritegrahic; - } - - } + public float Speed { get; set; } + + private InlineManager manager; + + private List allatlas; + + private List alltexts; + + private Dictionary> textGraphics; + + private Dictionary renderData; + + private List rebuildqueue; + + private UnitMeshInfo tempMesh; + + private float? _time; + + private static GameObject PoolObj; + + public UnitRender(InlineManager target) + { + manager = target; + } + + public List GetAllRenders() + { + return alltexts; + } + + public List GetAllRenderAtlas() + { + return allatlas; + } + + public void Clear() + { + if (alltexts != null) + { + alltexts.Clear(); + } + + if (renderData != null) + { + renderData.Clear(); + } + + if (allatlas != null) + { + allatlas.Clear(); + } + + if (rebuildqueue != null) + { + rebuildqueue.Clear(); + } + + } + + public bool isRendingAtlas(SpriteAsset asset) + { + if (allatlas != null) + return allatlas.Contains(asset); + return false; + } + + public void PrepareAtlas(SpriteAsset asset) + { + if (allatlas == null) + { + allatlas = ListPool.Get(); + } + + if (!allatlas.Contains(asset)) + { + allatlas.Add(asset); + } + } + + public bool TryRendering(InlineText text) + { + AddInText(text); + + if (rebuildqueue == null) + { + rebuildqueue = ListPool.Get(); + } + + if (!rebuildqueue.Contains(text)) + { + rebuildqueue.Add(text); + return true; + } + + return false; + } + + public void DisRendering(InlineText text) + { + RemoveInText(text); + + if (rebuildqueue != null && !rebuildqueue.Contains(text)) + { + rebuildqueue.Add(text); + } + } + + public Texture getRenderTexture(SpriteGraphic graphic) + { + if (graphic != null && renderData != null) + { + UnitMeshInfo info; + if (renderData.TryGetValue(graphic, out info)) + { + return info.getTexture(); + } + } + return null; + } + + public void Dispose() + { + if (allatlas != null) + { + ListPool.Release(allatlas); + allatlas = null; + } + + if (alltexts != null) + { + ListPool.Release(alltexts); + alltexts = null; + } + + if (tempMesh != null) + { + UnitMeshInfoPool.Release(tempMesh); + tempMesh = null; + } + + if (textGraphics != null) + { + var en = textGraphics.GetEnumerator(); + while (en.MoveNext()) + { + var list = en.Current.Value; + for (int i = 0; i < list.Count; ++i) + { + var target = list[i]; + if (target != null) + { + target.Draw(null); + target.SetVerticesDirty(); + } + } + + ListPool.Release(en.Current.Value); + } + textGraphics = null; + } + + if (rebuildqueue != null) + { + ListPool.Release(rebuildqueue); + rebuildqueue = null; + } + + if (renderData != null) + { + renderData.Clear(); + renderData = null; + } + + if (tempMesh != null) + { + UnitMeshInfoPool.Release(tempMesh); + tempMesh = null; + } + + _time = null; + } + + public void Release(Graphic graphic) + { + + if (graphic is SpriteGraphic) + { + SpriteGraphic spriteGraphic = graphic as SpriteGraphic; + if (renderData != null) + renderData.Remove(spriteGraphic); + + if (textGraphics != null) + { + var en = textGraphics.GetEnumerator(); + while (en.MoveNext()) + { + var list = en.Current.Value; + for (int i = list.Count - 1; i >= 0; --i) + { + var target = list[i]; + + if (UnityEngine.Object.ReferenceEquals(target, graphic)) + { + list.RemoveAt(i); + break; + } + } + } + } + } + + } + + + public void LateUpdate() + { + if (Application.isPlaying) + { + RenderRebuild(); + PlayAnimation(); + } + + } + + void RenderRebuild() + { + EmojiTools.BeginSample("Emoji_UnitRebuild"); + if (rebuildqueue != null && rebuildqueue.Count > 0) + { + for (int i = 0; i < rebuildqueue.Count; ++i) + { + InlineText text = rebuildqueue[i]; + List emojidata = text.PopEmojiData(); + if (emojidata != null && emojidata.Count > 0 && allatlas != null && allatlas.Count > 0) + { + if (tempMesh == null) + tempMesh = UnitMeshInfoPool.Get(); + + if (renderData == null) + renderData = new Dictionary(emojidata.Count); + + List joblist = ListPool.Get(); + + for (int j = 0; j < emojidata.Count; ++j) + { + IFillData taginfo = emojidata[j]; + SpriteGraphic job = Parse(text, taginfo, joblist); + if (job) + joblist.Add(job); + } + + List list; + if (textGraphics != null && textGraphics.TryGetValue(text, out list)) + { + for (int j = 0; j < list.Count; ++j) + { + SpriteGraphic graphic = list[j]; + //not render + if (graphic != null && !joblist.Contains(graphic)) + { + graphic.Draw(null); + graphic.SetVerticesDirty(); + } + } + } + + ListPool.Release(joblist); + } + else + { + List list; + if (textGraphics != null && textGraphics.TryGetValue(text, out list)) + { + for (int j = 0; j < list.Count; ++j) + { + SpriteGraphic graphic = list[j]; + //not render + if (graphic != null) + { + graphic.Draw(null); + graphic.SetVerticesDirty(); + } + } + } + } + } + + rebuildqueue.Clear(); + } + EmojiTools.EndSample(); + } + + void PlayAnimation() + { + EmojiTools.BeginSample("Emoji_UnitAnimation"); + if (alltexts != null) + { + if (_time == null) + { + _time = Time.timeSinceLevelLoad; + } + else + { + float deltatime = Time.timeSinceLevelLoad - _time.Value; + //at least one frame + int framecnt = Mathf.RoundToInt(deltatime * Speed); + if (framecnt > 0) + { + for (int i = 0; i < alltexts.Count; ++i) + { + InlineText text = alltexts[i]; + List emojidata = text.PopEmojiData(); + if (emojidata != null && emojidata.Count > 0 && allatlas != null && allatlas.Count > 0) + { + List joblist = ListPool.Get(); + for (int j = 0; j < emojidata.Count; ++j) + { + IFillData taginfo = emojidata[j]; + SpriteAsset asset = null; + SpriteInfoGroup groupinfo = manager.FindSpriteGroup(taginfo.Tag, out asset); + if (groupinfo != null && groupinfo.spritegroups.Count > 1) + { + int index = framecnt % groupinfo.spritegroups.Count; + SpriteInfo sprInfo = groupinfo.spritegroups[index]; + taginfo.uv = sprInfo.uv; + + List list = null; + SpriteGraphic target = FindGraphic(text, asset, out list); + if (target) + { + if (tempMesh == null) + tempMesh = UnitMeshInfoPool.Get(); + + if (renderData == null) + renderData = new Dictionary(emojidata.Count); + + RefreshSubUIMesh(text, target, asset, taginfo.pos, taginfo.uv, joblist); + joblist.Add(target); + } + } + } + + ListPool.Release(joblist); + } + } + } + } + } + + EmojiTools.EndSample(); + } + + SpriteGraphic Parse(InlineText text, IFillData taginfo, List joblist) + { + if (taginfo != null) + { + return ParsePosAndUV(text, taginfo.ID, taginfo.pos, taginfo.uv, joblist); + } + return null; + } + + SpriteGraphic ParsePosAndUV(InlineText text, int ID, Vector3[] Pos, Vector2[] UV, List joblist) + { + EmojiTools.BeginSample("Emoji_UnitParsePosAndUV"); + SpriteAsset matchAsset = null; + for (int i = 0; i < allatlas.Count; ++i) + { + SpriteAsset asset = allatlas[i]; + if (asset != null && asset.ID == ID) + { + matchAsset = asset; + break; + } + } + + if (matchAsset && matchAsset.texSource != null) + { + List list = null; + SpriteGraphic target = FindGraphic(text, matchAsset, out list); + if (!target) + { + target = CreateSpriteRender(text.transform); + list.Add(target); + } + + RefreshSubUIMesh(text, target, matchAsset, Pos, UV, joblist); + + EmojiTools.EndSample(); + return target; + } + else + { + Debug.LogErrorFormat("missing {0} atlas", ID); + } + EmojiTools.EndSample(); + return null; + } + + void RefreshSubUIMesh(InlineText text, SpriteGraphic target, SpriteAsset matchAsset, Vector3[] Pos, Vector2[] UV, List joblist) + { + // set mesh + tempMesh.SetAtlas(matchAsset); + tempMesh.SetUVLen(UV.Length); + tempMesh.SetVertLen(Pos.Length); + + for (int i = 0; i < Pos.Length; ++i) + { + //text object pos + Vector3 value = Pos[i]; + Vector3 worldpos = text.transform.TransformPoint(value); + Vector3 localpos = target.transform.InverseTransformPoint(worldpos); + tempMesh.SetVert(i, localpos); + } + + for (int i = 0; i < UV.Length; ++i) + { + Vector2 value = UV[i]; + tempMesh.SetUV(i, value); + } + + //rendermesh + UnitMeshInfo currentMesh = null; + if (!this.renderData.TryGetValue(target, out currentMesh)) + { + currentMesh = new UnitMeshInfo(); + renderData[target] = currentMesh; + } + + if (!currentMesh.Equals(tempMesh)) + { + if (joblist != null && joblist.Contains(target)) + { + currentMesh.AddCopy(tempMesh); + tempMesh.Clear(); + } + else + { + currentMesh.Copy(tempMesh); + } + } + + if (currentMesh.VertCnt() > 3 && currentMesh.UVCnt() > 3) + { + target.Draw(this); + target.SetVerticesDirty(); + } + else + { + target.Draw(null); + target.SetVerticesDirty(); + } + } + + public void FillMesh(Graphic graphic, VertexHelper vh) + { + UnitMeshInfo rendermesh; + if (renderData != null && renderData.Count > 0 && renderData.TryGetValue(graphic, out rendermesh)) + { + if (rendermesh != null && rendermesh.getTexture() != null) + { + int vertcnt = rendermesh.VertCnt(); + int uvcnt = rendermesh.UVCnt(); + if (vertcnt != uvcnt) + { + Debug.LogError("data error"); + } + else + { + for (int i = 0; i < vertcnt; ++i) + { + vh.AddVert(rendermesh.GetVert(i), graphic.color, rendermesh.GetUV(i)); + } + + int cnt = vertcnt / 4; + for (int i = 0; i < cnt; ++i) + { + int m = i * 4; + + vh.AddTriangle(m, m + 1, m + 2); + vh.AddTriangle(m + 2, m + 3, m); + } + + //vh.AddTriangle(0, 1, 2); + //vh.AddTriangle(2, 3, 0); + } + } + } + } + + public void DrawGizmos(Graphic graphic) + { + UnitMeshInfo rendermesh; + if (renderData != null && renderData.Count > 0 && renderData.TryGetValue(graphic, out rendermesh)) + { + if (rendermesh != null && rendermesh.getTexture() != null) + { + Gizmos.color = Color.red; + int vertcnt = rendermesh.VertCnt(); + int uvcnt = rendermesh.UVCnt(); + if (vertcnt != uvcnt) + { + Debug.LogError("data error"); + } + else + { + for (int i = 0; i < vertcnt; i += 4) + { + Vector3 p1 = getPoint(graphic, rendermesh.GetVert(i)); + Vector3 p2 = getPoint(graphic, rendermesh.GetVert(i + 1)); + Vector3 p3 = getPoint(graphic, rendermesh.GetVert(i + 2)); + Vector3 p4 = getPoint(graphic, rendermesh.GetVert(i + 3)); + + Gizmos.DrawLine(p1, p2); + Gizmos.DrawLine(p2, p3); + Gizmos.DrawLine(p3, p4); + Gizmos.DrawLine(p4, p1); + } + } + } + } + + } + + Vector3 getPoint(Graphic graphic, Vector3 v) + { + Vector3 worldpos = graphic.transform.TransformPoint(v); + return worldpos; + } + + #region 考虑到后面测试和调整的时候数据类型的转换 + + SpriteGraphic FindGraphic(InlineText text, int atlasID, out SpriteAsset matchAsset) + { + matchAsset = null; + for (int i = 0; i < allatlas.Count; ++i) + { + SpriteAsset asset = allatlas[i]; + if (asset != null && asset.ID == atlasID) + { + matchAsset = asset; + break; + } + } + + if (matchAsset && matchAsset.texSource != null) + { + List list = null; + SpriteGraphic target = FindGraphic(text, matchAsset, out list); + if (!target) + { + target = CreateSpriteRender(text.transform); + list.Add(target); + } + return target; + } + return null; + } + + + SpriteGraphic FindGraphic(InlineText text, SpriteAsset matchAsset, out List list) + { + EmojiTools.BeginSample("Emoji_UnitFindGraphic"); + if (textGraphics == null) + textGraphics = new Dictionary>(); + + if (!textGraphics.TryGetValue(text, out list)) + { + list = ListPool.Get(); + textGraphics[text] = list; + } + + SpriteGraphic target = null; + for (int i = 0; i < list.Count; ++i) + { + SpriteGraphic graphic = list[i]; + if (graphic && UnityEngine.Object.ReferenceEquals(graphic.mainTexture, matchAsset.texSource)) + { + target = graphic; + break; + } + } + EmojiTools.EndSample(); + return target; + } + + void AddInText(InlineText text) + { + if (alltexts == null) + { + alltexts = ListPool.Get(); + } + + if (!alltexts.Contains(text)) + { + alltexts.Add(text); + } + } + + void RemoveInText(InlineText text) + { + if (alltexts != null) + { + alltexts.Remove(text); + } + } + + #endregion + + SpriteGraphic CreateSpriteRender(Transform targetTrans) + { + if (PoolObj == null) + { + PoolObj = new GameObject("UnitRenderPool"); + SpriteGraphic target = null; + for (int i = 0; i < 10; i++) + { + target = CreateInstance(PoolObj.transform); + } + + target.transform.SetParent(targetTrans); + return target; + } + else + { + int childcnt = PoolObj.transform.childCount; + if (childcnt > 0) + { + Transform trans = PoolObj.transform.GetChild(0); + trans.SetParent(targetTrans); + return trans.GetComponent(); + } + + return CreateInstance(targetTrans); + } + } + + SpriteGraphic CreateInstance(Transform targetTrans) + { + GameObject newobject = new GameObject("pre_Sprite"); + newobject.transform.SetParent(targetTrans); + newobject.transform.localPosition = Vector3.zero; + newobject.transform.localScale = Vector3.one; + newobject.transform.localRotation = Quaternion.identity; + newobject.transform.gameObject.layer = targetTrans.gameObject.layer; + newobject.transform.tag = targetTrans.gameObject.tag; + //newobject.transform.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector; + + SpriteGraphic spritegrahic = newobject.AddComponent(); + spritegrahic.raycastTarget = false; + return spritegrahic; + } + + } } diff --git a/Assets/TextInlineSprite/Scripts/InlineText.cs b/Assets/TextInlineSprite/Scripts/InlineText.cs index c8eaea8..99dca97 100644 --- a/Assets/TextInlineSprite/Scripts/InlineText.cs +++ b/Assets/TextInlineSprite/Scripts/InlineText.cs @@ -5,7 +5,7 @@ /// date: /// version:v1.0 /// ======================================================== - + using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -16,810 +16,432 @@ using UnityEngine.Events; using System; -namespace EmojiUI +namespace EmojiUI { - public class InlineText : Text, IPointerClickHandler - { - // 用正则取 [图集ID#表情Tag] ID值==-1 ,表示为超链接 - private static readonly Regex _InputTagRegex = new Regex(@"\[(\-{0,1}\d{0,})#(.+?)\]", RegexOptions.Singleline); - private static StringBuilder _textBuilder; - private static UIVertex[] m_TempVerts = new UIVertex[4]; - private static TextGenerator _UnderlineText; - private TextGenerator _SpaceGen; - private List _listVertsPos; - private InlineManager _InlineManager; - //文本表情管理器 - private InlineManager Manager - { - get - { - if (!_InlineManager && canvas != null) - { - _InlineManager =GetComponentInParent(); - if (_InlineManager == null) - { - _InlineManager = canvas.gameObject.AddComponent(); - } - } - return _InlineManager; - } - } - - List RenderTagList; - private const string palceholder = "1"; - private bool needupdate; - private bool updatespace =true; - private string _OutputText = ""; - - #region 超链接 - [System.Serializable] - public class HrefClickEvent : UnityEvent { } - //点击事件监听 - public HrefClickEvent OnHrefClick = new HrefClickEvent(); - // 超链接信息列表 - private List _ListHrefInfos; - #endregion - - private float? _pw; - - public override float preferredWidth - { - get - { - if(_pw == null) - { - //its override from uGUI Code ,but has bug? - - //var settings = GetGenerationSettings(Vector2.zero); - //return cachedTextGeneratorForLayout.GetPreferredWidth(_OutputText, settings) / pixelsPerUnit; - - //next idea - Vector2 extents = rectTransform.rect.size; - - var settings = GetGenerationSettings(extents); - cachedTextGenerator.Populate(_OutputText, settings); - - if(cachedTextGenerator.lineCount > 1) - { - float? minx = null; - float? maxx = null; - IList verts = cachedTextGenerator.verts; - int maxIndex = cachedTextGenerator.lines[1].startCharIdx; - - for (int i = 0, index = 0; i < verts.Count; i += 4, index++) - { - UIVertex v0 = verts[i]; - UIVertex v2 = verts[i + 1]; - float min = v0.position.x; - float max = v2.position.x; - - if (minx.HasValue == false) - { - minx = min; - } - else - { - minx = Mathf.Min(minx.Value, min); - } - - if (maxx.HasValue == false) - { - maxx = max; - } - else - { - maxx = Mathf.Max(maxx.Value, max); - } - - if (index > maxIndex) - { - break; - } - } - - _pw = (maxx - minx); - } - else - { - //_pw = cachedTextGeneratorForLayout.GetPreferredWidth(_OutputText, settings) / pixelsPerUnit; - float? minx = null; - float? maxx = null; - IList verts = cachedTextGenerator.verts; - int maxIndex = cachedTextGenerator.characterCount; - - for (int i = 0, index = 0; i < verts.Count; i += 4, index++) - { - UIVertex v0 = verts[i]; - UIVertex v2 = verts[i + 1]; - float min = v0.position.x; - float max = v2.position.x; - - if (minx.HasValue == false) - { - minx = min; - } - else - { - minx = Mathf.Min(minx.Value, min); - } - - if (maxx.HasValue == false) - { - maxx = max; - } - else - { - maxx = Mathf.Max(maxx.Value, max); - } - - if (index > maxIndex) - { - break; - } - } - - _pw = (maxx - minx); - } - - } - return _pw.Value; - } - } - - public override float preferredHeight - { - get - { - var settings = GetGenerationSettings(new Vector2(GetPixelAdjustedRect().size.x, 0.0f)); - return cachedTextGeneratorForLayout.GetPreferredHeight(_OutputText, settings) / pixelsPerUnit; - } - } - - void OnDrawGizmos() - { - Gizmos.color = Color.blue; - - var corners = new Vector3[4]; - rectTransform.GetWorldCorners(corners); - - Gizmos.DrawLine(corners[0], corners[1]); - Gizmos.DrawLine(corners[1], corners[2]); - Gizmos.DrawLine(corners[3], corners[3]); - Gizmos.DrawLine(corners[3], corners[0]); - //Vector3 size = new Vector3(preferredWidth, preferredHeight, 0); - //Vector3 fixsize = transform.TransformDirection(rectTransform.rect.size); - //Vector3 textsize = transform.TransformDirection(size); - - //Vector3 fixpos = transform.position; - //int cid = ((int)alignment) / 3; - //int rid = ((int)alignment) % 3; - //float pivx = this.rectTransform.pivot.x; - //float pivy = this.rectTransform.pivot.y; - - ////可简化 - //if (this.alignment == TextAnchor.LowerCenter) - //{ - // fixpos += new Vector3(0, -0.5f * (fixsize.y - textsize.y), 0); - //} - //else if (this.alignment == TextAnchor.LowerLeft) - //{ - // fixpos += new Vector3(-0.5f * (fixsize.x - textsize.x), -0.5f * (fixsize.y - textsize.y), 0); - //} - //else if (this.alignment == TextAnchor.LowerRight) - //{ - // fixpos += new Vector3(0.5f * (fixsize.x - textsize.x), -0.5f * (fixsize.y - textsize.y), 0); - //} - //else if (this.alignment == TextAnchor.MiddleCenter) - //{ - // fixpos += new Vector3(0, 0, 0); - //} - //else if (this.alignment == TextAnchor.MiddleLeft) - //{ - // fixpos += new Vector3(-0.5f * (fixsize.x - textsize.x), 0, 0); - //} - //else if (this.alignment == TextAnchor.MiddleRight) - //{ - // fixpos += new Vector3(0.5f * (fixsize.x - textsize.x), 0, 0); - //} - //else if (this.alignment == TextAnchor.UpperCenter) - //{ - // fixpos += new Vector3(0, 0.5f * (fixsize.y - textsize.y), 0); - //} - //else if (this.alignment == TextAnchor.UpperLeft) - //{ - // fixpos += new Vector3(-0.5f * (fixsize.x - textsize.x), 0.5f * (fixsize.y - textsize.y), 0); - //} - //else if (this.alignment == TextAnchor.UpperRight) - //{ - // fixpos += new Vector3(0.5f * (fixsize.x - textsize.x), 0.5f * (fixsize.y - textsize.y), 0); - //} - - // Gizmos.DrawWireCube(fixpos, textsize); - } - - protected override void Start() - { - base.Start(); - - EmojiTools.AddUnityMemory(this); - } - - protected override void OnEnable() - { - base.OnEnable(); - - // supportRichText = true; - SetVerticesDirty(); - } - - public override void SetVerticesDirty() - { - base.SetVerticesDirty(); - if (!Application.isPlaying || !Manager) - { - _pw = null; - _OutputText = m_Text; - return; - } - - string outtext = GetOutputText(m_Text); - if (RenderTagList != null && RenderTagList.Count > 0) - { - _OutputText = outtext; - needupdate = true; - _pw = null; - } - else - { - _OutputText = m_Text; - needupdate = true; - _pw = null; - } - } - - protected override void OnDestroy() - { - base.OnDestroy(); - - if(RenderTagList != null) - { - ListPool.Release(RenderTagList); - RenderTagList = null; - } - - if(_ListHrefInfos != null) - { - ListPool.Release(_ListHrefInfos); - _ListHrefInfos = null; - } - - if(Manager) - { - Manager.UnRegister(this); - } - - EmojiTools.RemoveUnityMemory(this); - } - - protected override void OnPopulateMesh(VertexHelper toFill) - { - if (font == null) - return; - - // We don't care if we the font Texture changes while we are doing our Update. - // The end result of cachedTextGenerator will be valid for this instance. - // Otherwise we can get issues like Case 619238. - m_DisableFontTextureRebuiltCallback = true; - - Vector2 extents = rectTransform.rect.size; - - var settings = GetGenerationSettings(extents); - cachedTextGenerator.PopulateWithErrors(_OutputText, settings, gameObject); - - // Apply the offset to the vertices - IList verts = cachedTextGenerator.verts; - float unitsPerPixel = 1 / pixelsPerUnit; - //Last 4 verts are always a new line... (\n) - int vertCount = verts.Count - 4; - Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y) * unitsPerPixel; - roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset; - toFill.Clear(); - - //ClearQuadUVs(verts); - - if(RenderTagList != null && RenderTagList.Count >0) - { - if(_listVertsPos == null) - _listVertsPos = new List(); - else - _listVertsPos.Clear(); - } - - - int NextSkipMin = -10; - int NextSkipMax = -10; - int TagIndex = 0; - if (RenderTagList != null && RenderTagList.Count > 0) - { - var data = RenderTagList[TagIndex]; - NextSkipMin = data.GetPositionIdx(); - NextSkipMax = NextSkipMin + 4 * data.GetPlaceHolderCnt(); - } - - if (roundingOffset != Vector2.zero) - { - for (int i = 0; i < vertCount; ++i) - { - int tempVertsIndex = i & 3; - m_TempVerts[tempVertsIndex] = verts[i]; - m_TempVerts[tempVertsIndex].position *= unitsPerPixel; - m_TempVerts[tempVertsIndex].position.x += roundingOffset.x; - m_TempVerts[tempVertsIndex].position.y += roundingOffset.y; - - if(NextSkipMin >=0 && i >= NextSkipMin && i <= NextSkipMax) - { - - } - else - { - if (tempVertsIndex == 3) - toFill.AddUIVertexQuad(m_TempVerts); - } - - - if (RenderTagList != null && RenderTagList.Count > 0) - { - if (i == NextSkipMax) - { - TagIndex++; - if (RenderTagList.Count > TagIndex) - { - var data = RenderTagList[TagIndex]; - NextSkipMin = data.GetPositionIdx(); - NextSkipMax = NextSkipMin + 4 * data.GetPlaceHolderCnt(); - } - else - { - NextSkipMin = -10; - } - } - - _listVertsPos.Add(m_TempVerts[tempVertsIndex].position); - } - - } - } - else - { - for (int i = 0; i < vertCount; ++i) - { - int tempVertsIndex = i & 3; - m_TempVerts[tempVertsIndex] = verts[i]; - m_TempVerts[tempVertsIndex].position *= unitsPerPixel; - - if (NextSkipMin >= 0 && i >= NextSkipMin && i <= NextSkipMax) - { - - } - else - { - if (tempVertsIndex == 3) - toFill.AddUIVertexQuad(m_TempVerts); - } - - - if (RenderTagList != null && RenderTagList.Count > 0) - { - if (i == NextSkipMax) - { - TagIndex++; - if (RenderTagList.Count > TagIndex) - { - var data = RenderTagList[TagIndex]; - NextSkipMin = data.GetPositionIdx(); - NextSkipMax = NextSkipMin + 4 * data.GetPlaceHolderCnt(); - } - else - { - NextSkipMin = -10; - } - } - - _listVertsPos.Add(m_TempVerts[tempVertsIndex].position); - } - } - } - - ////计算quad占位的信息 - CalcQuadInfo(); - //计算包围盒 - CalcBoundsInfo(toFill, settings); - - if (needupdate && Manager != null) - { - if((_ListHrefInfos != null && _ListHrefInfos.Count >0 ) || (RenderTagList != null && RenderTagList.Count >0)) - { - Manager.Register(this); - } - else - { - Manager.UnRegister(this); - } - } - - m_DisableFontTextureRebuiltCallback = false; - needupdate = false; - } - - private void ClearQuadUVs(IList verts) - { - if (RenderTagList != null) - { - for (int i = 0; i < RenderTagList.Count; ++i) - { - SpriteTagInfo info = RenderTagList[i]; - int pos = info.GetPositionIdx(); - if ((pos + 4) > verts.Count) - continue; - for (int m = pos; m < pos + 4; m++) - { - //清除乱码 - UIVertex tempVertex = verts[m]; - tempVertex.uv0 = Vector2.zero; - verts[m] = tempVertex; - } - } - } - - } - - void CalcQuadInfo() - { - if(RenderTagList != null) - { - Rect rect = rectTransform.rect; - for(int i = RenderTagList.Count -1; i >= 0;--i) - { - SpriteTagInfo info = RenderTagList[i]; - int pos = info.GetPositionIdx(); - if ((pos + 4) > _listVertsPos.Count) - continue; - - Vector3 p1 = _listVertsPos[pos+3]; - - //info._Pos[0] = p1 ; - //info._Pos[1] = _listVertsPos[pos+1]; - //info._Pos[2] = _listVertsPos[pos+2]; - //info._Pos[3] = _listVertsPos[pos+3]; - //int cid = ((int)alignment) /3; - //int rid = ((int)alignment) % 3; - - info._Pos[0] = p1 + new Vector3(0, info._Size.y , 0); - info._Pos[1] = p1 + new Vector3(info._Size.x,info._Size.y, 0); - info._Pos[2] = p1 + new Vector3(info._Size.x,0, 0); - info._Pos[3] = p1 + new Vector3(0, 0 ,0); - } - } - - } - - void CalcBoundsInfo(VertexHelper toFill, TextGenerationSettings settings) - { - - if(_ListHrefInfos != null && _ListHrefInfos.Count >0) - { - - if (_listVertsPos == null) - _listVertsPos = new List(); - // 处理超链接包围框 - for (int k = 0; k< _ListHrefInfos.Count;++k) - { - var hrefInfo = _ListHrefInfos[k]; - hrefInfo.boxes.Clear(); - if (hrefInfo.startIndex >= _listVertsPos.Count) - { - continue; - } - - // 将超链接里面的文本顶点索引坐标加入到包围框 - var pos = _listVertsPos[hrefInfo.startIndex]; - var bounds = new Bounds(pos, Vector3.zero); - for (int i = hrefInfo.startIndex, m = hrefInfo.endIndex; i < m; i++) - { - if (i >= _listVertsPos.Count) - { - break; - } - - pos = _listVertsPos[i]; - if (pos.x < bounds.min.x) - { - // 换行重新添加包围框 - hrefInfo.boxes.Add(new Rect(bounds.min, bounds.size)); - bounds = new Bounds(pos, Vector3.zero); - } - else - { - bounds.Encapsulate(pos); // 扩展包围框 - } - } - //添加包围盒 - hrefInfo.boxes.Add(new Rect(bounds.min, bounds.size)); - } - - - if(_UnderlineText == null) - { - _UnderlineText = new TextGenerator(); - _UnderlineText.Populate("_", settings); - } - - IList _TUT = _UnderlineText.verts; - - for (int m = 0; m < _ListHrefInfos.Count; ++m) - { - var item = _ListHrefInfos[m]; - for (int i = 0; i < item.boxes.Count; i++) - { - - //绘制下划线 - for (int j = 0; j < 4; j++) - { - m_TempVerts[j] = _TUT[j]; - m_TempVerts[j].color = Color.blue; - - if(j ==0) - { - m_TempVerts[j].position =item.boxes[i].position + new Vector2(0.0f, fontSize * 0.2f); - } - else if(j == 1) - { - m_TempVerts[j].position =item.boxes[i].position + new Vector2(item.boxes[i].width, fontSize * 0.2f); - } - else if(j == 2) - { - m_TempVerts[j].position = item.boxes[i].position + new Vector2(item.boxes[i].width, 0.0f); - } - else - { - m_TempVerts[j].position = item.boxes[i].position; - } - - if (j == 3) - toFill.AddUIVertexQuad(m_TempVerts); - } - - } - } - } - } - - public List PopEmojiData() - { - return RenderTagList; - } - - bool ParseHref(string newInfo,int hrefCnt, int Id,string TagName, Match match,ref int _textIndex) - { - if(Id <0) - { - _textBuilder.Append(newInfo.Substring(_textIndex, match.Index - _textIndex)); - _textBuilder.Append(""); - int _startIndex = _textBuilder.Length * 4; - _textBuilder.Append("[" + TagName + "]"); - int _endIndex = _textBuilder.Length * 4 - 2; - _textBuilder.Append(""); - - if(_ListHrefInfos.Count > hrefCnt) - { - HrefInfo hrefInfo = _ListHrefInfos[hrefCnt]; - hrefInfo.id = Mathf.Abs(Id); - hrefInfo.startIndex = _startIndex;// 超链接里的文本起始顶点索引 - hrefInfo.endIndex = _endIndex; - hrefInfo.name = TagName; - } - else - { - HrefInfo hrefInfo = new HrefInfo - { - id = Mathf.Abs(Id), - startIndex = _startIndex, // 超链接里的文本起始顶点索引 - endIndex = _endIndex, - name = TagName - }; - _ListHrefInfos.Add(hrefInfo); - } - - - return true; - } - return false; - } - - bool ParseEmoji(string newInfo,int Index, int Id, string TagName, Match match, ref int _textIndex) - { - if (Manager != null && Manager.CanRendering(Id) && Manager.CanRendering(TagName)) - { - SpriteAsset sprAsset; - SpriteInfoGroup tagSprites = Manager.FindSpriteGroup(TagName, out sprAsset); - if (tagSprites != null && tagSprites.spritegroups.Count > 0) - { - if (!Manager.isRendering(sprAsset)) - { - Manager.PushRenderAtlas(sprAsset); - } - - _textBuilder.Append(newInfo.Substring(_textIndex, match.Index - _textIndex)); - int _tempIndex = _textBuilder.Length * 4; - - - if (_SpaceGen == null) - { - _SpaceGen = new TextGenerator(); - } - - if(updatespace) - { - Vector2 extents = rectTransform.rect.size; - TextGenerationSettings settings = GetGenerationSettings(extents); - _SpaceGen.Populate(palceholder, settings); - updatespace = false; - } - - IList spaceverts = _SpaceGen.verts; - float spacewid = spaceverts[1].position.x - spaceverts[0].position.x; - float spaceheight = spaceverts[0].position.y - spaceverts[3].position.y; - - - float autosize = Mathf.Min( tagSprites.size,Mathf.Max(spacewid,spaceheight)); - float spacesize = Mathf.Max(spacewid, spaceheight); - - int fillspacecnt = Mathf.CeilToInt(autosize / spacesize); - - for (int i = 0; i < fillspacecnt; i++) - { - _textBuilder.Append(palceholder); - } - Debug.LogError(autosize); - - //_textBuilder.AppendFormat("", tagSprites.x, tagSprites.y, autosize, tagSprites.width); - - if (RenderTagList.Count > Index) - { - SpriteTagInfo _tempSpriteTag = RenderTagList[Index]; - _tempSpriteTag._ID = Id; - _tempSpriteTag._Tag = TagName; - _tempSpriteTag._Size = new Vector2(autosize, autosize); - _tempSpriteTag.FillIdxAndPlaceHolder(_tempIndex, fillspacecnt); - _tempSpriteTag._UV = tagSprites.spritegroups[0].uv; - } - else - { - SpriteTagInfo _tempSpriteTag = new SpriteTagInfo - { - _ID = Id, - _Tag = TagName, - _Size = new Vector2(autosize , autosize), - _Pos = new Vector3[4], - _UV = tagSprites.spritegroups[0].uv - }; - - _tempSpriteTag.FillIdxAndPlaceHolder(_tempIndex, fillspacecnt); - - RenderTagList.Add(_tempSpriteTag); - } - - return true; - } - else - { - Debug.LogErrorFormat("missing {0} or lenght too low :{1}", TagName, tagSprites != null ? tagSprites.spritegroups.Count : 0); - } - - } - else if(Manager) - { - //Debug.LogErrorFormat("not found that atlas:{0} or Tag:{1}", Id, TagName); - } - return false; - } - - private string GetOutputText(string newinfo) - { - if (RenderTagList == null) - RenderTagList = ListPool.Get(); - - if (_ListHrefInfos == null) - _ListHrefInfos = ListPool.Get(); - - if (_textBuilder == null) - _textBuilder = new StringBuilder(newinfo.Length); - else - _textBuilder.Length = 0; - - int _textIndex = 0; - int hrefCnt = 0; - int emojicnt = 0; - - MatchCollection en = _InputTagRegex.Matches(newinfo); - for(int i =0; i < en.Count;++i) - { - Match match = en[i]; - - int tempId = 0; - if(match.Groups.Count>0 ) - { - string firstgpval = match.Groups[1].Value; - if (!string.IsNullOrEmpty(firstgpval) && !firstgpval.Equals("-")) - { - tempId = int.Parse(firstgpval); - } - } - - string tempTag = null; - if (match.Groups.Count > 1) - { - tempTag = match.Groups[2].Value; - } - - if(!ParseHref(newinfo, hrefCnt, tempId, tempTag,match,ref _textIndex)) - { - if(ParseEmoji(newinfo, emojicnt, tempId, tempTag, match, ref _textIndex)) - { - emojicnt++; - } - } - else - { - hrefCnt++; - } - - _textIndex = match.Index + match.Length; - } - - //remove unused - for(int i = RenderTagList.Count -1; i >= emojicnt;--i) - { - SpriteTagInfo info = RenderTagList[i]; - RenderTagList.RemoveAt(i); - } - - for (int i = _ListHrefInfos.Count - 1; i >= hrefCnt; --i) - { - HrefInfo info = _ListHrefInfos[i]; - _ListHrefInfos.RemoveAt(i); - } - - _textBuilder.Append(newinfo.Substring(_textIndex, newinfo.Length - _textIndex)); - - updatespace = true; - return _textBuilder.ToString(); - } - - - #region 点击事件检测是否点击到超链接文本 - public void OnPointerClick(PointerEventData eventData) - { - Vector2 lp; - RectTransformUtility.ScreenPointToLocalPointInRectangle( - rectTransform, eventData.position, eventData.pressEventCamera, out lp); - - foreach (var hrefInfo in _ListHrefInfos) - { - var boxes = hrefInfo.boxes; - for (var i = 0; i < boxes.Count; ++i) - { - if (boxes[i].Contains(lp)) - { - OnHrefClick.Invoke(hrefInfo.name, hrefInfo.id); - return; - } - } - } - } - #endregion - - } + public class InlineText : Text + { + private static StringBuilder _textBuilder = new StringBuilder(); + private static UIVertex[] m_TempVerts = new UIVertex[4]; + + private TextGenerator _SpaceGen; + private List _listVertsPos; + private InlineManager _InlineManager; + //文本表情管理器 + public InlineManager Manager + { + get + { + if (!_InlineManager && canvas != null) + { + _InlineManager = GetComponentInParent(); + if (_InlineManager == null) + { + _InlineManager = canvas.gameObject.AddComponent(); + } + } + return _InlineManager; + } + } + + List RenderTagList; + + private string _OutputText = ""; + private float? _pw; + + public override float preferredWidth + { + get + { + if (_pw == null) + { + //its override from uGUI Code ,but has bug? + + //var settings = GetGenerationSettings(Vector2.zero); + //return cachedTextGeneratorForLayout.GetPreferredWidth(_OutputText, settings) / pixelsPerUnit; + + //next idea + Vector2 extents = rectTransform.rect.size; + + var settings = GetGenerationSettings(extents); + cachedTextGenerator.Populate(_OutputText, settings); + + if (cachedTextGenerator.lineCount > 1) + { + float? minx = null; + float? maxx = null; + IList verts = cachedTextGenerator.verts; + int maxIndex = cachedTextGenerator.lines[1].startCharIdx; + + for (int i = 0, index = 0; i < verts.Count; i += 4, index++) + { + UIVertex v0 = verts[i]; + UIVertex v2 = verts[i + 1]; + float min = v0.position.x; + float max = v2.position.x; + + if (minx.HasValue == false) + { + minx = min; + } + else + { + minx = Mathf.Min(minx.Value, min); + } + + if (maxx.HasValue == false) + { + maxx = max; + } + else + { + maxx = Mathf.Max(maxx.Value, max); + } + + if (index > maxIndex) + { + break; + } + } + + _pw = (maxx - minx); + } + else + { + //_pw = cachedTextGeneratorForLayout.GetPreferredWidth(_OutputText, settings) / pixelsPerUnit; + float? minx = null; + float? maxx = null; + IList verts = cachedTextGenerator.verts; + int maxIndex = cachedTextGenerator.characterCount; + + for (int i = 0, index = 0; i < verts.Count; i += 4, index++) + { + UIVertex v0 = verts[i]; + UIVertex v2 = verts[i + 1]; + float min = v0.position.x; + float max = v2.position.x; + + if (minx.HasValue == false) + { + minx = min; + } + else + { + minx = Mathf.Min(minx.Value, min); + } + + if (maxx.HasValue == false) + { + maxx = max; + } + else + { + maxx = Mathf.Max(maxx.Value, max); + } + + if (index > maxIndex) + { + break; + } + } + + _pw = (maxx - minx); + } + + } + return _pw.Value; + } + } + + public override float preferredHeight + { + get + { + var settings = GetGenerationSettings(new Vector2(GetPixelAdjustedRect().size.x, 0.0f)); + return cachedTextGeneratorForLayout.GetPreferredHeight(_OutputText, settings) / pixelsPerUnit; + } + } + + void OnDrawGizmos() + { + Gizmos.color = Color.blue; + + var corners = new Vector3[4]; + rectTransform.GetWorldCorners(corners); + + Gizmos.DrawLine(corners[0], corners[1]); + Gizmos.DrawLine(corners[1], corners[2]); + Gizmos.DrawLine(corners[3], corners[3]); + Gizmos.DrawLine(corners[3], corners[0]); + } + + protected override void Start() + { + base.Start(); + + EmojiTools.AddUnityMemory(this); + } + +#if UNITY_EDITOR + protected override void OnValidate() + { + //do nothing + } +#endif + + public override void SetVerticesDirty() + { + base.SetVerticesDirty(); + if (!Application.isPlaying || !Manager) + { + _pw = null; + _OutputText = m_Text; + return; + } + + ParserTransmit.mIns.DoParser(this, _textBuilder, m_Text); + + _OutputText = _textBuilder.ToString(); + _textBuilder.Length = 0; + Debug.LogError(_OutputText); + + } + + protected override void OnDestroy() + { + base.OnDestroy(); + + if (RenderTagList != null) + { + ListPool.Release(RenderTagList); + RenderTagList = null; + } + + if (Manager) + { + Manager.UnRegister(this); + } + + EmojiTools.RemoveUnityMemory(this); + } + + protected override void OnPopulateMesh(VertexHelper toFill) + { + if (font == null) + return; + + // We don't care if we the font Texture changes while we are doing our Update. + // The end result of cachedTextGenerator will be valid for this instance. + // Otherwise we can get issues like Case 619238. + m_DisableFontTextureRebuiltCallback = true; + + Vector2 extents = rectTransform.rect.size; + + var settings = GetGenerationSettings(extents); + cachedTextGenerator.PopulateWithErrors(_OutputText, settings, gameObject); + + // Apply the offset to the vertices + IList verts = cachedTextGenerator.verts; + float unitsPerPixel = 1 / pixelsPerUnit; + //Last 4 verts are always a new line... (\n) + int vertCount = verts.Count - 4; + Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y) * unitsPerPixel; + roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset; + toFill.Clear(); + + //ClearQuadUVs(verts); + + if (RenderTagList != null && RenderTagList.Count > 0) + { + if (_listVertsPos == null) + _listVertsPos = new List(); + else + _listVertsPos.Clear(); + } + + + int NextSkipMin = -10; + int NextSkipMax = -10; + int TagIndex = 0; + if (RenderTagList != null && RenderTagList.Count > 0) + { + var data = RenderTagList[TagIndex]; + NextSkipMin = data.GetPositionIdx(); + NextSkipMax = NextSkipMin + 4 * data.GetPlaceHolderCnt(); + } + + if (roundingOffset != Vector2.zero) + { + for (int i = 0; i < vertCount; ++i) + { + int tempVertsIndex = i & 3; + m_TempVerts[tempVertsIndex] = verts[i]; + m_TempVerts[tempVertsIndex].position *= unitsPerPixel; + m_TempVerts[tempVertsIndex].position.x += roundingOffset.x; + m_TempVerts[tempVertsIndex].position.y += roundingOffset.y; + + if (NextSkipMin >= 0 && i >= NextSkipMin && i <= NextSkipMax) + { + + } + else + { + if (tempVertsIndex == 3) + toFill.AddUIVertexQuad(m_TempVerts); + } + + + if (RenderTagList != null && RenderTagList.Count > 0) + { + if (i == NextSkipMax) + { + TagIndex++; + if (RenderTagList.Count > TagIndex) + { + var data = RenderTagList[TagIndex]; + NextSkipMin = data.GetPositionIdx(); + NextSkipMax = NextSkipMin + 4 * data.GetPlaceHolderCnt(); + } + else + { + NextSkipMin = -10; + } + } + + _listVertsPos.Add(m_TempVerts[tempVertsIndex].position); + } + + } + } + else + { + for (int i = 0; i < vertCount; ++i) + { + int tempVertsIndex = i & 3; + m_TempVerts[tempVertsIndex] = verts[i]; + m_TempVerts[tempVertsIndex].position *= unitsPerPixel; + + if (NextSkipMin >= 0 && i >= NextSkipMin && i <= NextSkipMax) + { + + } + else + { + if (tempVertsIndex == 3) + toFill.AddUIVertexQuad(m_TempVerts); + } + + if (RenderTagList != null && RenderTagList.Count > 0) + { + if (i == NextSkipMax) + { + TagIndex++; + if (RenderTagList.Count > TagIndex) + { + var data = RenderTagList[TagIndex]; + NextSkipMin = data.GetPositionIdx(); + NextSkipMax = NextSkipMin + 4 * data.GetPlaceHolderCnt(); + } + else + { + NextSkipMin = -10; + } + } + + _listVertsPos.Add(m_TempVerts[tempVertsIndex].position); + } + } + } + + m_DisableFontTextureRebuiltCallback = false; + needupdate = false; + } + + + public List PopEmojiData() + { + return RenderTagList; + } + + + internal void FillSpriteTag(StringBuilder stringBuilder, Match match, int Index, ParsedData tagInfo) + { + int Id = tagInfo.atlasID; + string TagName = tagInfo.atlasTag; + if (Manager != null && Manager.CanRendering(Id) && Manager.CanRendering(TagName)) + { + SpriteAsset sprAsset; + SpriteInfoGroup tagSprites = Manager.FindSpriteGroup(TagName, out sprAsset); + if (tagSprites != null && tagSprites.spritegroups.Count > 0) + { + if (!Manager.isRendering(sprAsset)) + { + Manager.PushRenderAtlas(sprAsset); + } + + if (_SpaceGen == null) + { + _SpaceGen = new TextGenerator(); + } + + if (updatespace) + { + Vector2 extents = rectTransform.rect.size; + TextGenerationSettings settings = GetGenerationSettings(extents); + _SpaceGen.Populate(palceholder, settings); + updatespace = false; + } + + IList spaceverts = _SpaceGen.verts; + float spacewid = spaceverts[1].position.x - spaceverts[0].position.x; + float spaceheight = spaceverts[0].position.y - spaceverts[3].position.y; + + + float autosize = Mathf.Min(tagSprites.size, Mathf.Max(spacewid, spaceheight)); + float spacesize = Mathf.Max(spacewid, spaceheight); + + int fillspacecnt = Mathf.CeilToInt(autosize / spacesize); + + for (int i = 0; i < fillspacecnt; i++) + { + stringBuilder.Append(palceholder); + } + + if (RenderTagList == null) + { + RenderTagList = ListPool.Get(); + } + + if (RenderTagList.Count > Index) + { + SpriteTagInfo _tempSpriteTag = RenderTagList[Index]; + _tempSpriteTag._ID = Id; + _tempSpriteTag._Tag = TagName; + _tempSpriteTag._Size = new Vector2(autosize, autosize); + _tempSpriteTag.FillIdxAndPlaceHolder(match.Index, fillspacecnt); + _tempSpriteTag._UV = tagSprites.spritegroups[0].uv; + } + else + { + SpriteTagInfo _tempSpriteTag = new SpriteTagInfo + { + _ID = Id, + _Tag = TagName, + _Size = new Vector2(autosize, autosize), + _Pos = new Vector3[4], + _UV = tagSprites.spritegroups[0].uv + }; + + _tempSpriteTag.FillIdxAndPlaceHolder(match.Index, fillspacecnt); + + RenderTagList.Add(_tempSpriteTag); + } + } + + } + } + + + } } diff --git a/Assets/TextInlineSprite/Scripts/ParseData.cs b/Assets/TextInlineSprite/Scripts/ParseData.cs new file mode 100644 index 0000000..d46d639 --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/ParseData.cs @@ -0,0 +1,71 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; +using System; + +namespace EmojiUI +{ + + #region generic + public interface IFillData + { + string Tag { get; } + int ID { get; } + Vector3[] pos { get; set; } + Vector2[] uv { get; set; } + } + + public struct ParsedData : IEquatable + { + public int atlasID; + public string atlasTag; + + public bool Equals(ParsedData other) + { + if (this.atlasID != other.atlasID) + return false; + + if (this.atlasTag != other.atlasTag) + return false; + + return true; + } + } + #endregion + + public class SpriteTagInfo:IFillData + { + private int _Position = -1; + private const int dv = 100000; + + + public int ID { get; set; } + + public Vector3[] pos { get; set; } + + public Vector2[] uv { get; set; } + + //custom + + public Vector2 Size { get; set; } + + public string Tag { get; set; } + + public void FillIdxAndPlaceHolder(int idx, int cnt) + { + _Position = cnt * dv + idx; + } + + public int GetPlaceHolderCnt() + { + return _Position / dv; + } + + public int GetPositionIdx() + { + return _Position % dv; + } + + } +} diff --git a/Assets/TextInlineSprite/Scripts/ParseData.cs.meta b/Assets/TextInlineSprite/Scripts/ParseData.cs.meta new file mode 100644 index 0000000..1272c49 --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/ParseData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d7da5a2ca81d20d4ea5a0c911ec99ce3 +timeCreated: 1532007087 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs b/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs new file mode 100644 index 0000000..503f453 --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs @@ -0,0 +1,78 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System.Text.RegularExpressions; +using System.Text; + +namespace EmojiUI +{ + public class EmojiParser : IParser + { + private static TextGenerator _UnderlineText; + public int Hot { get; set; } + + public void DoFillMesh() + { + + } + + public void DoFillText(InlineText text, StringBuilder stringBuilder, Match match, int Index, ParsedData tagInfo) + { + + } + + public void RecordTextUpdate(InlineText text) + { + throw new System.NotImplementedException(); + } + + public bool ParsetContent(Match data, ref ParsedData parsedData) + { + + string value = data.Value; + if (!string.IsNullOrEmpty(value)) + { + int index = value.IndexOf('#'); + int atlasId = 0; + string tagKey = null; + if (index != -1) + { + string subID = value.Substring(1, index - 1); + if (subID.Length > 0 && !int.TryParse(subID, out atlasId)) + { + Debug.LogErrorFormat("{0} convert failed ", subID); + } + else if (subID.Length > 0) + { + atlasId = -1; + } + else if (subID.Length == 0) + { + atlasId = 0; + } + + tagKey = value.Substring(index + 1, value.Length - index - 2); + + parsedData.atlasID = atlasId; + parsedData.atlasTag = tagKey; + + } + else + { + tagKey = value.Substring(1, value.Length - 2); + + parsedData.atlasID = atlasId; + parsedData.atlasTag = tagKey; + + } + return true; + } + + return false; + } + + + } +} + + diff --git a/Assets/TextInlineSprite/Scripts/AutoContainer.cs.meta b/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs.meta similarity index 76% rename from Assets/TextInlineSprite/Scripts/AutoContainer.cs.meta rename to Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs.meta index 5eebec4..a823431 100644 --- a/Assets/TextInlineSprite/Scripts/AutoContainer.cs.meta +++ b/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 1e2d0e698e7d942d4b680da5027c5384 -timeCreated: 1530758038 +guid: a79681dbbe05f4f1c842c92938490a00 +timeCreated: 1531053213 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs b/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs new file mode 100644 index 0000000..63a4893 --- /dev/null +++ b/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs @@ -0,0 +1,36 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System.Text.RegularExpressions; +using System.Text; + +namespace EmojiUI +{ + public class HrefParser : IParser + { + + public int Hot { get; set; } + + public void DoFillMesh() + { + throw new System.NotImplementedException(); + } + + public void RecordTextUpdate(InlineText text) + { + throw new System.NotImplementedException(); + } + + public void DoFillText(InlineText text, StringBuilder stringBuilder, Match match, int Index, ParsedData tagInfo) + { + throw new System.NotImplementedException(); + } + + public bool ParsetContent(Match data, ref ParsedData parsedData) + { + return false; + } + + } + +} diff --git a/Assets/TextInlineSprite/Scripts/PriorityQueue.cs.meta b/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs.meta similarity index 76% rename from Assets/TextInlineSprite/Scripts/PriorityQueue.cs.meta rename to Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs.meta index ab47cdb..ac9e129 100644 --- a/Assets/TextInlineSprite/Scripts/PriorityQueue.cs.meta +++ b/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: bb748da643a7244768585668a85faed7 -timeCreated: 1530757633 +guid: 790d38974836d4678a33a26f9615d38c +timeCreated: 1531053236 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs index f85e368..024251d 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs @@ -2,17 +2,22 @@ using System.Collections.Generic; using UnityEngine; using System.Text.RegularExpressions; +using System.Text; namespace EmojiUI { - public interface IParser - { - int Hot { get; set; } + public interface IParser + { + int Hot { get; set; } - Regex regex { get; } + bool ParsetContent(Match data, ref ParsedData parsedData); - bool ParsetContent(string data); - } + void DoFillText(InlineText text, StringBuilder stringBuilder, Match match, int Index, ParsedData tagInfo); + + void DoFillMesh(); + + void RecordTextUpdate(InlineText text); + } } diff --git a/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs index 3736e89..4fccae6 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs @@ -1,40 +1,126 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +using System.Text; +using System.Text.RegularExpressions; + namespace EmojiUI { - public class ParserTransmit - { - - private static ParserTransmit _mins; - - public static ParserTransmit mIns{ - get - { - if(_mins == null) - { - _mins = new ParserTransmit(); - } - return _mins; - } - } - - private struct ParserHistory - { - - } - - public void AddParser(IParser parser) - { - - } - - public void RemoveParser(IParser parser) - { - - } - } + public class ParserTransmit + { + + private static ParserTransmit _mins; + + public static ParserTransmit mIns + { + get + { + if (_mins == null) + { + _mins = new ParserTransmit(); + } + return _mins; + } + } + + private const string palceholder = "1"; + + private const string ParsetLeft = "\\["; + + private const string ParsetRight = "\\]"; + + public static int hot = 100; + + private List parsers = new List(8); + + private Regex TagRegex = new Regex(string.Format(@"{0}(\-{{0,1}}\d{{0,}})#(.+?){1}", ParsetLeft, ParsetRight), RegexOptions.Singleline); + + private ParserTransmit() + { + //default + AddParser(new EmojiParser()); + } + + public void AddParser(IParser parser) + { + if (Application.isEditor && parsers.Contains(parser)) + { + Debug.LogErrorFormat("has contains it :{0}", parser); + } + + parsers.Add(parser); + } + + public bool RemoveParser(IParser parser) + { + return parsers.Remove(parser); + } + + public void DoParser(InlineText text, StringBuilder fillbuilder, string content) + { + if (parsers.Count > 0) + { + MatchCollection matches = TagRegex.Matches(content); + if (matches.Count > 0) + { + bool needfix = false; + int index = 0; + for (int m = 0; m < matches.Count; ++m) + { + Match matchstr = matches[m]; + + fillbuilder.Append(content.Substring(index, matchstr.Index - index)); + + if (m == matches.Count - 1) + { + fillbuilder.Append(content.Substring(matchstr.Index + matchstr.Length)); + } + + index = matchstr.Index + matchstr.Length; + + for (int i = 0; i < parsers.Count; ++i) + { + var parser = parsers[i]; + + ParsedData tagInfo = new ParsedData(); + if (parser.ParsetContent(matchstr, ref tagInfo)) + { + parser.Hot++; + + parser.DoFillText(fillbuilder, matchstr, m, tagInfo); + + if (parser.Hot > hot) + { + needfix = true; + } + } + } + } + + //reset and fix + if (needfix && this.parsers.Count >1) + this.parsers.Sort(SortList); + + // + for (int i = 0; i < parsers.Count; ++i) + { + var parser = parsers[i]; + parser.Hot = 0; + } + } + } + else + { + fillbuilder.Append(content); + } + } + + int SortList(IParser lf, IParser rt) + { + return -lf.Hot + rt.Hot; + } + } } diff --git a/Assets/TextInlineSprite/Scripts/Pool.cs b/Assets/TextInlineSprite/Scripts/Pool.cs index daf9e9c..b8e3fb4 100644 --- a/Assets/TextInlineSprite/Scripts/Pool.cs +++ b/Assets/TextInlineSprite/Scripts/Pool.cs @@ -5,100 +5,100 @@ namespace EmojiUI { - /// - /// from UGUI - /// - internal class ObjectPool where T : new() - { - private readonly Stack m_Stack = new Stack(); - private readonly UnityAction m_ActionOnGet; - private readonly UnityAction m_ActionOnRelease; - - public int countAll { get; private set; } - public int countActive { get { return countAll - countInactive; } } - public int countInactive { get { return m_Stack.Count; } } - - public ObjectPool(UnityAction actionOnGet, UnityAction actionOnRelease) - { - m_ActionOnGet = actionOnGet; - m_ActionOnRelease = actionOnRelease; - } - - public T Get() - { - T element; - if (m_Stack.Count == 0) - { - element = new T(); - countAll++; - } - else - { - element = m_Stack.Pop(); - } - if (m_ActionOnGet != null) - m_ActionOnGet(element); - return element; - } - - public void Release(T element) - { - if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element)) - Debug.LogError("Internal error. Trying to destroy object that is already released to pool."); - if (m_ActionOnRelease != null) - m_ActionOnRelease(element); - m_Stack.Push(element); - } - } + /// + /// from UGUI + /// + internal class ObjectPool where T : new() + { + private readonly Stack m_Stack = new Stack(); + private readonly UnityAction m_ActionOnGet; + private readonly UnityAction m_ActionOnRelease; - internal static class UnitMeshInfoPool - { - // Object pool to avoid allocations. - private static readonly ObjectPool s_ListPool = new ObjectPool(null, l => l.Clear()); - - public static UnitMeshInfo Get() - { - return s_ListPool.Get(); - } - - public static void Release(UnitMeshInfo toRelease) - { - s_ListPool.Release(toRelease); - } - } + public int countAll { get; private set; } + public int countActive { get { return countAll - countInactive; } } + public int countInactive { get { return m_Stack.Count; } } - internal static class ListPool - { - // Object pool to avoid allocations. - private static readonly ObjectPool> s_ListPool = new ObjectPool>(null, l => l.Clear()); - - public static List Get(int i =0) - { - List result = s_ListPool.Get(); - result.Capacity = 0; - return result; - } - - public static void Release(List toRelease) - { - s_ListPool.Release(toRelease); - } - } + public ObjectPool(UnityAction actionOnGet, UnityAction actionOnRelease) + { + m_ActionOnGet = actionOnGet; + m_ActionOnRelease = actionOnRelease; + } - internal static class QueuePool - { - // Object pool to avoid allocations. - private static readonly ObjectPool> s_ListPool = new ObjectPool>(null, l => l.Clear()); - - public static Queue Get() - { - return s_ListPool.Get(); - } - - public static void Release(Queue toRelease) - { - s_ListPool.Release(toRelease); - } - } + public T Get() + { + T element; + if (m_Stack.Count == 0) + { + element = new T(); + countAll++; + } + else + { + element = m_Stack.Pop(); + } + if (m_ActionOnGet != null) + m_ActionOnGet(element); + return element; + } + + public void Release(T element) + { + if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element)) + Debug.LogError("Internal error. Trying to destroy object that is already released to pool."); + if (m_ActionOnRelease != null) + m_ActionOnRelease(element); + m_Stack.Push(element); + } + } + + internal static class UnitMeshInfoPool + { + // Object pool to avoid allocations. + private static readonly ObjectPool s_ListPool = new ObjectPool(null, l => l.Clear()); + + public static UnitMeshInfo Get() + { + return s_ListPool.Get(); + } + + public static void Release(UnitMeshInfo toRelease) + { + s_ListPool.Release(toRelease); + } + } + + internal static class ListPool + { + // Object pool to avoid allocations. + private static readonly ObjectPool> s_ListPool = new ObjectPool>(null, l => l.Clear()); + + public static List Get(int i = 0) + { + List result = s_ListPool.Get(); + result.Capacity = 0; + return result; + } + + public static void Release(List toRelease) + { + s_ListPool.Release(toRelease); + } + } + + internal static class QueuePool + { + // Object pool to avoid allocations. + private static readonly ObjectPool> s_ListPool = new ObjectPool>(null, l => l.Clear()); + + public static Queue Get() + { + return s_ListPool.Get(); + } + + public static void Release(Queue toRelease) + { + s_ListPool.Release(toRelease); + } + } } diff --git a/Assets/TextInlineSprite/Scripts/PriorityQueue.cs b/Assets/TextInlineSprite/Scripts/PriorityQueue.cs deleted file mode 100644 index 13088de..0000000 --- a/Assets/TextInlineSprite/Scripts/PriorityQueue.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using System; - -namespace EmojiUI -{ - public class PriorityQueue - { - IComparer comparer; - T[] heap; - - public int Count { get; private set; } - - public PriorityQueue() : this(null) { } - public PriorityQueue(int capacity) : this(capacity, null) { } - public PriorityQueue(IComparer comparer) : this(16, comparer) { } - - public PriorityQueue(int capacity, IComparer comparer) - { - this.comparer = (comparer == null) ? Comparer.Default : comparer; - this.heap = new T[capacity]; - } - - public void Push(T v) - { - if (Count >= heap.Length) Array.Resize(ref heap, Count * 2); - heap[Count] = v; - SiftUp(Count++); - } - - public T Pop() - { - var v = Top(); - heap[0] = heap[--Count]; - if (Count > 0) SiftDown(0); - return v; - } - - public T Top() - { - if (Count > 0) return heap[0]; - throw new InvalidOperationException("empty queue"); - } - - void SiftUp(int n) - { - var v = heap[n]; - for (var n2 = n / 2; n > 0 && comparer.Compare(v, heap[n2]) > 0; n = n2, n2 /= 2) heap[n] = heap[n2]; - heap[n] = v; - } - - void SiftDown(int n) - { - var v = heap[n]; - for (var n2 = n * 2; n2 < Count; n = n2, n2 *= 2) - { - if (n2 + 1 < Count && comparer.Compare(heap[n2 + 1], heap[n2]) > 0) n2++; - if (comparer.Compare(v, heap[n2]) >= 0) break; - heap[n] = heap[n2]; - } - heap[n] = v; - } - } -} - - diff --git a/Assets/TextInlineSprite/Scripts/SpriteAsset.cs b/Assets/TextInlineSprite/Scripts/SpriteAsset.cs index 2dcff56..0293f37 100644 --- a/Assets/TextInlineSprite/Scripts/SpriteAsset.cs +++ b/Assets/TextInlineSprite/Scripts/SpriteAsset.cs @@ -5,24 +5,24 @@ namespace EmojiUI { - public class SpriteAsset : ScriptableObject - { + public class SpriteAsset : ScriptableObject + { - public string AssetName; - /// - /// 图集ID - /// - public int ID; - /// - /// 图片资源 - /// - public Texture texSource; - /// - /// 所有sprite信息 SpriteAssetInfor类为具体的信息类 - /// - public List listSpriteGroup = new List(); + public string AssetName; + /// + /// 图集ID + /// + public int ID; + /// + /// 图片资源 + /// + public Texture texSource; + /// + /// 所有sprite信息 SpriteAssetInfor类为具体的信息类 + /// + public List listSpriteGroup = new List(); - } + } } diff --git a/Assets/TextInlineSprite/Scripts/SpriteGraphic.cs b/Assets/TextInlineSprite/Scripts/SpriteGraphic.cs index 904d4e4..d3d7a4c 100644 --- a/Assets/TextInlineSprite/Scripts/SpriteGraphic.cs +++ b/Assets/TextInlineSprite/Scripts/SpriteGraphic.cs @@ -6,67 +6,67 @@ namespace EmojiUI { - public class SpriteGraphic : MaskableGraphic - { - IEmojiRender _Render; + public class SpriteGraphic : MaskableGraphic + { + IEmojiRender _Render; - public override Texture mainTexture - { - get - { - if(_Render != null) - { - Texture texture = _Render.getRenderTexture(this); - if(texture != null) - { - return texture; - } - } - return s_WhiteTexture; - } - } + public override Texture mainTexture + { + get + { + if (_Render != null) + { + Texture texture = _Render.getRenderTexture(this); + if (texture != null) + { + return texture; + } + } + return s_WhiteTexture; + } + } - public void Draw(IEmojiRender rd) - { - _Render = rd; - } - - protected override void Start() - { - base.Start(); - - EmojiTools.AddUnityMemory(this); - } + public void Draw(IEmojiRender rd) + { + _Render = rd; + } + + protected override void Start() + { + base.Start(); + + EmojiTools.AddUnityMemory(this); + } - protected override void OnDestroy() - { - base.OnDestroy(); + protected override void OnDestroy() + { + base.OnDestroy(); - if(_Render != null) - { - _Render.Release(this); - } - _Render = null; - EmojiTools.RemoveUnityMemory(this); - } + if (_Render != null) + { + _Render.Release(this); + } + _Render = null; + EmojiTools.RemoveUnityMemory(this); + } - protected override void OnPopulateMesh(VertexHelper vh) - { - vh.Clear(); - if (_Render != null) - { - _Render.FillMesh(this,vh); - } - } + protected override void OnPopulateMesh(VertexHelper vh) + { + vh.Clear(); + if (_Render != null) + { + _Render.FillMesh(this, vh); + } + } - void OnDrawGizmos() - { - if (_Render != null) - { - _Render.DrawGizmos(this); - } - } - } + void OnDrawGizmos() + { + if (_Render != null) + { + _Render.DrawGizmos(this); + } + } + } } From 472c2605552c706ef909c0748c796eca898498e1 Mon Sep 17 00:00:00 2001 From: cjsjy123 Date: Sat, 28 Jul 2018 13:53:09 +0800 Subject: [PATCH 06/12] back up --- Assets/Examples.meta | 9 + Assets/Examples/Scripts/ClickTest.cs | 78 +-- Assets/Plugins.meta | 9 + Assets/Plugins/Editor.meta | 9 + Assets/Plugins/Editor/JetBrains.meta | 9 + ...ider.Unity.Editor.Plugin.Repacked.dll.meta | 34 ++ Assets/TextInlineSprite.meta | 9 + Assets/TextInlineSprite/.DS_Store | Bin 6148 -> 6148 bytes Assets/TextInlineSprite/Scripts/InlineText.cs | 456 +++++++----------- Assets/TextInlineSprite/Scripts/ParseData.cs | 2 + .../Scripts/Parser/EmojiParser.cs | 83 +++- .../Scripts/Parser/HrefParser.cs | 2 +- .../Scripts/Parser/IParser.cs | 4 +- .../Scripts/Parser/ParserTransmit.cs | 7 +- 14 files changed, 370 insertions(+), 341 deletions(-) create mode 100644 Assets/Examples.meta create mode 100644 Assets/Plugins.meta create mode 100644 Assets/Plugins/Editor.meta create mode 100644 Assets/Plugins/Editor/JetBrains.meta create mode 100644 Assets/Plugins/Editor/JetBrains/JetBrains.Rider.Unity.Editor.Plugin.Repacked.dll.meta create mode 100644 Assets/TextInlineSprite.meta diff --git a/Assets/Examples.meta b/Assets/Examples.meta new file mode 100644 index 0000000..72ae9c6 --- /dev/null +++ b/Assets/Examples.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e81b20b4188478f43b69f1d7c0f321b5 +folderAsset: yes +timeCreated: 1458923026 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Examples/Scripts/ClickTest.cs b/Assets/Examples/Scripts/ClickTest.cs index d48000f..8c716ce 100644 --- a/Assets/Examples/Scripts/ClickTest.cs +++ b/Assets/Examples/Scripts/ClickTest.cs @@ -1,39 +1,39 @@ -/// ======================================================== -/// file:ClickTest.cs -/// brief: -/// author: coding2233 -/// date: -/// version:v1.0 -/// ======================================================== - -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using EmojiUI; - -public class ClickTest : MonoBehaviour -{ - - private InlineText _text; - - void Awake() - { - _text = GetComponent(); - } - - void OnEnable() - { - _text.OnHrefClick.AddListener(OnHrefClick); - } - - void OnDisable() - { - _text.OnHrefClick.RemoveListener(OnHrefClick); - } - - private void OnHrefClick(string hrefName, int id) - { - Debug.Log("点击了 " + hrefName + " id:" + id); - // Application.OpenURL("www.baidu.com"); - } -} +/// ======================================================== +/// file:ClickTest.cs +/// brief: +/// author: coding2233 +/// date: +/// version:v1.0 +/// ======================================================== + +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using EmojiUI; + +public class ClickTest : MonoBehaviour +{ + + private InlineText _text; + + void Awake() + { + _text = GetComponent(); + } + + void OnEnable() + { + + } + + void OnDisable() + { + + } + + private void OnHrefClick(string hrefName, int id) + { + Debug.Log("点击了 " + hrefName + " id:" + id); + // Application.OpenURL("www.baidu.com"); + } +} diff --git a/Assets/Plugins.meta b/Assets/Plugins.meta new file mode 100644 index 0000000..02e6847 --- /dev/null +++ b/Assets/Plugins.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7ae12929bed2d48f89836e2d71eeee9a +folderAsset: yes +timeCreated: 1531763212 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/Editor.meta b/Assets/Plugins/Editor.meta new file mode 100644 index 0000000..d10f080 --- /dev/null +++ b/Assets/Plugins/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ee5b3d955fc5049e08f3edf84e943fd1 +folderAsset: yes +timeCreated: 1531763212 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/Editor/JetBrains.meta b/Assets/Plugins/Editor/JetBrains.meta new file mode 100644 index 0000000..1d976e9 --- /dev/null +++ b/Assets/Plugins/Editor/JetBrains.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 26484119c770c4eb78f08327131c463b +folderAsset: yes +timeCreated: 1531763212 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/Editor/JetBrains/JetBrains.Rider.Unity.Editor.Plugin.Repacked.dll.meta b/Assets/Plugins/Editor/JetBrains/JetBrains.Rider.Unity.Editor.Plugin.Repacked.dll.meta new file mode 100644 index 0000000..971c721 --- /dev/null +++ b/Assets/Plugins/Editor/JetBrains/JetBrains.Rider.Unity.Editor.Plugin.Repacked.dll.meta @@ -0,0 +1,34 @@ +fileFormatVersion: 2 +guid: 47eebe181c3f3412e9444510b386875c +timeCreated: 1531763214 +licenseType: Free +PluginImporter: + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + data: + first: + Any: + second: + enabled: 0 + settings: {} + data: + first: + Editor: Editor + second: + enabled: 1 + settings: + DefaultValueInitialized: true + data: + first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TextInlineSprite.meta b/Assets/TextInlineSprite.meta new file mode 100644 index 0000000..a4e5f9a --- /dev/null +++ b/Assets/TextInlineSprite.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e27c3e51a44cadb46b180758a7fbe38e +folderAsset: yes +timeCreated: 1529059843 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TextInlineSprite/.DS_Store b/Assets/TextInlineSprite/.DS_Store index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..82414224c2dddc8ce3d35d19bf2db9be37767441 100644 GIT binary patch delta 389 zcmZoMXfc=|#>B)qF;Q%yo}wrd0|Nsi1A_nqLjgkxLvd1haY0hf#>C}}^&lB`hG2$d zh9ZVcWZC>Apv>2#f}G6a5(9%9j7-cdtZeKYoLttbL8hKLE6 zDF_jOlShCov_L5fF3QWv&r1i&Fm6md#WLAIgk>`~2R8>WkT)iNXP(S2qR0vgOohpY MBGQ`!M7A&k00F3JhyVZp delta 70 zcmZoMXfc=|#>AjHu~2NHo+1YW5HK<@2yAv_KE|>+fcX{EW_AvK4xj>{$am(+{342+ UKzW7)kiy9(Jj$D6L{=~Z044qo@Bjb+ diff --git a/Assets/TextInlineSprite/Scripts/InlineText.cs b/Assets/TextInlineSprite/Scripts/InlineText.cs index 99dca97..651beff 100644 --- a/Assets/TextInlineSprite/Scripts/InlineText.cs +++ b/Assets/TextInlineSprite/Scripts/InlineText.cs @@ -24,7 +24,6 @@ public class InlineText : Text private static UIVertex[] m_TempVerts = new UIVertex[4]; private TextGenerator _SpaceGen; - private List _listVertsPos; private InlineManager _InlineManager; //文本表情管理器 public InlineManager Manager @@ -44,122 +43,123 @@ public InlineManager Manager } List RenderTagList; - + + private string _lasttext ; private string _OutputText = ""; - private float? _pw; - - public override float preferredWidth - { - get - { - if (_pw == null) - { - //its override from uGUI Code ,but has bug? - - //var settings = GetGenerationSettings(Vector2.zero); - //return cachedTextGeneratorForLayout.GetPreferredWidth(_OutputText, settings) / pixelsPerUnit; - - //next idea - Vector2 extents = rectTransform.rect.size; - - var settings = GetGenerationSettings(extents); - cachedTextGenerator.Populate(_OutputText, settings); - - if (cachedTextGenerator.lineCount > 1) - { - float? minx = null; - float? maxx = null; - IList verts = cachedTextGenerator.verts; - int maxIndex = cachedTextGenerator.lines[1].startCharIdx; - - for (int i = 0, index = 0; i < verts.Count; i += 4, index++) - { - UIVertex v0 = verts[i]; - UIVertex v2 = verts[i + 1]; - float min = v0.position.x; - float max = v2.position.x; - - if (minx.HasValue == false) - { - minx = min; - } - else - { - minx = Mathf.Min(minx.Value, min); - } - - if (maxx.HasValue == false) - { - maxx = max; - } - else - { - maxx = Mathf.Max(maxx.Value, max); - } - - if (index > maxIndex) - { - break; - } - } - - _pw = (maxx - minx); - } - else - { - //_pw = cachedTextGeneratorForLayout.GetPreferredWidth(_OutputText, settings) / pixelsPerUnit; - float? minx = null; - float? maxx = null; - IList verts = cachedTextGenerator.verts; - int maxIndex = cachedTextGenerator.characterCount; - - for (int i = 0, index = 0; i < verts.Count; i += 4, index++) - { - UIVertex v0 = verts[i]; - UIVertex v2 = verts[i + 1]; - float min = v0.position.x; - float max = v2.position.x; - - if (minx.HasValue == false) - { - minx = min; - } - else - { - minx = Mathf.Min(minx.Value, min); - } - - if (maxx.HasValue == false) - { - maxx = max; - } - else - { - maxx = Mathf.Max(maxx.Value, max); - } - - if (index > maxIndex) - { - break; - } - } - - _pw = (maxx - minx); - } - - } - return _pw.Value; - } - } - - public override float preferredHeight - { - get - { - var settings = GetGenerationSettings(new Vector2(GetPixelAdjustedRect().size.x, 0.0f)); - return cachedTextGeneratorForLayout.GetPreferredHeight(_OutputText, settings) / pixelsPerUnit; - } - } +// private float? _pw; +// +// public override float preferredWidth +// { +// get +// { +// if (_pw == null) +// { +// //its override from uGUI Code ,but has bug? +// +// //var settings = GetGenerationSettings(Vector2.zero); +// //return cachedTextGeneratorForLayout.GetPreferredWidth(_OutputText, settings) / pixelsPerUnit; +// +// //next idea +// Vector2 extents = rectTransform.rect.size; +// +// var settings = GetGenerationSettings(extents); +// cachedTextGenerator.Populate(_OutputText, settings); +// +// if (cachedTextGenerator.lineCount > 1) +// { +// float? minx = null; +// float? maxx = null; +// IList verts = cachedTextGenerator.verts; +// int maxIndex = cachedTextGenerator.lines[1].startCharIdx; +// +// for (int i = 0, index = 0; i < verts.Count; i += 4, index++) +// { +// UIVertex v0 = verts[i]; +// UIVertex v2 = verts[i + 1]; +// float min = v0.position.x; +// float max = v2.position.x; +// +// if (minx.HasValue == false) +// { +// minx = min; +// } +// else +// { +// minx = Mathf.Min(minx.Value, min); +// } +// +// if (maxx.HasValue == false) +// { +// maxx = max; +// } +// else +// { +// maxx = Mathf.Max(maxx.Value, max); +// } +// +// if (index > maxIndex) +// { +// break; +// } +// } +// +// _pw = (maxx - minx); +// } +// else +// { +// //_pw = cachedTextGeneratorForLayout.GetPreferredWidth(_OutputText, settings) / pixelsPerUnit; +// float? minx = null; +// float? maxx = null; +// IList verts = cachedTextGenerator.verts; +// int maxIndex = cachedTextGenerator.characterCount; +// +// for (int i = 0, index = 0; i < verts.Count; i += 4, index++) +// { +// UIVertex v0 = verts[i]; +// UIVertex v2 = verts[i + 1]; +// float min = v0.position.x; +// float max = v2.position.x; +// +// if (minx.HasValue == false) +// { +// minx = min; +// } +// else +// { +// minx = Mathf.Min(minx.Value, min); +// } +// +// if (maxx.HasValue == false) +// { +// maxx = max; +// } +// else +// { +// maxx = Mathf.Max(maxx.Value, max); +// } +// +// if (index > maxIndex) +// { +// break; +// } +// } +// +// _pw = (maxx - minx); +// } +// +// } +// return _pw.Value; +// } +// } +// +// public override float preferredHeight +// { +// get +// { +// var settings = GetGenerationSettings(new Vector2(GetPixelAdjustedRect().size.x, 0.0f)); +// return cachedTextGeneratorForLayout.GetPreferredHeight(_OutputText, settings) / pixelsPerUnit; +// } +// } void OnDrawGizmos() { @@ -191,18 +191,23 @@ protected override void OnValidate() public override void SetVerticesDirty() { base.SetVerticesDirty(); - if (!Application.isPlaying || !Manager) + if (!Manager) { - _pw = null; _OutputText = m_Text; return; - } - - ParserTransmit.mIns.DoParser(this, _textBuilder, m_Text); + } + + if(m_Text != null && !m_Text.Equals(_lasttext) ) + { + ParserTransmit.mIns.DoParser(this, _textBuilder, m_Text); + + _OutputText = _textBuilder.ToString(); + _textBuilder.Length = 0; + + Debug.LogError(_OutputText); + } - _OutputText = _textBuilder.ToString(); - _textBuilder.Length = 0; - Debug.LogError(_OutputText); + Manager.Register(this); } @@ -247,28 +252,8 @@ protected override void OnPopulateMesh(VertexHelper toFill) Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y) * unitsPerPixel; roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset; toFill.Clear(); - - //ClearQuadUVs(verts); - - if (RenderTagList != null && RenderTagList.Count > 0) - { - if (_listVertsPos == null) - _listVertsPos = new List(); - else - _listVertsPos.Clear(); - } - - - int NextSkipMin = -10; - int NextSkipMax = -10; - int TagIndex = 0; - if (RenderTagList != null && RenderTagList.Count > 0) - { - var data = RenderTagList[TagIndex]; - NextSkipMin = data.GetPositionIdx(); - NextSkipMax = NextSkipMin + 4 * data.GetPlaceHolderCnt(); - } - + + if (roundingOffset != Vector2.zero) { for (int i = 0; i < vertCount; ++i) @@ -279,36 +264,8 @@ protected override void OnPopulateMesh(VertexHelper toFill) m_TempVerts[tempVertsIndex].position.x += roundingOffset.x; m_TempVerts[tempVertsIndex].position.y += roundingOffset.y; - if (NextSkipMin >= 0 && i >= NextSkipMin && i <= NextSkipMax) - { - - } - else - { - if (tempVertsIndex == 3) - toFill.AddUIVertexQuad(m_TempVerts); - } - - - if (RenderTagList != null && RenderTagList.Count > 0) - { - if (i == NextSkipMax) - { - TagIndex++; - if (RenderTagList.Count > TagIndex) - { - var data = RenderTagList[TagIndex]; - NextSkipMin = data.GetPositionIdx(); - NextSkipMax = NextSkipMin + 4 * data.GetPlaceHolderCnt(); - } - else - { - NextSkipMin = -10; - } - } - - _listVertsPos.Add(m_TempVerts[tempVertsIndex].position); - } + if (tempVertsIndex == 3) + toFill.AddUIVertexQuad(m_TempVerts); } } @@ -320,127 +277,50 @@ protected override void OnPopulateMesh(VertexHelper toFill) m_TempVerts[tempVertsIndex] = verts[i]; m_TempVerts[tempVertsIndex].position *= unitsPerPixel; - if (NextSkipMin >= 0 && i >= NextSkipMin && i <= NextSkipMax) - { - - } - else - { - if (tempVertsIndex == 3) - toFill.AddUIVertexQuad(m_TempVerts); - } - - if (RenderTagList != null && RenderTagList.Count > 0) - { - if (i == NextSkipMax) - { - TagIndex++; - if (RenderTagList.Count > TagIndex) - { - var data = RenderTagList[TagIndex]; - NextSkipMin = data.GetPositionIdx(); - NextSkipMax = NextSkipMin + 4 * data.GetPlaceHolderCnt(); - } - else - { - NextSkipMin = -10; - } - } - - _listVertsPos.Add(m_TempVerts[tempVertsIndex].position); - } + if (tempVertsIndex == 3) + toFill.AddUIVertexQuad(m_TempVerts); } } - m_DisableFontTextureRebuiltCallback = false; - needupdate = false; + m_DisableFontTextureRebuiltCallback = false; + + if(RenderTagList != null) + { + for(int i =0; i < RenderTagList.Count;++i) + RenderTagList[i].Fill(toFill); + } } - public List PopEmojiData() + internal List PopEmojiData() { return RenderTagList; - } - - - internal void FillSpriteTag(StringBuilder stringBuilder, Match match, int Index, ParsedData tagInfo) - { - int Id = tagInfo.atlasID; - string TagName = tagInfo.atlasTag; - if (Manager != null && Manager.CanRendering(Id) && Manager.CanRendering(TagName)) - { - SpriteAsset sprAsset; - SpriteInfoGroup tagSprites = Manager.FindSpriteGroup(TagName, out sprAsset); - if (tagSprites != null && tagSprites.spritegroups.Count > 0) - { - if (!Manager.isRendering(sprAsset)) - { - Manager.PushRenderAtlas(sprAsset); - } - - if (_SpaceGen == null) - { - _SpaceGen = new TextGenerator(); - } - - if (updatespace) - { - Vector2 extents = rectTransform.rect.size; - TextGenerationSettings settings = GetGenerationSettings(extents); - _SpaceGen.Populate(palceholder, settings); - updatespace = false; - } - - IList spaceverts = _SpaceGen.verts; - float spacewid = spaceverts[1].position.x - spaceverts[0].position.x; - float spaceheight = spaceverts[0].position.y - spaceverts[3].position.y; - - - float autosize = Mathf.Min(tagSprites.size, Mathf.Max(spacewid, spaceheight)); - float spacesize = Mathf.Max(spacewid, spaceheight); - - int fillspacecnt = Mathf.CeilToInt(autosize / spacesize); - - for (int i = 0; i < fillspacecnt; i++) - { - stringBuilder.Append(palceholder); - } + } - if (RenderTagList == null) - { - RenderTagList = ListPool.Get(); - } - - if (RenderTagList.Count > Index) - { - SpriteTagInfo _tempSpriteTag = RenderTagList[Index]; - _tempSpriteTag._ID = Id; - _tempSpriteTag._Tag = TagName; - _tempSpriteTag._Size = new Vector2(autosize, autosize); - _tempSpriteTag.FillIdxAndPlaceHolder(match.Index, fillspacecnt); - _tempSpriteTag._UV = tagSprites.spritegroups[0].uv; - } - else - { - SpriteTagInfo _tempSpriteTag = new SpriteTagInfo - { - _ID = Id, - _Tag = TagName, - _Size = new Vector2(autosize, autosize), - _Pos = new Vector3[4], - _UV = tagSprites.spritegroups[0].uv - }; - - _tempSpriteTag.FillIdxAndPlaceHolder(match.Index, fillspacecnt); - - RenderTagList.Add(_tempSpriteTag); - } - } - - } - } - - + internal void ClearFillData(IFillData data) + { + if(RenderTagList != null) + { + RenderTagList.Clear(); + } + } + + internal void AddFillData(IFillData data) + { + if(RenderTagList == null) + { + RenderTagList = ListPool.Get(); + } + this.RenderTagList.Add(data); + } + + internal void RemoveFillData(IFillData data) + { + if(RenderTagList != null) + { + RenderTagList.Remove(data); + } + } } } diff --git a/Assets/TextInlineSprite/Scripts/ParseData.cs b/Assets/TextInlineSprite/Scripts/ParseData.cs index d46d639..5b6259b 100644 --- a/Assets/TextInlineSprite/Scripts/ParseData.cs +++ b/Assets/TextInlineSprite/Scripts/ParseData.cs @@ -14,6 +14,8 @@ public interface IFillData int ID { get; } Vector3[] pos { get; set; } Vector2[] uv { get; set; } + + void Fill(VertexHelper filler); } public struct ParsedData : IEquatable diff --git a/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs b/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs index 503f453..8a2d843 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs @@ -16,17 +16,90 @@ public void DoFillMesh() } - public void DoFillText(InlineText text, StringBuilder stringBuilder, Match match, int Index, ParsedData tagInfo) + public void RecordTextUpdate(InlineText text) { - + throw new System.NotImplementedException(); } - public void RecordTextUpdate(InlineText text) + internal void FillSpriteTag(StringBuilder stringBuilder, Match match, int Index, ParsedData tagInfo) { - throw new System.NotImplementedException(); + int Id = tagInfo.atlasID; + string TagName = tagInfo.atlasTag; + if (Manager != null && Manager.CanRendering(Id) && Manager.CanRendering(TagName)) + { + SpriteAsset sprAsset; + SpriteInfoGroup tagSprites = Manager.FindSpriteGroup(TagName, out sprAsset); + if (tagSprites != null && tagSprites.spritegroups.Count > 0) + { + if (!Manager.isRendering(sprAsset)) + { + Manager.PushRenderAtlas(sprAsset); + } + + if (_SpaceGen == null) + { + _SpaceGen = new TextGenerator(); + } + + if (updatespace) + { + Vector2 extents = rectTransform.rect.size; + TextGenerationSettings settings = GetGenerationSettings(extents); + _SpaceGen.Populate(palceholder, settings); + updatespace = false; + } + + IList spaceverts = _SpaceGen.verts; + float spacewid = spaceverts[1].position.x - spaceverts[0].position.x; + float spaceheight = spaceverts[0].position.y - spaceverts[3].position.y; + + + float autosize = Mathf.Min(tagSprites.size, Mathf.Max(spacewid, spaceheight)); + float spacesize = Mathf.Max(spacewid, spaceheight); + + int fillspacecnt = Mathf.CeilToInt(autosize / spacesize); + + for (int i = 0; i < fillspacecnt; i++) + { + stringBuilder.Append(palceholder); + } + + if (RenderTagList == null) + { + RenderTagList = ListPool.Get(); + } + + if (RenderTagList.Count > Index) + { + SpriteTagInfo _tempSpriteTag = RenderTagList[Index]; + _tempSpriteTag._ID = Id; + _tempSpriteTag._Tag = TagName; + _tempSpriteTag._Size = new Vector2(autosize, autosize); + _tempSpriteTag.FillIdxAndPlaceHolder(match.Index, fillspacecnt); + _tempSpriteTag._UV = tagSprites.spritegroups[0].uv; + } + else + { + SpriteTagInfo _tempSpriteTag = new SpriteTagInfo + { + _ID = Id, + _Tag = TagName, + _Size = new Vector2(autosize, autosize), + _Pos = new Vector3[4], + _UV = tagSprites.spritegroups[0].uv + }; + + _tempSpriteTag.FillIdxAndPlaceHolder(match.Index, fillspacecnt); + + RenderTagList.Add(_tempSpriteTag); + } + } + + } } - public bool ParsetContent(Match data, ref ParsedData parsedData) + + public bool ParsetContent(InlineText text,StringBuilder textfiller, Match data,int matchindex) { string value = data.Value; diff --git a/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs b/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs index 63a4893..c6edd05 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs @@ -26,7 +26,7 @@ public void DoFillText(InlineText text, StringBuilder stringBuilder, Match match throw new System.NotImplementedException(); } - public bool ParsetContent(Match data, ref ParsedData parsedData) + public bool ParsetContent(InlineText text,StringBuilder textfiller, Match data,int matchindex) { return false; } diff --git a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs index 024251d..5454b53 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs @@ -10,9 +10,7 @@ public interface IParser { int Hot { get; set; } - bool ParsetContent(Match data, ref ParsedData parsedData); - - void DoFillText(InlineText text, StringBuilder stringBuilder, Match match, int Index, ParsedData tagInfo); + bool ParsetContent(InlineText text,StringBuilder textfiller, Match data,int matchindex); void DoFillMesh(); diff --git a/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs index 4fccae6..fb162cd 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs @@ -24,7 +24,7 @@ public static ParserTransmit mIns } } - private const string palceholder = "1"; + public const string palceholder = "1"; private const string ParsetLeft = "\\["; @@ -84,12 +84,9 @@ public void DoParser(InlineText text, StringBuilder fillbuilder, string content) var parser = parsers[i]; ParsedData tagInfo = new ParsedData(); - if (parser.ParsetContent(matchstr, ref tagInfo)) + if (parser.ParsetContent(text,fillbuilder,matchstr,m)) { parser.Hot++; - - parser.DoFillText(fillbuilder, matchstr, m, tagInfo); - if (parser.Hot > hot) { needfix = true; From 9fa10a35ae34620f5f4e12738d7d4a5714bedc97 Mon Sep 17 00:00:00 2001 From: cjsjy123 Date: Sat, 28 Jul 2018 19:17:22 +0800 Subject: [PATCH 07/12] meta --- Assets/Examples.meta | 9 +++++++++ Assets/TextInlineSprite.meta | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 Assets/Examples.meta create mode 100644 Assets/TextInlineSprite.meta diff --git a/Assets/Examples.meta b/Assets/Examples.meta new file mode 100644 index 0000000..72ae9c6 --- /dev/null +++ b/Assets/Examples.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e81b20b4188478f43b69f1d7c0f321b5 +folderAsset: yes +timeCreated: 1458923026 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TextInlineSprite.meta b/Assets/TextInlineSprite.meta new file mode 100644 index 0000000..a4e5f9a --- /dev/null +++ b/Assets/TextInlineSprite.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e27c3e51a44cadb46b180758a7fbe38e +folderAsset: yes +timeCreated: 1529059843 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: From 08ee40d80aa5b61f9b5a0f851935bf5dd65fe77b Mon Sep 17 00:00:00 2001 From: cjsjy123 Date: Sat, 28 Jul 2018 23:44:04 +0800 Subject: [PATCH 08/12] back up --- Assets/Plugins/Editor.meta | 9 - Assets/Plugins/Editor/JetBrains.meta | 9 - ...ider.Unity.Editor.Plugin.Repacked.dll.meta | 34 -- .../Editor/AutoSetInlineOrder.cs | 23 + .../Editor/AutoSetInlineOrder.cs.meta | 12 + .../Editor/InlineManagerEditor.cs | 166 +++---- .../TextInlineSprite/Scripts/InlineManager.cs | 396 ++++++++-------- .../Scripts/InlineManager.cs.meta | 6 +- Assets/TextInlineSprite/Scripts/InlineText.cs | 423 +++++++++--------- .../Scripts/InlineText.cs.meta | 4 +- Assets/TextInlineSprite/Scripts/ParseData.cs | 60 +-- .../Scripts/Parser/EmojiParser.cs | 88 ++-- .../Scripts/Parser/HrefParser.cs | 19 +- .../Scripts/Parser/IParser.cs | 3 - .../Scripts/Parser/ParserTransmit.cs | 42 +- 15 files changed, 634 insertions(+), 660 deletions(-) delete mode 100644 Assets/Plugins/Editor.meta delete mode 100644 Assets/Plugins/Editor/JetBrains.meta delete mode 100644 Assets/Plugins/Editor/JetBrains/JetBrains.Rider.Unity.Editor.Plugin.Repacked.dll.meta create mode 100644 Assets/TextInlineSprite/Editor/AutoSetInlineOrder.cs create mode 100644 Assets/TextInlineSprite/Editor/AutoSetInlineOrder.cs.meta diff --git a/Assets/Plugins/Editor.meta b/Assets/Plugins/Editor.meta deleted file mode 100644 index d10f080..0000000 --- a/Assets/Plugins/Editor.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: ee5b3d955fc5049e08f3edf84e943fd1 -folderAsset: yes -timeCreated: 1531763212 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/Editor/JetBrains.meta b/Assets/Plugins/Editor/JetBrains.meta deleted file mode 100644 index 1d976e9..0000000 --- a/Assets/Plugins/Editor/JetBrains.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 26484119c770c4eb78f08327131c463b -folderAsset: yes -timeCreated: 1531763212 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/Editor/JetBrains/JetBrains.Rider.Unity.Editor.Plugin.Repacked.dll.meta b/Assets/Plugins/Editor/JetBrains/JetBrains.Rider.Unity.Editor.Plugin.Repacked.dll.meta deleted file mode 100644 index 971c721..0000000 --- a/Assets/Plugins/Editor/JetBrains/JetBrains.Rider.Unity.Editor.Plugin.Repacked.dll.meta +++ /dev/null @@ -1,34 +0,0 @@ -fileFormatVersion: 2 -guid: 47eebe181c3f3412e9444510b386875c -timeCreated: 1531763214 -licenseType: Free -PluginImporter: - serializedVersion: 2 - iconMap: {} - executionOrder: {} - isPreloaded: 0 - isOverridable: 0 - platformData: - data: - first: - Any: - second: - enabled: 0 - settings: {} - data: - first: - Editor: Editor - second: - enabled: 1 - settings: - DefaultValueInitialized: true - data: - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/TextInlineSprite/Editor/AutoSetInlineOrder.cs b/Assets/TextInlineSprite/Editor/AutoSetInlineOrder.cs new file mode 100644 index 0000000..d185ff1 --- /dev/null +++ b/Assets/TextInlineSprite/Editor/AutoSetInlineOrder.cs @@ -0,0 +1,23 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +[InitializeOnLoad] +public class AutoSetInlineOrder : MonoBehaviour { + + +#if UNITY_EDITOR + static AutoSetInlineOrder() + { + + foreach (MonoScript monoScript in MonoImporter.GetAllRuntimeMonoScripts()) + { + if (monoScript.name == "InlineManager") + { + if(MonoImporter.GetExecutionOrder(monoScript) != 10) + MonoImporter.SetExecutionOrder(monoScript, 10); + } + } + } +#endif +} diff --git a/Assets/TextInlineSprite/Editor/AutoSetInlineOrder.cs.meta b/Assets/TextInlineSprite/Editor/AutoSetInlineOrder.cs.meta new file mode 100644 index 0000000..d0956f7 --- /dev/null +++ b/Assets/TextInlineSprite/Editor/AutoSetInlineOrder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 801634a8067207043a5e06105ee77355 +timeCreated: 1532788130 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TextInlineSprite/Editor/InlineManagerEditor.cs b/Assets/TextInlineSprite/Editor/InlineManagerEditor.cs index a355b0c..a474cd1 100644 --- a/Assets/TextInlineSprite/Editor/InlineManagerEditor.cs +++ b/Assets/TextInlineSprite/Editor/InlineManagerEditor.cs @@ -3,46 +3,46 @@ using UnityEngine; using UnityEditor; -namespace EmojiUI -{ - [CustomEditor(typeof(InlineManager),true)] - [CanEditMultipleObjects] - public class InlineManagerEditor : Editor - { - SerializedProperty m_Script; - - private bool foldout =true; - - private Dictionary assetDic = new Dictionary(); - - protected virtual void OnEnable() - { - m_Script = serializedObject.FindProperty("m_Script"); - } - - public override void OnInspectorGUI() - { - InlineManager manager = target as InlineManager; - EditorGUILayout.PropertyField(m_Script); - - EditorGUILayout.Space(); - serializedObject.Update(); +namespace EmojiUI +{ + [CustomEditor(typeof(InlineManager),true)] + [CanEditMultipleObjects] + public class InlineManagerEditor : Editor + { + SerializedProperty m_Script; + + private bool foldout =true; + + private Dictionary assetDic = new Dictionary(); + + protected virtual void OnEnable() + { + m_Script = serializedObject.FindProperty("m_Script"); + } + + public override void OnInspectorGUI() + { + InlineManager manager = target as InlineManager; + EditorGUILayout.PropertyField(m_Script); + + EditorGUILayout.Space(); + serializedObject.Update(); manager.OpenDebug =EditorGUILayout.Toggle("Debug", manager.OpenDebug); - manager.renderType = (EmojiRenderType)EditorGUILayout.EnumPopup("Rendetype", manager.renderType); - manager.AnimationSpeed = EditorGUILayout.Slider("AnimationSpeed", manager.AnimationSpeed, 0, 100); - - foldout = EditorGUILayout.Foldout(foldout, "prepared:"+manager.PreparedAtlas.Count); - if(foldout) - { - EditorGUI.indentLevel++; - for (int i =0; i < manager.PreparedAtlas.Count;++i) - { - string resName = manager.PreparedAtlas[i]; - SpriteAsset asset = null; - if(!string.IsNullOrEmpty(resName)) - { - if (!assetDic.ContainsKey(resName)) + manager.RenderType = (EmojiRenderType)EditorGUILayout.EnumPopup("Rendetype", manager.RenderType); + manager.AnimationSpeed = EditorGUILayout.Slider("AnimationSpeed", manager.AnimationSpeed, 0, 100); + + foldout = EditorGUILayout.Foldout(foldout, "prepared:"+manager.PreparedAtlas.Count); + if(foldout) + { + EditorGUI.indentLevel++; + for (int i =0; i < manager.PreparedAtlas.Count;++i) + { + string resName = manager.PreparedAtlas[i]; + SpriteAsset asset = null; + if(!string.IsNullOrEmpty(resName)) + { + if (!assetDic.ContainsKey(resName)) { string fixname = System.IO.Path.GetFileNameWithoutExtension(resName); @@ -56,51 +56,51 @@ public override void OnInspectorGUI() asset = assetDic[resName] = AssetDatabase.LoadAssetAtPath(path); break; } - } - } - else - { - asset = assetDic[resName]; - } - } - - SpriteAsset newasset = (SpriteAsset)EditorGUILayout.ObjectField(i.ToString(), asset, typeof(SpriteAsset),false); - if(newasset != asset) - { - if(newasset == null) - { - manager.PreparedAtlas[i] = ""; - } - else - { - manager.PreparedAtlas[i] = System.IO.Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(newasset)); - assetDic[manager.PreparedAtlas[i]] = newasset; - } - EditorUtility.SetDirty(manager); - } - - } - - EditorGUI.indentLevel--; - - EditorGUILayout.BeginHorizontal(); - - if(GUILayout.Button("add",GUILayout.Width(100))) - { - manager.PreparedAtlas.Add(""); - } - - if (GUILayout.Button("remove", GUILayout.Width(100))) - { - if (manager.PreparedAtlas.Count > 0) - manager.PreparedAtlas.RemoveAt(manager.PreparedAtlas.Count - 1); - } - EditorGUILayout.EndHorizontal(); - } - - serializedObject.ApplyModifiedProperties(); - } - } + } + } + else + { + asset = assetDic[resName]; + } + } + + SpriteAsset newasset = (SpriteAsset)EditorGUILayout.ObjectField(i.ToString(), asset, typeof(SpriteAsset),false); + if(newasset != asset) + { + if(newasset == null) + { + manager.PreparedAtlas[i] = ""; + } + else + { + manager.PreparedAtlas[i] = System.IO.Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(newasset)); + assetDic[manager.PreparedAtlas[i]] = newasset; + } + EditorUtility.SetDirty(manager); + } + + } + + EditorGUI.indentLevel--; + + EditorGUILayout.BeginHorizontal(); + + if(GUILayout.Button("add",GUILayout.Width(100))) + { + manager.PreparedAtlas.Add(""); + } + + if (GUILayout.Button("remove", GUILayout.Width(100))) + { + if (manager.PreparedAtlas.Count > 0) + manager.PreparedAtlas.RemoveAt(manager.PreparedAtlas.Count - 1); + } + EditorGUILayout.EndHorizontal(); + } + + serializedObject.ApplyModifiedProperties(); + } + } } diff --git a/Assets/TextInlineSprite/Scripts/InlineManager.cs b/Assets/TextInlineSprite/Scripts/InlineManager.cs index 1b23aa6..0b26f03 100644 --- a/Assets/TextInlineSprite/Scripts/InlineManager.cs +++ b/Assets/TextInlineSprite/Scripts/InlineManager.cs @@ -1,33 +1,27 @@ -/// ======================================================== -/// file:InlineManager.cs -/// brief: -/// author: coding2233 -/// date: -/// version:v1.0 -/// ======================================================== - -using System.Collections; -using System.Collections.Generic; -using UnityEngine; + +using System.Collections; +using System.Collections.Generic; +using UnityEngine; using System; -#if UNITY_EDITOR +#if UNITY_EDITOR using UnityEditor; -#endif +#endif -namespace EmojiUI -{ - [DefaultExecutionOrder(-99999)] +namespace EmojiUI +{ public class InlineManager : MonoBehaviour { - private List sharedAtlases = new List(); + private readonly List _sharedAtlases = new List(); - private Dictionary alltags = new Dictionary(); + private readonly Dictionary _alltags = new Dictionary(); - private IEmojiRender _Render; + private IEmojiRender _render; public List PreparedAtlas = new List(); + + public bool HasInit { get; private set; } -#if UNITY_EDITOR +#if UNITY_EDITOR [SerializeField] private bool _openDebug; public bool OpenDebug @@ -56,10 +50,10 @@ public bool OpenDebug } } - private List unityallAtlases; + private List _unityallAtlases; - private List lostAssets; -#endif + private List _lostAssets; +#endif [SerializeField] private float _animationspeed = 5f; public float AnimationSpeed @@ -70,9 +64,9 @@ public float AnimationSpeed } set { - if (_Render != null) + if (_render != null) { - _Render.Speed = value; + _render.Speed = value; } _animationspeed = value; } @@ -80,7 +74,7 @@ public float AnimationSpeed [SerializeField] private EmojiRenderType _renderType = EmojiRenderType.RenderUnit; - public EmojiRenderType renderType + public EmojiRenderType RenderType { get { @@ -96,14 +90,15 @@ public EmojiRenderType renderType } } + void Awake() { -#if UNITY_EDITOR +#if UNITY_EDITOR if (OpenDebug) { EmojiTools.StartDumpGUI(); } -#endif +#endif EmojiTools.BeginSample("Emoji_Init"); Initialize(); @@ -114,25 +109,26 @@ void Awake() void Initialize() { -#if UNITY_EDITOR + HasInit = true; +#if UNITY_EDITOR string[] result = AssetDatabase.FindAssets(string.Format("t:{0}", typeof(SpriteAsset).FullName)); - if (result.Length > 0 && unityallAtlases == null) + if (result.Length > 0 && _unityallAtlases == null) { - unityallAtlases = new List(result.Length); + _unityallAtlases = new List(result.Length); for (int i = 0; i < result.Length; ++i) { string path = AssetDatabase.GUIDToAssetPath(result[i]); SpriteAsset asset = AssetDatabase.LoadAssetAtPath(path); if (asset) { - unityallAtlases.Add(asset); + _unityallAtlases.Add(asset); } } } Debug.LogFormat("find :{0} atlas resource", result.Length); Debug.LogWarning("if your asset not in the resources please override InstantiateSpriteAsset"); -#endif +#endif EmojiTools.BeginSample("Emoji_Init"); @@ -151,31 +147,31 @@ void Initialize() void LateUpdate() { EmojiTools.BeginSample("Emoji_LateUpdate"); - if (_Render != null) + if (_render != null) { - _Render.LateUpdate(); + _render.LateUpdate(); } EmojiTools.EndSample(); } private void OnDestroy() { -#if UNITY_EDITOR - if (lostAssets != null) +#if UNITY_EDITOR + if (_lostAssets != null) { - for (int i = 0; i < lostAssets.Count; ++i) + for (int i = 0; i < _lostAssets.Count; ++i) { - string asset = lostAssets[i]; + string asset = _lostAssets[i]; Debug.LogError(string.Format("not prepred atlasAsset named :{0}", asset)); } } -#endif - if (_Render != null) +#endif + if (_render != null) { - _Render.Dispose(); + _render.Dispose(); } - _Render = null; + _render = null; EmojiTools.RemoveUnityMemory(this); } @@ -186,17 +182,17 @@ protected virtual SpriteAsset InstantiateSpriteAsset(string filepath) void InitRender() { - if (_Render == null || _Render.renderType != renderType) + if (_render == null || _render.renderType != RenderType) { - if (renderType == EmojiRenderType.RenderGroup) + if (RenderType == EmojiRenderType.RenderGroup) { EmojiRenderGroup newRender = new EmojiRenderGroup(this); newRender.Speed = AnimationSpeed; - if (_Render != null) + if (_render != null) { - List list = _Render.GetAllRenders(); + List list = _render.GetAllRenders(); if (list != null) { for (int i = 0; i < list.Count; ++i) @@ -207,7 +203,7 @@ void InitRender() } } - List atlaslist = _Render.GetAllRenderAtlas(); + List atlaslist = _render.GetAllRenderAtlas(); if (atlaslist != null) { for (int i = 0; i < atlaslist.Count; ++i) @@ -217,20 +213,20 @@ void InitRender() newRender.PrepareAtlas(atlas); } } - _Render.Dispose(); + _render.Dispose(); } - _Render = newRender; + _render = newRender; } - else if (renderType == EmojiRenderType.RenderUnit) + else if (RenderType == EmojiRenderType.RenderUnit) { UnitRender newRender = new UnitRender(this); newRender.Speed = AnimationSpeed; - if (_Render != null) + if (_render != null) { - List list = _Render.GetAllRenders(); + List list = _render.GetAllRenders(); if (list != null) { for (int i = 0; i < list.Count; ++i) @@ -241,7 +237,7 @@ void InitRender() } } - List atlaslist = _Render.GetAllRenderAtlas(); + List atlaslist = _render.GetAllRenderAtlas(); if (atlaslist != null) { for (int i = 0; i < atlaslist.Count; ++i) @@ -252,10 +248,10 @@ void InitRender() } } - _Render.Dispose(); + _render.Dispose(); } - _Render = newRender; + _render = newRender; } else { @@ -279,56 +275,56 @@ void PreLoad() void RebuildTagList() { EmojiTools.BeginSample("Emoji_rebuildTags"); - alltags.Clear(); -#if UNITY_EDITOR - if (unityallAtlases != null) + _alltags.Clear(); +#if UNITY_EDITOR + if (_unityallAtlases != null) { - for (int i = 0; i < unityallAtlases.Count; ++i) + for (int i = 0; i < _unityallAtlases.Count; ++i) { - SpriteAsset asset = unityallAtlases[i]; + SpriteAsset asset = _unityallAtlases[i]; for (int j = 0; j < asset.listSpriteGroup.Count; ++j) { SpriteInfoGroup infogroup = asset.listSpriteGroup[j]; SpriteInfoGroup group; - if (alltags.TryGetValue(infogroup.tag, out group)) + if (_alltags.TryGetValue(infogroup.tag, out group)) { Debug.LogErrorFormat("already exist :{0} ", infogroup.tag); } - alltags[infogroup.tag] = infogroup; + _alltags[infogroup.tag] = infogroup; } } } -#else - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - for (int j = 0; j < asset.listSpriteGroup.Count; ++j) - { - SpriteInfoGroup infogroup = asset.listSpriteGroup[j]; - SpriteInfoGroup group; - if (alltags.TryGetValue(infogroup.tag, out group)) - { - Debug.LogErrorFormat("already exist :{0} ", infogroup.tag); - } - - alltags[infogroup.tag] = infogroup; - } - } -#endif +#else + for (int i = 0; i < sharedAtlases.Count; ++i) + { + SpriteAsset asset = sharedAtlases[i]; + for (int j = 0; j < asset.listSpriteGroup.Count; ++j) + { + SpriteInfoGroup infogroup = asset.listSpriteGroup[j]; + SpriteInfoGroup group; + if (alltags.TryGetValue(infogroup.tag, out group)) + { + Debug.LogErrorFormat("already exist :{0} ", infogroup.tag); + } + + alltags[infogroup.tag] = infogroup; + } + } +#endif EmojiTools.EndSample(); } public IEmojiRender Register(InlineText _key) { EmojiTools.BeginSample("Emoji_Register"); - if (_Render != null) + if (_render != null) { - if (_Render.TryRendering(_key)) + if (_render.TryRendering(_key)) { EmojiTools.EndSample(); - return _Render; + return _render; } } EmojiTools.EndSample(); @@ -336,17 +332,17 @@ public IEmojiRender Register(InlineText _key) } - /// - /// 移除文本 - /// - /// - /// + /// + /// 移除文本 + /// + /// + /// public void UnRegister(InlineText _key) { EmojiTools.BeginSample("Emoji_UnRegister"); - if (_Render != null) + if (_render != null) { - _Render.DisRendering(_key); + _render.DisRendering(_key); } EmojiTools.EndSample(); } @@ -362,38 +358,38 @@ public void ForceRebuild() EmojiTools.EndSample(); } - /// - /// 清除所有的精灵 - /// + /// + /// 清除所有的精灵 + /// public void ClearAllSprites() { EmojiTools.BeginSample("Emoji_ClearAll"); - if (_Render != null) + if (_render != null) { - _Render.Clear(); + _render.Clear(); } EmojiTools.EndSample(); } public bool isRendering(SpriteAsset _spriteAsset) { - return _spriteAsset != null && _Render != null && _Render.isRendingAtlas(_spriteAsset); + return _spriteAsset != null && _render != null && _render.isRendingAtlas(_spriteAsset); } public bool CanRendering(string tagName) - { - return alltags != null && alltags.ContainsKey(tagName); + { + return _alltags != null && _alltags.ContainsKey(tagName); } public bool CanRendering(int atlasId) { -#if UNITY_EDITOR - if (unityallAtlases != null) +#if UNITY_EDITOR + if (_unityallAtlases != null) { - for (int i = 0; i < unityallAtlases.Count; ++i) + for (int i = 0; i < _unityallAtlases.Count; ++i) { - SpriteAsset asset = unityallAtlases[i]; + SpriteAsset asset = _unityallAtlases[i]; if (asset.ID == atlasId) { return true; @@ -402,17 +398,17 @@ public bool CanRendering(int atlasId) } return false; -#else - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - if (asset.ID == atlasId) - { - return true; - } - } - return false; -#endif +#else + for (int i = 0; i < sharedAtlases.Count; ++i) + { + SpriteAsset asset = sharedAtlases[i]; + if (asset.ID == atlasId) + { + return true; + } + } + return false; +#endif } public void PushRenderAtlas(SpriteAsset _spriteAsset) @@ -420,11 +416,11 @@ public void PushRenderAtlas(SpriteAsset _spriteAsset) EmojiTools.BeginSample("Emoji_PushRenderAtlas"); if (!isRendering(_spriteAsset) && _spriteAsset != null) { - _Render.PrepareAtlas(_spriteAsset); + _render.PrepareAtlas(_spriteAsset); - if (!sharedAtlases.Contains(_spriteAsset)) + if (!_sharedAtlases.Contains(_spriteAsset)) { - sharedAtlases.Add(_spriteAsset); + _sharedAtlases.Add(_spriteAsset); } } EmojiTools.EndSample(); @@ -433,16 +429,16 @@ public void PushRenderAtlas(SpriteAsset _spriteAsset) public SpriteInfoGroup FindSpriteGroup(string TagName, out SpriteAsset resultatlas) { EmojiTools.BeginSample("Emoji_FindSpriteGroup"); -#if UNITY_EDITOR +#if UNITY_EDITOR resultatlas = null; SpriteInfoGroup result = null; - if (unityallAtlases != null) + if (_unityallAtlases != null) { - for (int i = 0; i < unityallAtlases.Count; ++i) + for (int i = 0; i < _unityallAtlases.Count; ++i) { - SpriteAsset asset = unityallAtlases[i]; + SpriteAsset asset = _unityallAtlases[i]; for (int j = 0; j < asset.listSpriteGroup.Count; ++j) { SpriteInfoGroup group = asset.listSpriteGroup[j]; @@ -456,52 +452,52 @@ public SpriteInfoGroup FindSpriteGroup(string TagName, out SpriteAsset resultatl } } - if (lostAssets == null) - lostAssets = new List(); + if (_lostAssets == null) + _lostAssets = new List(); if (resultatlas != null && !PreparedAtlas.Contains(resultatlas.AssetName)) { - if (!lostAssets.Contains(resultatlas.AssetName)) - lostAssets.Add(resultatlas.AssetName); + if (!_lostAssets.Contains(resultatlas.AssetName)) + _lostAssets.Add(resultatlas.AssetName); } EmojiTools.EndSample(); return result; -#else - resultatlas = null; - - SpriteInfoGroup result = null; - if(sharedAtlases != null) - { - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - for (int j = 0; j < asset.listSpriteGroup.Count; ++j) - { - SpriteInfoGroup group = asset.listSpriteGroup[j]; - if (group.tag.Equals(TagName)) - { - result = group; - resultatlas = asset; - break; - } - } - } - } - EmojiTools.EndSample(); - return result; -#endif +#else + resultatlas = null; + + SpriteInfoGroup result = null; + if(sharedAtlases != null) + { + for (int i = 0; i < sharedAtlases.Count; ++i) + { + SpriteAsset asset = sharedAtlases[i]; + for (int j = 0; j < asset.listSpriteGroup.Count; ++j) + { + SpriteInfoGroup group = asset.listSpriteGroup[j]; + if (group.tag.Equals(TagName)) + { + result = group; + resultatlas = asset; + break; + } + } + } + } + EmojiTools.EndSample(); + return result; +#endif } public SpriteAsset FindAtlas(int atlasID) { EmojiTools.BeginSample("Emoji_FindAtlas"); -#if UNITY_EDITOR +#if UNITY_EDITOR SpriteAsset result = null; - if (unityallAtlases != null) + if (_unityallAtlases != null) { - for (int i = 0; i < unityallAtlases.Count; ++i) + for (int i = 0; i < _unityallAtlases.Count; ++i) { - SpriteAsset asset = unityallAtlases[i]; + SpriteAsset asset = _unityallAtlases[i]; if (asset.ID.Equals(atlasID)) { result = asset; @@ -510,42 +506,42 @@ public SpriteAsset FindAtlas(int atlasID) } } - if (lostAssets == null) - lostAssets = new List(); + if (_lostAssets == null) + _lostAssets = new List(); if (result != null && !PreparedAtlas.Contains(result.AssetName)) { - if (!lostAssets.Contains(result.AssetName)) - lostAssets.Add(result.AssetName); + if (!_lostAssets.Contains(result.AssetName)) + _lostAssets.Add(result.AssetName); } EmojiTools.EndSample(); return result; -#else - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - if (asset.ID.Equals(atlasID)) - { - EmojiTools.EndSample(); - return asset; - } - } - EmojiTools.EndSample(); - return null; -#endif +#else + for (int i = 0; i < sharedAtlases.Count; ++i) + { + SpriteAsset asset = sharedAtlases[i]; + if (asset.ID.Equals(atlasID)) + { + EmojiTools.EndSample(); + return asset; + } + } + EmojiTools.EndSample(); + return null; +#endif } public SpriteAsset FindAtlas(string atlasname) { EmojiTools.BeginSample("FindAtlas"); -#if UNITY_EDITOR +#if UNITY_EDITOR SpriteAsset result = null; - if (unityallAtlases != null) + if (_unityallAtlases != null) { - for (int i = 0; i < unityallAtlases.Count; ++i) + for (int i = 0; i < _unityallAtlases.Count; ++i) { - SpriteAsset asset = unityallAtlases[i]; + SpriteAsset asset = _unityallAtlases[i]; if (asset.AssetName.Equals(atlasname)) { result = asset; @@ -554,38 +550,38 @@ public SpriteAsset FindAtlas(string atlasname) } } - if (lostAssets == null) - lostAssets = new List(); + if (_lostAssets == null) + _lostAssets = new List(); if (!PreparedAtlas.Contains(atlasname)) { - if (!lostAssets.Contains(atlasname)) - lostAssets.Add(atlasname); + if (!_lostAssets.Contains(atlasname)) + _lostAssets.Add(atlasname); } EmojiTools.EndSample(); return result; -#else - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - if (asset.AssetName.Equals(atlasname)) - { - EmojiTools.EndSample(); - return asset; - } - } - - SpriteAsset newasset = InstantiateSpriteAsset(atlasname); - if(newasset != null) - { - sharedAtlases.Add(newasset); - } - EmojiTools.EndSample(); - return newasset; -#endif +#else + for (int i = 0; i < sharedAtlases.Count; ++i) + { + SpriteAsset asset = sharedAtlases[i]; + if (asset.AssetName.Equals(atlasname)) + { + EmojiTools.EndSample(); + return asset; + } + } + + SpriteAsset newasset = InstantiateSpriteAsset(atlasname); + if(newasset != null) + { + sharedAtlases.Add(newasset); + } + EmojiTools.EndSample(); + return newasset; +#endif } - } -} - - + } +} + + diff --git a/Assets/TextInlineSprite/Scripts/InlineManager.cs.meta b/Assets/TextInlineSprite/Scripts/InlineManager.cs.meta index be0829f..355a033 100644 --- a/Assets/TextInlineSprite/Scripts/InlineManager.cs.meta +++ b/Assets/TextInlineSprite/Scripts/InlineManager.cs.meta @@ -1,11 +1,11 @@ fileFormatVersion: 2 guid: 0ae7019e071d5fe4e9d442887a3ac0de -timeCreated: 1498308655 -licenseType: Free +timeCreated: 1532788409 +licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] - executionOrder: 0 + executionOrder: 10 icon: {instanceID: 0} userData: assetBundleName: diff --git a/Assets/TextInlineSprite/Scripts/InlineText.cs b/Assets/TextInlineSprite/Scripts/InlineText.cs index 651beff..90afbba 100644 --- a/Assets/TextInlineSprite/Scripts/InlineText.cs +++ b/Assets/TextInlineSprite/Scripts/InlineText.cs @@ -1,27 +1,28 @@ -/// ======================================================== -/// file:InlineText.cs -/// brief: -/// author: coding2233 -/// date: -/// version:v1.0 -/// ======================================================== - -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; -using System.Text.RegularExpressions; -using System.Text; -using UnityEngine.EventSystems; -using UnityEngine.Events; -using System; - -namespace EmojiUI +/// ======================================================== +/// file:InlineText.cs +/// brief: +/// author: coding2233 +/// date: +/// version:v1.0 +/// ======================================================== + +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; +using System.Text.RegularExpressions; +using System.Text; +using UnityEngine.EventSystems; +using UnityEngine.Events; +using System; + +namespace EmojiUI { public class InlineText : Text { private static StringBuilder _textBuilder = new StringBuilder(); private static UIVertex[] m_TempVerts = new UIVertex[4]; + private static UIVertex[] m_TagVerts = new UIVertex[4]; private TextGenerator _SpaceGen; private InlineManager _InlineManager; @@ -42,124 +43,9 @@ public InlineManager Manager } } - List RenderTagList; - + List _renderTagList; private string _lasttext ; - private string _OutputText = ""; -// private float? _pw; -// -// public override float preferredWidth -// { -// get -// { -// if (_pw == null) -// { -// //its override from uGUI Code ,but has bug? -// -// //var settings = GetGenerationSettings(Vector2.zero); -// //return cachedTextGeneratorForLayout.GetPreferredWidth(_OutputText, settings) / pixelsPerUnit; -// -// //next idea -// Vector2 extents = rectTransform.rect.size; -// -// var settings = GetGenerationSettings(extents); -// cachedTextGenerator.Populate(_OutputText, settings); -// -// if (cachedTextGenerator.lineCount > 1) -// { -// float? minx = null; -// float? maxx = null; -// IList verts = cachedTextGenerator.verts; -// int maxIndex = cachedTextGenerator.lines[1].startCharIdx; -// -// for (int i = 0, index = 0; i < verts.Count; i += 4, index++) -// { -// UIVertex v0 = verts[i]; -// UIVertex v2 = verts[i + 1]; -// float min = v0.position.x; -// float max = v2.position.x; -// -// if (minx.HasValue == false) -// { -// minx = min; -// } -// else -// { -// minx = Mathf.Min(minx.Value, min); -// } -// -// if (maxx.HasValue == false) -// { -// maxx = max; -// } -// else -// { -// maxx = Mathf.Max(maxx.Value, max); -// } -// -// if (index > maxIndex) -// { -// break; -// } -// } -// -// _pw = (maxx - minx); -// } -// else -// { -// //_pw = cachedTextGeneratorForLayout.GetPreferredWidth(_OutputText, settings) / pixelsPerUnit; -// float? minx = null; -// float? maxx = null; -// IList verts = cachedTextGenerator.verts; -// int maxIndex = cachedTextGenerator.characterCount; -// -// for (int i = 0, index = 0; i < verts.Count; i += 4, index++) -// { -// UIVertex v0 = verts[i]; -// UIVertex v2 = verts[i + 1]; -// float min = v0.position.x; -// float max = v2.position.x; -// -// if (minx.HasValue == false) -// { -// minx = min; -// } -// else -// { -// minx = Mathf.Min(minx.Value, min); -// } -// -// if (maxx.HasValue == false) -// { -// maxx = max; -// } -// else -// { -// maxx = Mathf.Max(maxx.Value, max); -// } -// -// if (index > maxIndex) -// { -// break; -// } -// } -// -// _pw = (maxx - minx); -// } -// -// } -// return _pw.Value; -// } -// } -// -// public override float preferredHeight -// { -// get -// { -// var settings = GetGenerationSettings(new Vector2(GetPixelAdjustedRect().size.x, 0.0f)); -// return cachedTextGeneratorForLayout.GetPreferredHeight(_OutputText, settings) / pixelsPerUnit; -// } -// } + private string _outputText = ""; void OnDrawGizmos() { @@ -181,44 +67,71 @@ protected override void Start() EmojiTools.AddUnityMemory(this); } -#if UNITY_EDITOR - protected override void OnValidate() +#if UNITY_EDITOR + protected override void OnValidate() { //do nothing } -#endif +#endif public override void SetVerticesDirty() { base.SetVerticesDirty(); - if (!Manager) + if (Application.isPlaying) { - _OutputText = m_Text; - return; - } - - if(m_Text != null && !m_Text.Equals(_lasttext) ) - { - ParserTransmit.mIns.DoParser(this, _textBuilder, m_Text); - - _OutputText = _textBuilder.ToString(); - _textBuilder.Length = 0; - - Debug.LogError(_OutputText); - } - - Manager.Register(this); + if (!Manager) + { + _outputText = m_Text; + return; + } + else if(Manager.HasInit) + { + DoUpdateEmoji(); + } + else + { + StartCoroutine(WaitManagerInited()); + } + + + } + } + + IEnumerator WaitManagerInited() + { + while (Manager != null && !Manager.HasInit) + { + yield return null; + } + DoUpdateEmoji(); + } + + void DoUpdateEmoji() + { + if(m_Text != null && !m_Text.Equals(_lasttext) ) + { + ClearFillData(); + _lasttext = m_Text; + ParserTransmit.mIns.DoParse(this, _textBuilder, m_Text); + + _outputText = _textBuilder.ToString(); + _textBuilder.Length = 0; + + Debug.LogError(_outputText); + } + + } protected override void OnDestroy() { base.OnDestroy(); - if (RenderTagList != null) + if (_renderTagList != null) { - ListPool.Release(RenderTagList); - RenderTagList = null; + ListPool.Release(_renderTagList); + _renderTagList = null; } if (Manager) @@ -242,7 +155,7 @@ protected override void OnPopulateMesh(VertexHelper toFill) Vector2 extents = rectTransform.rect.size; var settings = GetGenerationSettings(extents); - cachedTextGenerator.PopulateWithErrors(_OutputText, settings, gameObject); + cachedTextGenerator.PopulateWithErrors(_outputText, settings, gameObject); // Apply the offset to the vertices IList verts = cachedTextGenerator.verts; @@ -252,8 +165,27 @@ protected override void OnPopulateMesh(VertexHelper toFill) Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y) * unitsPerPixel; roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset; toFill.Clear(); - - + + + int nextfilldata = -1; + int fillindex = -1; + int startfilldata = -1; + + if (_renderTagList != null && _renderTagList.Count >0) + { + var data = _renderTagList[0]; + nextfilldata = data.GetPositionIdx() ; + //at least one + startfilldata = nextfilldata - (data.GetFillCnt()-1) * 4-3; + fillindex = 0; + + Manager.Register(this); + } + else + { + Manager.UnRegister(this); + } + if (roundingOffset != Vector2.zero) { for (int i = 0; i < vertCount; ++i) @@ -264,9 +196,40 @@ protected override void OnPopulateMesh(VertexHelper toFill) m_TempVerts[tempVertsIndex].position.x += roundingOffset.x; m_TempVerts[tempVertsIndex].position.y += roundingOffset.y; - if (tempVertsIndex == 3) - toFill.AddUIVertexQuad(m_TempVerts); + //first + if (startfilldata >= 0 && i == startfilldata) + { + m_TagVerts[0] = m_TempVerts[tempVertsIndex]; + } + //second + if (nextfilldata >= 0 && i == nextfilldata - 2) + { + m_TagVerts[1] = m_TempVerts[tempVertsIndex]; + } + //third + if (nextfilldata >= 0 && i == nextfilldata - 1) + { + m_TagVerts[2] = m_TempVerts[tempVertsIndex]; + } + //fourth + if (startfilldata >= 0 && i == startfilldata + 3) + { + m_TagVerts[3] = m_TempVerts[tempVertsIndex]; + } + if (tempVertsIndex == 3) + { + //skip + if ( i < startfilldata || i > nextfilldata ) + { + toFill.AddUIVertexQuad(m_TempVerts); + } + + if (nextfilldata >=0 && i >= nextfilldata) + { + FillNextTag(ref startfilldata,ref nextfilldata,ref fillindex); + } + } } } else @@ -277,54 +240,106 @@ protected override void OnPopulateMesh(VertexHelper toFill) m_TempVerts[tempVertsIndex] = verts[i]; m_TempVerts[tempVertsIndex].position *= unitsPerPixel; - if (tempVertsIndex == 3) - toFill.AddUIVertexQuad(m_TempVerts); + //first + if (startfilldata >= 0 && i == startfilldata) + { + m_TagVerts[0] = m_TempVerts[tempVertsIndex]; + } + //second + if (nextfilldata >= 0 && i == nextfilldata - 2) + { + m_TagVerts[1] = m_TempVerts[tempVertsIndex]; + } + //third + if (nextfilldata >= 0 && i == nextfilldata - 1) + { + m_TagVerts[2] = m_TempVerts[tempVertsIndex]; + } + //fourth + if (startfilldata >= 0 && i == startfilldata + 3) + { + m_TagVerts[3] = m_TempVerts[tempVertsIndex]; + } + + if (tempVertsIndex == 3) + { + //skip + if ( startfilldata == -1 || (startfilldata >=0 && i < startfilldata) || (nextfilldata >= 0 && i > nextfilldata )) + { + toFill.AddUIVertexQuad(m_TempVerts); + } + + if (nextfilldata >=0 && i >= nextfilldata) + { + FillNextTag(ref startfilldata,ref nextfilldata,ref fillindex); + } + } } } - m_DisableFontTextureRebuiltCallback = false; - - if(RenderTagList != null) - { - for(int i =0; i < RenderTagList.Count;++i) - RenderTagList[i].Fill(toFill); + m_DisableFontTextureRebuiltCallback = false; + + } + + void FillNextTag(ref int startfilldata,ref int nextfilldata,ref int fillindex) + { + if(_renderTagList != null && fillindex >=0) + { + //fill current + var current = _renderTagList[fillindex]; + current.Fill(m_TagVerts); + + fillindex++; + if (fillindex < _renderTagList.Count) + { + //update next + var data = _renderTagList[fillindex]; + nextfilldata = data.GetPositionIdx(); + startfilldata = nextfilldata - (data.GetFillCnt() - 1) * 4 - 3; + } + else + { + startfilldata = -1; + nextfilldata = -1; + fillindex = -1; + } } } internal List PopEmojiData() { - return RenderTagList; - } - - internal void ClearFillData(IFillData data) - { - if(RenderTagList != null) - { - RenderTagList.Clear(); - } - } - - internal void AddFillData(IFillData data) - { - if(RenderTagList == null) - { - RenderTagList = ListPool.Get(); - } - this.RenderTagList.Add(data); - } - - internal void RemoveFillData(IFillData data) - { - if(RenderTagList != null) - { - RenderTagList.Remove(data); - } + return _renderTagList; + } + + void ClearFillData() + { + if(_renderTagList != null) + { + _renderTagList.Clear(); + } + } + + internal void AddFillData(IFillData data) + { + if(_renderTagList == null) + { + _renderTagList = ListPool.Get(); + } + this._renderTagList.Add(data); + } + + internal void RemoveFillData(IFillData data) + { + if(_renderTagList != null) + { + _renderTagList.Remove(data); + } } - } -} - - - - - + } +} + + + + + diff --git a/Assets/TextInlineSprite/Scripts/InlineText.cs.meta b/Assets/TextInlineSprite/Scripts/InlineText.cs.meta index ad77eca..2b526eb 100644 --- a/Assets/TextInlineSprite/Scripts/InlineText.cs.meta +++ b/Assets/TextInlineSprite/Scripts/InlineText.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 guid: fe91fb1d3926f5940bad17bb75cfd5fe -timeCreated: 1498315505 -licenseType: Free +timeCreated: 1532788406 +licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/Assets/TextInlineSprite/Scripts/ParseData.cs b/Assets/TextInlineSprite/Scripts/ParseData.cs index 5b6259b..f657ace 100644 --- a/Assets/TextInlineSprite/Scripts/ParseData.cs +++ b/Assets/TextInlineSprite/Scripts/ParseData.cs @@ -15,58 +15,66 @@ public interface IFillData Vector3[] pos { get; set; } Vector2[] uv { get; set; } - void Fill(VertexHelper filler); - } - - public struct ParsedData : IEquatable - { - public int atlasID; - public string atlasTag; + int Fill(UIVertex[] filler); - public bool Equals(ParsedData other) - { - if (this.atlasID != other.atlasID) - return false; + int GetFillCnt(); - if (this.atlasTag != other.atlasTag) - return false; + int GetPositionIdx(); - return true; - } + int GetTagIndex(); } + #endregion public class SpriteTagInfo:IFillData { - private int _Position = -1; - private const int dv = 100000; - - + private int _position ; + private const int Dv = 1000; + private const int DV2 = Dv * Dv; + public int ID { get; set; } public Vector3[] pos { get; set; } public Vector2[] uv { get; set; } - //custom - public Vector2 Size { get; set; } public string Tag { get; set; } - public void FillIdxAndPlaceHolder(int idx, int cnt) + public void FillIdxAndPlaceHolder(int idx, int tagidx,int fillcnt) { - _Position = cnt * dv + idx; + _position =fillcnt *DV2 + tagidx * Dv + idx; } - public int GetPlaceHolderCnt() + public int GetTagIndex() { - return _Position / dv; + return (_position / Dv) % Dv; } public int GetPositionIdx() { - return _Position % dv; + return _position % Dv; + } + + public int GetFillCnt() + { + return _position / DV2; + } + + public int Fill(UIVertex[] filler) + { + int index = GetPositionIdx(); + if (index >= 0) + { + pos[0] = filler[0].position; + pos[1] = filler[1].position; + pos[2] = filler[2].position; + pos[3] = filler[3].position; + + } + + return -1; } } diff --git a/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs b/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs index 8a2d843..5a69ac4 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs @@ -10,6 +10,14 @@ public class EmojiParser : IParser { private static TextGenerator _UnderlineText; public int Hot { get; set; } + + private const string palceholder = "1"; + + private TextGenerator _SpaceGen; + + private int cacheframecnt; + + private InlineText cachetext; public void DoFillMesh() { @@ -21,19 +29,18 @@ public void RecordTextUpdate(InlineText text) throw new System.NotImplementedException(); } - internal void FillSpriteTag(StringBuilder stringBuilder, Match match, int Index, ParsedData tagInfo) + void FillSpriteTag(InlineText text,StringBuilder stringBuilder, Match match,int matchindex, int atlasId,string atlasTag) { - int Id = tagInfo.atlasID; - string TagName = tagInfo.atlasTag; - if (Manager != null && Manager.CanRendering(Id) && Manager.CanRendering(TagName)) + + if (text.Manager != null && text.Manager.CanRendering(atlasId) && text.Manager.CanRendering(atlasTag)) { SpriteAsset sprAsset; - SpriteInfoGroup tagSprites = Manager.FindSpriteGroup(TagName, out sprAsset); + SpriteInfoGroup tagSprites = text.Manager.FindSpriteGroup(atlasTag, out sprAsset); if (tagSprites != null && tagSprites.spritegroups.Count > 0) { - if (!Manager.isRendering(sprAsset)) + if (!text.Manager.isRendering(sprAsset)) { - Manager.PushRenderAtlas(sprAsset); + text.Manager.PushRenderAtlas(sprAsset); } if (_SpaceGen == null) @@ -41,19 +48,21 @@ internal void FillSpriteTag(StringBuilder stringBuilder, Match match, int Index, _SpaceGen = new TextGenerator(); } - if (updatespace) + if (cacheframecnt != Time.frameCount || cachetext != text) { - Vector2 extents = rectTransform.rect.size; - TextGenerationSettings settings = GetGenerationSettings(extents); + cacheframecnt = Time.frameCount; + cachetext = text; + + Vector2 extents = text.rectTransform.rect.size; + TextGenerationSettings settings = text.GetGenerationSettings(extents); _SpaceGen.Populate(palceholder, settings); - updatespace = false; + } IList spaceverts = _SpaceGen.verts; float spacewid = spaceverts[1].position.x - spaceverts[0].position.x; float spaceheight = spaceverts[0].position.y - spaceverts[3].position.y; - float autosize = Mathf.Min(tagSprites.size, Mathf.Max(spacewid, spaceheight)); float spacesize = Mathf.Max(spacewid, spaceheight); @@ -64,34 +73,19 @@ internal void FillSpriteTag(StringBuilder stringBuilder, Match match, int Index, stringBuilder.Append(palceholder); } - if (RenderTagList == null) + if (fillspacecnt > 0) { - RenderTagList = ListPool.Get(); - } + SpriteTagInfo tempSpriteTag = new SpriteTagInfo(); + tempSpriteTag.ID = atlasId; + tempSpriteTag.Tag = atlasTag; + tempSpriteTag.Size = new Vector2(autosize, autosize); + tempSpriteTag.pos = new Vector3[4]; + tempSpriteTag.uv = tagSprites.spritegroups[0].uv; + + + tempSpriteTag.FillIdxAndPlaceHolder(stringBuilder.Length * 4-1,matchindex,fillspacecnt); - if (RenderTagList.Count > Index) - { - SpriteTagInfo _tempSpriteTag = RenderTagList[Index]; - _tempSpriteTag._ID = Id; - _tempSpriteTag._Tag = TagName; - _tempSpriteTag._Size = new Vector2(autosize, autosize); - _tempSpriteTag.FillIdxAndPlaceHolder(match.Index, fillspacecnt); - _tempSpriteTag._UV = tagSprites.spritegroups[0].uv; - } - else - { - SpriteTagInfo _tempSpriteTag = new SpriteTagInfo - { - _ID = Id, - _Tag = TagName, - _Size = new Vector2(autosize, autosize), - _Pos = new Vector3[4], - _UV = tagSprites.spritegroups[0].uv - }; - - _tempSpriteTag.FillIdxAndPlaceHolder(match.Index, fillspacecnt); - - RenderTagList.Add(_tempSpriteTag); + text.AddFillData(tempSpriteTag); } } @@ -110,32 +104,30 @@ public bool ParsetContent(InlineText text,StringBuilder textfiller, Match data,i string tagKey = null; if (index != -1) { - string subID = value.Substring(1, index - 1); - if (subID.Length > 0 && !int.TryParse(subID, out atlasId)) + string subId = value.Substring(1, index - 1); + if (subId.Length > 0 && !int.TryParse(subId, out atlasId)) { - Debug.LogErrorFormat("{0} convert failed ", subID); + Debug.LogErrorFormat("{0} convert failed ", subId); } - else if (subID.Length > 0) + else if (subId.Length > 0) { atlasId = -1; } - else if (subID.Length == 0) + else if (subId.Length == 0) { atlasId = 0; } tagKey = value.Substring(index + 1, value.Length - index - 2); + + FillSpriteTag(text,textfiller,data,matchindex,atlasId,tagKey); - parsedData.atlasID = atlasId; - parsedData.atlasTag = tagKey; } else { tagKey = value.Substring(1, value.Length - 2); - - parsedData.atlasID = atlasId; - parsedData.atlasTag = tagKey; + FillSpriteTag(text,textfiller,data,matchindex,atlasId,tagKey); } return true; diff --git a/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs b/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs index c6edd05..59218f2 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/HrefParser.cs @@ -10,27 +10,10 @@ public class HrefParser : IParser { public int Hot { get; set; } - - public void DoFillMesh() + public bool ParsetContent(InlineText text, StringBuilder textfiller, Match data,int matchindex) { throw new System.NotImplementedException(); } - - public void RecordTextUpdate(InlineText text) - { - throw new System.NotImplementedException(); - } - - public void DoFillText(InlineText text, StringBuilder stringBuilder, Match match, int Index, ParsedData tagInfo) - { - throw new System.NotImplementedException(); - } - - public bool ParsetContent(InlineText text,StringBuilder textfiller, Match data,int matchindex) - { - return false; - } - } } diff --git a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs index 5454b53..a46ede8 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/IParser.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/IParser.cs @@ -12,9 +12,6 @@ public interface IParser bool ParsetContent(InlineText text,StringBuilder textfiller, Match data,int matchindex); - void DoFillMesh(); - - void RecordTextUpdate(InlineText text); } } diff --git a/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs index fb162cd..bfc34d9 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs @@ -24,7 +24,7 @@ public static ParserTransmit mIns } } - public const string palceholder = "1"; + private const string ParsetLeft = "\\["; @@ -32,9 +32,9 @@ public static ParserTransmit mIns public static int hot = 100; - private List parsers = new List(8); + private readonly List _parsers = new List(8); - private Regex TagRegex = new Regex(string.Format(@"{0}(\-{{0,1}}\d{{0,}})#(.+?){1}", ParsetLeft, ParsetRight), RegexOptions.Singleline); + private readonly Regex _tagRegex = new Regex(string.Format(@"{0}(\-{{0,1}}\d{{0,}})#(.+?){1}", ParsetLeft, ParsetRight), RegexOptions.Singleline); private ParserTransmit() { @@ -44,24 +44,25 @@ private ParserTransmit() public void AddParser(IParser parser) { - if (Application.isEditor && parsers.Contains(parser)) + if (Application.isEditor && _parsers.Contains(parser)) { Debug.LogErrorFormat("has contains it :{0}", parser); } - parsers.Add(parser); + _parsers.Add(parser); } public bool RemoveParser(IParser parser) { - return parsers.Remove(parser); + return _parsers.Remove(parser); } - public void DoParser(InlineText text, StringBuilder fillbuilder, string content) + public void DoParse(InlineText text, StringBuilder fillbuilder, string content) { - if (parsers.Count > 0) + + if (_parsers.Count > 0) { - MatchCollection matches = TagRegex.Matches(content); + MatchCollection matches = _tagRegex.Matches(content); if (matches.Count > 0) { bool needfix = false; @@ -72,18 +73,12 @@ public void DoParser(InlineText text, StringBuilder fillbuilder, string content) fillbuilder.Append(content.Substring(index, matchstr.Index - index)); - if (m == matches.Count - 1) - { - fillbuilder.Append(content.Substring(matchstr.Index + matchstr.Length)); - } - index = matchstr.Index + matchstr.Length; - for (int i = 0; i < parsers.Count; ++i) + for (int i = 0; i < _parsers.Count; ++i) { - var parser = parsers[i]; + var parser = _parsers[i]; - ParsedData tagInfo = new ParsedData(); if (parser.ParsetContent(text,fillbuilder,matchstr,m)) { parser.Hot++; @@ -93,16 +88,21 @@ public void DoParser(InlineText text, StringBuilder fillbuilder, string content) } } } + + if (m == matches.Count - 1) + { + fillbuilder.Append(content.Substring(matchstr.Index + matchstr.Length)); + } } //reset and fix - if (needfix && this.parsers.Count >1) - this.parsers.Sort(SortList); + if (needfix && this._parsers.Count >1) + this._parsers.Sort(SortList); // - for (int i = 0; i < parsers.Count; ++i) + for (int i = 0; i < _parsers.Count; ++i) { - var parser = parsers[i]; + var parser = _parsers[i]; parser.Hot = 0; } } From 918b81a553f95e84987354c91539fe3b58983f8e Mon Sep 17 00:00:00 2001 From: cjsjy123 Date: Sun, 29 Jul 2018 00:12:59 +0800 Subject: [PATCH 09/12] v1 --- .gitignore | 1 + Assets/Examples/Scene/Text.unity | Bin 30115 -> 29448 bytes Assets/Plugins.meta | 4 +- Assets/TextInlineSprite/Scripts/InlineText.cs | 54 +++++------------- Assets/TextInlineSprite/Scripts/ParseData.cs | 17 +++--- .../Scripts/Parser/EmojiParser.cs | 4 +- .../Scripts/Parser/ParserTransmit.cs | 4 ++ 7 files changed, 31 insertions(+), 53 deletions(-) diff --git a/.gitignore b/.gitignore index d3c55cb..f5fa4aa 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ *.csproj *.sln *.suo +/Assets/Plugins diff --git a/Assets/Examples/Scene/Text.unity b/Assets/Examples/Scene/Text.unity index dc54348370fd25ea85d4262ffae66edd20155261..ac7a4355ef4a29ba020ddd69d9fae5007158291f 100644 GIT binary patch literal 29448 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 literal 30115 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 diff --git a/Assets/Plugins.meta b/Assets/Plugins.meta index 02e6847..5d3dd28 100644 --- a/Assets/Plugins.meta +++ b/Assets/Plugins.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 7ae12929bed2d48f89836e2d71eeee9a folderAsset: yes -timeCreated: 1531763212 -licenseType: Free +timeCreated: 1532778406 +licenseType: Pro DefaultImporter: userData: assetBundleName: diff --git a/Assets/TextInlineSprite/Scripts/InlineText.cs b/Assets/TextInlineSprite/Scripts/InlineText.cs index 90afbba..a6bdaa1 100644 --- a/Assets/TextInlineSprite/Scripts/InlineText.cs +++ b/Assets/TextInlineSprite/Scripts/InlineText.cs @@ -22,7 +22,7 @@ public class InlineText : Text { private static StringBuilder _textBuilder = new StringBuilder(); private static UIVertex[] m_TempVerts = new UIVertex[4]; - private static UIVertex[] m_TagVerts = new UIVertex[4]; + private static Vector3[] m_TagVerts = new Vector3[2]; private TextGenerator _SpaceGen; private InlineManager _InlineManager; @@ -67,13 +67,6 @@ protected override void Start() EmojiTools.AddUnityMemory(this); } -#if UNITY_EDITOR - protected override void OnValidate() - { - //do nothing - } -#endif - public override void SetVerticesDirty() { base.SetVerticesDirty(); @@ -82,7 +75,6 @@ public override void SetVerticesDirty() if (!Manager) { _outputText = m_Text; - return; } else if(Manager.HasInit) { @@ -92,8 +84,10 @@ public override void SetVerticesDirty() { StartCoroutine(WaitManagerInited()); } - - + } + else + { + _outputText = m_Text; } } @@ -117,11 +111,7 @@ void DoUpdateEmoji() _outputText = _textBuilder.ToString(); _textBuilder.Length = 0; - - Debug.LogError(_outputText); - } - - + } } protected override void OnDestroy() @@ -199,22 +189,13 @@ protected override void OnPopulateMesh(VertexHelper toFill) //first if (startfilldata >= 0 && i == startfilldata) { - m_TagVerts[0] = m_TempVerts[tempVertsIndex]; - } - //second - if (nextfilldata >= 0 && i == nextfilldata - 2) - { - m_TagVerts[1] = m_TempVerts[tempVertsIndex]; + m_TagVerts[0]= m_TempVerts[tempVertsIndex].position; } + //third if (nextfilldata >= 0 && i == nextfilldata - 1) { - m_TagVerts[2] = m_TempVerts[tempVertsIndex]; - } - //fourth - if (startfilldata >= 0 && i == startfilldata + 3) - { - m_TagVerts[3] = m_TempVerts[tempVertsIndex]; + m_TagVerts[1] = m_TempVerts[tempVertsIndex].position; } if (tempVertsIndex == 3) @@ -243,22 +224,13 @@ protected override void OnPopulateMesh(VertexHelper toFill) //first if (startfilldata >= 0 && i == startfilldata) { - m_TagVerts[0] = m_TempVerts[tempVertsIndex]; - } - //second - if (nextfilldata >= 0 && i == nextfilldata - 2) - { - m_TagVerts[1] = m_TempVerts[tempVertsIndex]; + m_TagVerts[0] = m_TempVerts[tempVertsIndex].position; } + //third if (nextfilldata >= 0 && i == nextfilldata - 1) { - m_TagVerts[2] = m_TempVerts[tempVertsIndex]; - } - //fourth - if (startfilldata >= 0 && i == startfilldata + 3) - { - m_TagVerts[3] = m_TempVerts[tempVertsIndex]; + m_TagVerts[1] = m_TempVerts[tempVertsIndex].position; } if (tempVertsIndex == 3) @@ -287,7 +259,7 @@ void FillNextTag(ref int startfilldata,ref int nextfilldata,ref int fillindex) { //fill current var current = _renderTagList[fillindex]; - current.Fill(m_TagVerts); + current.Fill(m_TagVerts[0],m_TagVerts[1]); fillindex++; if (fillindex < _renderTagList.Count) diff --git a/Assets/TextInlineSprite/Scripts/ParseData.cs b/Assets/TextInlineSprite/Scripts/ParseData.cs index f657ace..ba61b44 100644 --- a/Assets/TextInlineSprite/Scripts/ParseData.cs +++ b/Assets/TextInlineSprite/Scripts/ParseData.cs @@ -15,7 +15,7 @@ public interface IFillData Vector3[] pos { get; set; } Vector2[] uv { get; set; } - int Fill(UIVertex[] filler); + int Fill(Vector3 start, Vector3 end); int GetFillCnt(); @@ -62,18 +62,19 @@ public int GetFillCnt() return _position / DV2; } - public int Fill(UIVertex[] filler) + public int Fill(Vector3 start,Vector3 end) { int index = GetPositionIdx(); if (index >= 0) { - pos[0] = filler[0].position; - pos[1] = filler[1].position; - pos[2] = filler[2].position; - pos[3] = filler[3].position; - + float w = Mathf.Abs(end.x - start.x); + float h = Mathf .Abs( end.y - start.y); + Vector3 center = (start + end) / 2; + pos[3] = center + new Vector3(-Size.x / 2,-Size.y / 2, 0); + pos[2] = center + new Vector3(Size.x / 2, -Size.y / 2, 0); + pos[1] = center + new Vector3(Size.x / 2, Size.y / 2, 0); + pos[0] = center + new Vector3(-Size.x / 2, Size.y / 2, 0); } - return -1; } diff --git a/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs b/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs index 5a69ac4..6dc6e43 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs @@ -64,9 +64,9 @@ void FillSpriteTag(InlineText text,StringBuilder stringBuilder, Match match,int float spaceheight = spaceverts[0].position.y - spaceverts[3].position.y; float autosize = Mathf.Min(tagSprites.size, Mathf.Max(spacewid, spaceheight)); - float spacesize = Mathf.Max(spacewid, spaceheight); + float spacesize = Mathf.Min(spacewid, spaceheight); - int fillspacecnt = Mathf.CeilToInt(autosize / spacesize); + int fillspacecnt = Mathf.RoundToInt(autosize / spacesize); for (int i = 0; i < fillspacecnt; i++) { diff --git a/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs index bfc34d9..44ff89b 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/ParserTransmit.cs @@ -106,6 +106,10 @@ public void DoParse(InlineText text, StringBuilder fillbuilder, string content) parser.Hot = 0; } } + else + { + fillbuilder.Append(content); + } } else { From 0347cf92b56d8721efffd532936c2337916c3a94 Mon Sep 17 00:00:00 2001 From: cjsjy123 Date: Sun, 29 Jul 2018 00:44:21 +0800 Subject: [PATCH 10/12] =?UTF-8?q?=E9=87=8D=E6=9E=84=E7=AC=AC=E4=B8=80?= =?UTF-8?q?=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Examples/Scene/Text.unity | Bin 29448 -> 29712 bytes .../Scripts/InlineRender/EmojiRenderGroup.cs | 4 + .../Scripts/InlineRender/UnitRender.cs | 5 + Assets/TextInlineSprite/Scripts/InlineText.cs | 148 +++++++++++++++++- Assets/TextInlineSprite/Scripts/ParseData.cs | 6 +- .../Scripts/Parser/EmojiParser.cs | 4 +- 6 files changed, 160 insertions(+), 7 deletions(-) diff --git a/Assets/Examples/Scene/Text.unity b/Assets/Examples/Scene/Text.unity index ac7a4355ef4a29ba020ddd69d9fae5007158291f..590eba6cdb59e1dbf5ef4f2b5ae6270c57604588 100644 GIT binary patch delta 520 zcmeBp#yH^xBL@RR2tNZuiNHpVmZ16!Rt5$x2B1*ko@^k+5Fx?9FcnC%0C6Z(>;q6t z2gnxy;xMR~f+R#t5GWQ76$^lh2?50-pkfU`v57#wFc3#V#U!K{7z%)VJ_ZJPhN6_W z`9L;92T;%k>X>4v*a`W~TEYLgCNGH+m~0TjGPxjIWOG2=6b>W-fyo@{8jPZw4b#P$ z*qMRm=vo?1_RlnAHncPb(wdXkWO6VY8dy%QPf49Dll7tgHBe1RYDG!3fpThYepY6@ oK`e+17NUbl9BnO|ERZcf`AlpKEQB@}WJj>WIH2&G{Gmt!06Kh_=Kufz delta 277 zcmbR6g0bTnBL@RR2tNZuF~>%ZmZ16s76t|`2B1*ko@^k+5FpOLFcnAxg&9JjVlRMV zIzYYv5Qjm^D!{UGZdw~ z%?Gj>8i0Z}tPsZ(L&XlrZPp6@$2B=5Qeg6fVvWrSaV;EBj>u$=bPYz4&4%gXOp_g= zEtpIVC;Me;O 1) diff --git a/Assets/TextInlineSprite/Scripts/InlineRender/UnitRender.cs b/Assets/TextInlineSprite/Scripts/InlineRender/UnitRender.cs index 82746d1..357031e 100644 --- a/Assets/TextInlineSprite/Scripts/InlineRender/UnitRender.cs +++ b/Assets/TextInlineSprite/Scripts/InlineRender/UnitRender.cs @@ -256,6 +256,8 @@ void RenderRebuild() for (int j = 0; j < emojidata.Count; ++j) { IFillData taginfo = emojidata[j]; + if (taginfo == null || taginfo.ignore) + continue; SpriteGraphic job = Parse(text, taginfo, joblist); if (job) joblist.Add(job); @@ -328,6 +330,9 @@ void PlayAnimation() for (int j = 0; j < emojidata.Count; ++j) { IFillData taginfo = emojidata[j]; + if (taginfo == null || taginfo.ignore) + continue; + SpriteAsset asset = null; SpriteInfoGroup groupinfo = manager.FindSpriteGroup(taginfo.Tag, out asset); if (groupinfo != null && groupinfo.spritegroups.Count > 1) diff --git a/Assets/TextInlineSprite/Scripts/InlineText.cs b/Assets/TextInlineSprite/Scripts/InlineText.cs index a6bdaa1..7caf8c5 100644 --- a/Assets/TextInlineSprite/Scripts/InlineText.cs +++ b/Assets/TextInlineSprite/Scripts/InlineText.cs @@ -23,8 +23,11 @@ public class InlineText : Text private static StringBuilder _textBuilder = new StringBuilder(); private static UIVertex[] m_TempVerts = new UIVertex[4]; private static Vector3[] m_TagVerts = new Vector3[2]; + /// + /// Security usually means additional performance overhead. If you control the bounding box yourself, this calculation may be redundant. + /// + public static bool safeMode = true; - private TextGenerator _SpaceGen; private InlineManager _InlineManager; //文本表情管理器 public InlineManager Manager @@ -46,6 +49,120 @@ public InlineManager Manager List _renderTagList; private string _lasttext ; private string _outputText = ""; + private float? _pw; + + public override float preferredWidth + { + get + { + if (_pw == null) + { + //its override from uGUI Code ,but has bug? + + //var settings = GetGenerationSettings(Vector2.zero); + //return cachedTextGeneratorForLayout.GetPreferredWidth(_OutputText, settings) / pixelsPerUnit; + + //next idea + Vector2 extents = rectTransform.rect.size; + + var settings = GetGenerationSettings(extents); + cachedTextGenerator.Populate(_outputText, settings); + + if (cachedTextGenerator.lineCount > 1) + { + float? minx = null; + float? maxx = null; + IList verts = cachedTextGenerator.verts; + int maxIndex = cachedTextGenerator.lines[1].startCharIdx; + + for (int i = 0, index = 0; i < verts.Count; i += 4, index++) + { + UIVertex v0 = verts[i]; + UIVertex v2 = verts[i + 1]; + float min = v0.position.x; + float max = v2.position.x; + + if (minx.HasValue == false) + { + minx = min; + } + else + { + minx = Mathf.Min(minx.Value, min); + } + + if (maxx.HasValue == false) + { + maxx = max; + } + else + { + maxx = Mathf.Max(maxx.Value, max); + } + + if (index > maxIndex) + { + break; + } + } + + _pw = (maxx - minx); + } + else + { + //_pw = cachedTextGeneratorForLayout.GetPreferredWidth(_OutputText, settings) / pixelsPerUnit; + float? minx = null; + float? maxx = null; + IList verts = cachedTextGenerator.verts; + int maxIndex = cachedTextGenerator.characterCount; + + for (int i = 0, index = 0; i < verts.Count; i += 4, index++) + { + UIVertex v0 = verts[i]; + UIVertex v2 = verts[i + 1]; + float min = v0.position.x; + float max = v2.position.x; + + if (minx.HasValue == false) + { + minx = min; + } + else + { + minx = Mathf.Min(minx.Value, min); + } + + if (maxx.HasValue == false) + { + maxx = max; + } + else + { + maxx = Mathf.Max(maxx.Value, max); + } + + if (index > maxIndex) + { + break; + } + } + + _pw = (maxx - minx); + } + + } + return _pw.Value; + } + } + + public override float preferredHeight + { + get + { + var settings = GetGenerationSettings(new Vector2(GetPixelAdjustedRect().size.x, 0.0f)); + return cachedTextGeneratorForLayout.GetPreferredHeight(_outputText, settings) / pixelsPerUnit; + } + } void OnDrawGizmos() { @@ -70,7 +187,7 @@ protected override void Start() public override void SetVerticesDirty() { base.SetVerticesDirty(); - if (Application.isPlaying) + if (Application.isPlaying && this.isActiveAndEnabled) { if (!Manager) { @@ -156,7 +273,6 @@ protected override void OnPopulateMesh(VertexHelper toFill) roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset; toFill.Clear(); - int nextfilldata = -1; int fillindex = -1; int startfilldata = -1; @@ -250,9 +366,35 @@ protected override void OnPopulateMesh(VertexHelper toFill) } m_DisableFontTextureRebuiltCallback = false; + // + + if(safeMode) + { + CalBoundsInSafe(); + } } + void CalBoundsInSafe() + { + if(_renderTagList != null && _renderTagList.Count>0) + { + Rect rect = rectTransform.rect; + for (int i = _renderTagList.Count - 1; i >= 0; i--) + { + IFillData data = _renderTagList[i]; + if (rect.Contains(data.pos[1]) && rect.Contains(data.pos[3])) + { + data.ignore = false; + } + else + { + data.ignore = true; + } + } + } + } + void FillNextTag(ref int startfilldata,ref int nextfilldata,ref int fillindex) { if(_renderTagList != null && fillindex >=0) diff --git a/Assets/TextInlineSprite/Scripts/ParseData.cs b/Assets/TextInlineSprite/Scripts/ParseData.cs index ba61b44..28d7fae 100644 --- a/Assets/TextInlineSprite/Scripts/ParseData.cs +++ b/Assets/TextInlineSprite/Scripts/ParseData.cs @@ -15,6 +15,8 @@ public interface IFillData Vector3[] pos { get; set; } Vector2[] uv { get; set; } + bool ignore { get; set; } + int Fill(Vector3 start, Vector3 end); int GetFillCnt(); @@ -40,6 +42,8 @@ public class SpriteTagInfo:IFillData public Vector2 Size { get; set; } + public bool ignore { get; set; } + public string Tag { get; set; } public void FillIdxAndPlaceHolder(int idx, int tagidx,int fillcnt) @@ -67,8 +71,6 @@ public int Fill(Vector3 start,Vector3 end) int index = GetPositionIdx(); if (index >= 0) { - float w = Mathf.Abs(end.x - start.x); - float h = Mathf .Abs( end.y - start.y); Vector3 center = (start + end) / 2; pos[3] = center + new Vector3(-Size.x / 2,-Size.y / 2, 0); pos[2] = center + new Vector3(Size.x / 2, -Size.y / 2, 0); diff --git a/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs b/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs index 6dc6e43..9348ded 100644 --- a/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs +++ b/Assets/TextInlineSprite/Scripts/Parser/EmojiParser.cs @@ -105,9 +105,9 @@ public bool ParsetContent(InlineText text,StringBuilder textfiller, Match data,i if (index != -1) { string subId = value.Substring(1, index - 1); - if (subId.Length > 0 && !int.TryParse(subId, out atlasId)) + if (subId.Length > 0 && int.TryParse(subId, out atlasId)) { - Debug.LogErrorFormat("{0} convert failed ", subId); + //Debug.LogErrorFormat("{0} convert success ", subId); } else if (subId.Length > 0) { From c4d963fac6d75ea89e2b738a2cd8cd9bba7379e9 Mon Sep 17 00:00:00 2001 From: cjsjy123 Date: Sun, 29 Jul 2018 01:06:24 +0800 Subject: [PATCH 11/12] optimze gc equals zero --- .../Scripts/InlineRender/EmojiRenderGroup.cs | 2 ++ .../Scripts/InlineRender/UnitRender.cs | 33 ++++++++----------- .../TextInlineSprite/Scripts/SpriteGraphic.cs | 8 +++++ 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/Assets/TextInlineSprite/Scripts/InlineRender/EmojiRenderGroup.cs b/Assets/TextInlineSprite/Scripts/InlineRender/EmojiRenderGroup.cs index c947a91..599025a 100644 --- a/Assets/TextInlineSprite/Scripts/InlineRender/EmojiRenderGroup.cs +++ b/Assets/TextInlineSprite/Scripts/InlineRender/EmojiRenderGroup.cs @@ -220,6 +220,7 @@ public void Dispose() if (target != null) { target.Draw(null); + target.SetDirtyMask(); target.SetVerticesDirty(); } @@ -391,6 +392,7 @@ void RenderRebuild() else { group.graphic.Draw(null); + group.graphic.SetDirtyMask(); group.graphic.SetVerticesDirty(); } } diff --git a/Assets/TextInlineSprite/Scripts/InlineRender/UnitRender.cs b/Assets/TextInlineSprite/Scripts/InlineRender/UnitRender.cs index 357031e..fbbcc33 100644 --- a/Assets/TextInlineSprite/Scripts/InlineRender/UnitRender.cs +++ b/Assets/TextInlineSprite/Scripts/InlineRender/UnitRender.cs @@ -162,6 +162,7 @@ public void Dispose() if (target != null) { target.Draw(null); + target.SetDirtyMask(); target.SetVerticesDirty(); } } @@ -251,16 +252,12 @@ void RenderRebuild() if (renderData == null) renderData = new Dictionary(emojidata.Count); - List joblist = ListPool.Get(); - for (int j = 0; j < emojidata.Count; ++j) { IFillData taginfo = emojidata[j]; if (taginfo == null || taginfo.ignore) continue; - SpriteGraphic job = Parse(text, taginfo, joblist); - if (job) - joblist.Add(job); + Parse(text, taginfo); } List list; @@ -270,15 +267,14 @@ void RenderRebuild() { SpriteGraphic graphic = list[j]; //not render - if (graphic != null && !joblist.Contains(graphic)) + if (graphic != null && !graphic.isDirty) { graphic.Draw(null); + graphic.SetDirtyMask(); graphic.SetVerticesDirty(); } } } - - ListPool.Release(joblist); } else { @@ -292,6 +288,7 @@ void RenderRebuild() if (graphic != null) { graphic.Draw(null); + graphic.SetDirtyMask(); graphic.SetVerticesDirty(); } } @@ -326,7 +323,6 @@ void PlayAnimation() List emojidata = text.PopEmojiData(); if (emojidata != null && emojidata.Count > 0 && allatlas != null && allatlas.Count > 0) { - List joblist = ListPool.Get(); for (int j = 0; j < emojidata.Count; ++j) { IFillData taginfo = emojidata[j]; @@ -351,13 +347,10 @@ void PlayAnimation() if (renderData == null) renderData = new Dictionary(emojidata.Count); - RefreshSubUIMesh(text, target, asset, taginfo.pos, taginfo.uv, joblist); - joblist.Add(target); + RefreshSubUIMesh(text, target, asset, taginfo.pos, taginfo.uv); } } } - - ListPool.Release(joblist); } } } @@ -367,16 +360,16 @@ void PlayAnimation() EmojiTools.EndSample(); } - SpriteGraphic Parse(InlineText text, IFillData taginfo, List joblist) + SpriteGraphic Parse(InlineText text, IFillData taginfo) { if (taginfo != null) { - return ParsePosAndUV(text, taginfo.ID, taginfo.pos, taginfo.uv, joblist); + return ParsePosAndUV(text, taginfo.ID, taginfo.pos, taginfo.uv); } return null; } - SpriteGraphic ParsePosAndUV(InlineText text, int ID, Vector3[] Pos, Vector2[] UV, List joblist) + SpriteGraphic ParsePosAndUV(InlineText text, int ID, Vector3[] Pos, Vector2[] UV) { EmojiTools.BeginSample("Emoji_UnitParsePosAndUV"); SpriteAsset matchAsset = null; @@ -400,7 +393,7 @@ SpriteGraphic ParsePosAndUV(InlineText text, int ID, Vector3[] Pos, Vector2[] UV list.Add(target); } - RefreshSubUIMesh(text, target, matchAsset, Pos, UV, joblist); + RefreshSubUIMesh(text, target, matchAsset, Pos, UV); EmojiTools.EndSample(); return target; @@ -413,7 +406,7 @@ SpriteGraphic ParsePosAndUV(InlineText text, int ID, Vector3[] Pos, Vector2[] UV return null; } - void RefreshSubUIMesh(InlineText text, SpriteGraphic target, SpriteAsset matchAsset, Vector3[] Pos, Vector2[] UV, List joblist) + void RefreshSubUIMesh(InlineText text, SpriteGraphic target, SpriteAsset matchAsset, Vector3[] Pos, Vector2[] UV) { // set mesh tempMesh.SetAtlas(matchAsset); @@ -445,7 +438,7 @@ void RefreshSubUIMesh(InlineText text, SpriteGraphic target, SpriteAsset matchAs if (!currentMesh.Equals(tempMesh)) { - if (joblist != null && joblist.Contains(target)) + if (target.isDirty) { currentMesh.AddCopy(tempMesh); tempMesh.Clear(); @@ -459,11 +452,13 @@ void RefreshSubUIMesh(InlineText text, SpriteGraphic target, SpriteAsset matchAs if (currentMesh.VertCnt() > 3 && currentMesh.UVCnt() > 3) { target.Draw(this); + target.SetDirtyMask(); target.SetVerticesDirty(); } else { target.Draw(null); + target.SetDirtyMask(); target.SetVerticesDirty(); } } diff --git a/Assets/TextInlineSprite/Scripts/SpriteGraphic.cs b/Assets/TextInlineSprite/Scripts/SpriteGraphic.cs index d3d7a4c..17e5a87 100644 --- a/Assets/TextInlineSprite/Scripts/SpriteGraphic.cs +++ b/Assets/TextInlineSprite/Scripts/SpriteGraphic.cs @@ -26,6 +26,13 @@ public override Texture mainTexture } } + public bool isDirty { get; protected set; } + + public void SetDirtyMask() + { + isDirty = true; + } + public void Draw(IEmojiRender rd) { _Render = rd; @@ -57,6 +64,7 @@ protected override void OnPopulateMesh(VertexHelper vh) { _Render.FillMesh(this, vh); } + isDirty = false; } void OnDrawGizmos() From a6aacfb388c80e717dc66262c93601c48ff1d4cc Mon Sep 17 00:00:00 2001 From: cjsjy123 Date: Sun, 29 Jul 2018 01:16:26 +0800 Subject: [PATCH 12/12] optime and faster --- .../TextInlineSprite/Scripts/InlineManager.cs | 155 +++++++++--------- 1 file changed, 73 insertions(+), 82 deletions(-) diff --git a/Assets/TextInlineSprite/Scripts/InlineManager.cs b/Assets/TextInlineSprite/Scripts/InlineManager.cs index 0b26f03..05d3b19 100644 --- a/Assets/TextInlineSprite/Scripts/InlineManager.cs +++ b/Assets/TextInlineSprite/Scripts/InlineManager.cs @@ -1,4 +1,4 @@ - +#define EMOJI_RUNTIME using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -15,10 +15,12 @@ public class InlineManager : MonoBehaviour private readonly Dictionary _alltags = new Dictionary(); + private readonly Dictionary> _spritemap = new Dictionary>(); + private IEmojiRender _render; public List PreparedAtlas = new List(); - + public bool HasInit { get; private set; } #if UNITY_EDITOR @@ -276,7 +278,8 @@ void RebuildTagList() { EmojiTools.BeginSample("Emoji_rebuildTags"); _alltags.Clear(); -#if UNITY_EDITOR + _spritemap.Clear(); +#if UNITY_EDITOR && !EMOJI_RUNTIME if (_unityallAtlases != null) { for (int i = 0; i < _unityallAtlases.Count; ++i) @@ -297,21 +300,22 @@ void RebuildTagList() } #else - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - for (int j = 0; j < asset.listSpriteGroup.Count; ++j) - { - SpriteInfoGroup infogroup = asset.listSpriteGroup[j]; - SpriteInfoGroup group; - if (alltags.TryGetValue(infogroup.tag, out group)) - { - Debug.LogErrorFormat("already exist :{0} ", infogroup.tag); - } - - alltags[infogroup.tag] = infogroup; - } - } + for (int i = 0; i < _sharedAtlases.Count; ++i) + { + SpriteAsset asset = _sharedAtlases[i]; + for (int j = 0; j < asset.listSpriteGroup.Count; ++j) + { + SpriteInfoGroup infogroup = asset.listSpriteGroup[j]; + SpriteInfoGroup group; + if (_alltags.TryGetValue(infogroup.tag, out group)) + { + Debug.LogErrorFormat("already exist :{0} ", infogroup.tag); + } + + _alltags[infogroup.tag] = infogroup; + _spritemap[infogroup.tag] = new KeyValuePair(asset, infogroup); + } + } #endif EmojiTools.EndSample(); } @@ -384,7 +388,7 @@ public bool CanRendering(string tagName) public bool CanRendering(int atlasId) { -#if UNITY_EDITOR +#if UNITY_EDITOR && !EMOJI_RUNTIME if (_unityallAtlases != null) { for (int i = 0; i < _unityallAtlases.Count; ++i) @@ -399,15 +403,15 @@ public bool CanRendering(int atlasId) return false; #else - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - if (asset.ID == atlasId) - { - return true; - } - } - return false; + for (int i = 0; i < _sharedAtlases.Count; ++i) + { + SpriteAsset asset = _sharedAtlases[i]; + if (asset.ID == atlasId) + { + return true; + } + } + return false; #endif } @@ -429,10 +433,9 @@ public void PushRenderAtlas(SpriteAsset _spriteAsset) public SpriteInfoGroup FindSpriteGroup(string TagName, out SpriteAsset resultatlas) { EmojiTools.BeginSample("Emoji_FindSpriteGroup"); -#if UNITY_EDITOR +#if UNITY_EDITOR && !EMOJI_RUNTIME resultatlas = null; - SpriteInfoGroup result = null; if (_unityallAtlases != null) { @@ -463,35 +466,23 @@ public SpriteInfoGroup FindSpriteGroup(string TagName, out SpriteAsset resultatl EmojiTools.EndSample(); return result; #else - resultatlas = null; - - SpriteInfoGroup result = null; - if(sharedAtlases != null) - { - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - for (int j = 0; j < asset.listSpriteGroup.Count; ++j) - { - SpriteInfoGroup group = asset.listSpriteGroup[j]; - if (group.tag.Equals(TagName)) - { - result = group; - resultatlas = asset; - break; - } - } - } - } - EmojiTools.EndSample(); - return result; + resultatlas = null; + SpriteInfoGroup result = null; + KeyValuePair data; + if (_spritemap.TryGetValue(TagName,out data)) + { + result = data.Value; + resultatlas = data.Key; + } + EmojiTools.EndSample(); + return result; #endif } public SpriteAsset FindAtlas(int atlasID) { EmojiTools.BeginSample("Emoji_FindAtlas"); -#if UNITY_EDITOR +#if UNITY_EDITOR && !EMOJI_RUNTIME SpriteAsset result = null; if (_unityallAtlases != null) { @@ -517,17 +508,17 @@ public SpriteAsset FindAtlas(int atlasID) EmojiTools.EndSample(); return result; #else - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - if (asset.ID.Equals(atlasID)) - { - EmojiTools.EndSample(); - return asset; - } - } - EmojiTools.EndSample(); - return null; + for (int i = 0; i < _sharedAtlases.Count; ++i) + { + SpriteAsset asset = _sharedAtlases[i]; + if (asset.ID.Equals(atlasID)) + { + EmojiTools.EndSample(); + return asset; + } + } + EmojiTools.EndSample(); + return null; #endif } @@ -535,7 +526,7 @@ public SpriteAsset FindAtlas(int atlasID) public SpriteAsset FindAtlas(string atlasname) { EmojiTools.BeginSample("FindAtlas"); -#if UNITY_EDITOR +#if UNITY_EDITOR && !EMOJI_RUNTIME SpriteAsset result = null; if (_unityallAtlases != null) { @@ -561,23 +552,23 @@ public SpriteAsset FindAtlas(string atlasname) EmojiTools.EndSample(); return result; #else - for (int i = 0; i < sharedAtlases.Count; ++i) - { - SpriteAsset asset = sharedAtlases[i]; - if (asset.AssetName.Equals(atlasname)) - { - EmojiTools.EndSample(); - return asset; - } - } - - SpriteAsset newasset = InstantiateSpriteAsset(atlasname); - if(newasset != null) - { - sharedAtlases.Add(newasset); - } - EmojiTools.EndSample(); - return newasset; + for (int i = 0; i < _sharedAtlases.Count; ++i) + { + SpriteAsset asset = _sharedAtlases[i]; + if (asset.AssetName.Equals(atlasname)) + { + EmojiTools.EndSample(); + return asset; + } + } + + SpriteAsset newasset = InstantiateSpriteAsset(atlasname); + if (newasset != null) + { + _sharedAtlases.Add(newasset); + } + EmojiTools.EndSample(); + return newasset; #endif }