12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using CommonLang;
- using CommonUI.Gemo;
- using CommonUI.Cell.Game;
- namespace CommonUI.Display.Text
- {
- public abstract class BaseRichTextLayer : IDisposable
- {
- private List<Region> mBlocks = new List<Region>();
- private List<Region> mOldBlocks = new List<Region>();
- private List<Line> mLines = new List<Line>();
- private AttributedString mText = new AttributedString();
- private float mWidth;
- private int mBorderCount;
- private uint mBorderColor;
- private RichTextAlignment mAlignment = RichTextAlignment.taLEFT;
- private float mLineSpace;
- private float mFixedLineSpace;
- private bool mEnableLineBreak;
- private float mContentWidth;
- private float mContentHeigh;
- private bool mIsEnable = true;
- private bool mIsColorDirty = true;
- private HashMap<string, TImageRegion> mImageCache = new HashMap<string, TImageRegion>();
- private HashMap<string, TSpriteMetaAnimateFrame> mSpriteCache = new HashMap<string, TSpriteMetaAnimateFrame>();
- public RichTextAlignment Alignment { get { return mAlignment; } }
- public bool IsMultiline { get { return mEnableLineBreak; } }
- public int LineCount { get { return mLines.Count; } }
- public float LineSpace { get { return mLineSpace; } }
- public float FixedLineSpace { get { return mFixedLineSpace; } }
- public int TextLength { get { return mText.Length; } }
- public float Width { get { return mWidth; } }
-
-
-
- public float ContentWidth { get { return mContentWidth; } }
-
-
-
- public float ContentHeight { get { return mContentHeigh; } }
- public int BorderCount { get { return mBorderCount; } }
- public uint BorderColor { get { return mBorderColor; } }
- public bool IsEnable
- {
- get { return mIsEnable; }
- set
- {
- if (mIsEnable != value)
- {
- mIsEnable = value;
- mIsColorDirty = true;
- }
- }
- }
- protected List<Region> AllRegions
- {
- get { return mBlocks; }
- }
- protected List<Line> AllLines
- {
- get { return mLines; }
- }
- protected BaseRichTextLayer(float width = 100, RichTextAlignment anchor = RichTextAlignment.taLEFT)
- {
- mWidth = width;
- mAlignment = anchor;
- mEnableLineBreak = true;
- mLineSpace = 0;
- mFixedLineSpace = 0;
- mContentHeigh = 0;
- mContentWidth = 0;
- mBorderCount = 0;
- }
-
-
-
-
-
- public BaseRichTextLayer SetAnchor(RichTextAlignment anchor)
- {
- if (mAlignment != anchor)
- {
- mAlignment = anchor;
- ResetLines();
- }
- return this;
- }
-
-
-
-
-
- public BaseRichTextLayer SetLineSpace(float space)
- {
- if (mLineSpace != space)
- {
- mLineSpace = space;
- ResetLines();
- }
- return this;
- }
-
-
-
-
-
- public BaseRichTextLayer SetFixedLineSpace(float space)
- {
- if (mFixedLineSpace != space)
- {
- mFixedLineSpace = space;
- ResetLines();
- }
- return this;
- }
- public BaseRichTextLayer SetEnableMultiline(bool multiline)
- {
- if (mEnableLineBreak != multiline)
- {
- mEnableLineBreak = multiline;
- ResetChars();
- }
- return this;
- }
- public BaseRichTextLayer SetWidth(float width)
- {
- if (mWidth != width)
- {
- mWidth = width;
- ResetChars();
- }
- return this;
- }
- public BaseRichTextLayer SetBorder(int count, uint color)
- {
- if (mBorderCount != count || mBorderColor != color)
- {
- mBorderCount = count;
- mBorderColor = color;
- ResetChars();
- }
- return this;
- }
- public BaseRichTextLayer SetString(AttributedString text)
- {
- if (!mText.Equals(text))
- {
- this.mText = text;
- ResetChars();
- }
- return this;
- }
- public BaseRichTextLayer.Line GetLine(int index)
- {
- if (index < mLines.Count)
- {
- return mLines[index];
- }
- return null;
- }
- public AttributedString GetText()
- {
- return mText;
- }
-
-
-
-
-
- public BaseRichTextLayer.Region GetRegion(int charIndex)
- {
- if (mLines.Count == 0)
- {
- return null;
- }
- for (int i = 0; i < mBlocks.Count; i++)
- {
- BaseRichTextLayer.Region rg = mBlocks[i];
- if (charIndex <= rg.mStartIndex)
- {
- return rg;
- }
- }
- return null;
- }
- protected void BeginRender(Graphics g)
- {
- if (mOldBlocks.Count > 0)
- {
- foreach (BaseRichTextLayer.Region it in mOldBlocks)
- {
- it.Dispose();
- }
- mOldBlocks.Clear();
- }
- if (mIsColorDirty)
- {
- mIsColorDirty = false;
- this.CreateRegionBuffs();
- }
- }
- protected void InternalRender(Graphics g, float px, float py, float pw, float ph, float cx, float cy)
- {
- Line tempL = null;
- for (int i = 0; i < mLines.Count; i++)
- {
- tempL = mLines[i];
- if (tempL.mBlocks.Count > 0)
- {
- if (Rectangle2D.IntersectRectWH(cx, cy, pw, ph,
- tempL.mBounds.x,
- tempL.mBounds.y,
- tempL.mBounds.width,
- tempL.mBounds.height))
- {
- tempL.RenderLine(g, px, py);
- }
- else
- {
- tempL.HideLine(px, py);
- }
- }
- }
- }
- protected void AfterRender(Graphics g) { }
- protected virtual void OnDrawRegion(Graphics g, Region rg, float px, float py) { }
- protected virtual void OnDrawLine(Graphics g, Line rg, float px, float py) { }
-
-
-
-
-
-
-
-
-
-
- public virtual void Render(Graphics g, float dx, float dy, float dw, float dh, float sx, float sy)
- {
- this.BeginRender(g);
- this.InternalRender(g, dx, dy, dw, dh, sx, sy);
- this.AfterRender(g);
- }
-
-
-
-
-
-
- public virtual void Render(Graphics g, float dx, float dy)
- {
- Render(g, dx, dy, Width, mContentHeigh, 0, 0);
- }
-
-
-
-
-
-
-
- public virtual bool Click(float cx, float cy, out RichTextClickInfo info)
- {
- info = new RichTextClickInfo();
- for (int i = 0; i < mLines.Count; i++)
- {
- Line line = mLines[i];
- for (int c = 0; c < line.mBlocks.Count; c++)
- {
- Region rg = line.mBlocks[c];
- if (rg.mBounds.contains(cx, cy))
- {
- info.mRegion = rg;
- return true;
- }
- }
- }
- return false;
- }
- public virtual RichTextClickInfo Click(float cx, float cy)
- {
- RichTextClickInfo info = new RichTextClickInfo();
- for (int i = 0; i < mLines.Count; i++)
- {
- Line line = mLines[i];
- for (int c = 0; c < line.mBlocks.Count; c++)
- {
- Region rg = line.mBlocks[c];
- if (rg.mBounds.contains(cx, cy))
- {
- info.mRegion = rg;
- return info;
- }
- }
- }
- return info;
- }
- public virtual void Dispose()
- {
- foreach (BaseRichTextLayer.Region it in mBlocks)
- {
- it.Dispose();
- }
- foreach (BaseRichTextLayer.Region it in mOldBlocks)
- {
- it.Dispose();
- }
- mBlocks.Clear();
- mOldBlocks.Clear();
- mLines.Clear();
- }
-
- protected virtual void OnBeginResetChars() { }
- protected virtual void OnEndResetLines() { }
- private Action<BaseRichTextLayer> event_EndResetLines;
- public event Action<BaseRichTextLayer> EndResetLines
- {
- add { event_EndResetLines += value; }
- remove { event_EndResetLines -= value; }
- }
- private void ResetChars()
- {
- OnBeginResetChars();
- if (mOldBlocks.Count > 0)
- {
-
- foreach (BaseRichTextLayer.Region it in mBlocks)
- {
- it.Dispose();
- }
- mBlocks.Clear();
- }
- else
- {
-
- var tmp = mOldBlocks;
- mOldBlocks = mBlocks;
- mBlocks = tmp;
- }
- this.mBlocks.Capacity = (mText.Length);
-
- if (mText.Length > 0)
- {
- Region buildRG = null;
- for (int i = 0; i < mText.Length; i++)
- {
- TextAttribute curTA = mText.GetAttribute(i);
- if (!string.IsNullOrEmpty(curTA.resImage))
- {
- AddImage(curTA);
- }
- else if (!string.IsNullOrEmpty(curTA.resSprite))
- {
- AddSprite(curTA);
- }
- char mCH = mText.GetChar(i);
-
- if (mEnableLineBreak && (mCH == '\n'))
- {
- if (buildRG != null)
- {
- buildRG.mEndIndex = i;
- buildRG.mText = mText.ToString().Substring(buildRG.mStartIndex, buildRG.CharCount);
- mBlocks.Add(buildRG);
- }
- Region br = new Region(this, curTA);
- br.mText = "\n";
- br.mStartIndex = i;
- br.mEndIndex = i + 1;
- mBlocks.Add(br);
- buildRG = null;
- }
- else
- {
- if (buildRG != null)
- {
-
- if (!TestSplitByAttribute(buildRG.mAttribute, curTA))
- {
- buildRG.mEndIndex = i;
- buildRG.mText = mText.ToString().Substring(buildRG.mStartIndex, buildRG.CharCount);
- mBlocks.Add(buildRG);
- buildRG = new Region(this, curTA);
- buildRG.mStartIndex = i;
- }
- }
- else
- {
-
- buildRG = new Region(this, curTA);
- buildRG.mStartIndex = i;
- }
- }
- }
-
- if (buildRG != null)
- {
- buildRG.mEndIndex = mText.Length;
- buildRG.mText = mText.ToString().Substring(buildRG.mStartIndex, buildRG.CharCount);
- mBlocks.Add(buildRG);
- buildRG = null;
- }
- }
-
- this.mLines.Clear();
- if (mBlocks.Count > 0)
- {
- if (mEnableLineBreak)
- {
- float curX = 0;
- Line curLine = new Line(this);
- for (int i = 0; i < mBlocks.Count; i++)
- {
- Region rg = mBlocks[i];
- Region split_cur;
- Region split_next;
- int testW = (int)(mWidth - curX);
-
- if (testW <= 0)
- {
-
- mLines.Add(curLine);
- curLine = new Line(this);
- curX = 0;
- testW = (int)mWidth;
- }
- if (rg.mText.EndsWith("\n"))
- {
-
- this.TestLineBreak2(rg.mText.Substring(0, rg.mText.Length - 1), rg.mAttribute, float.MaxValue, out rg.mBounds.width, out rg.mBounds.height);
- curLine.AddRegion(rg);
- mLines.Add(curLine);
- curLine = new Line(this);
- curX = 0;
- }
- else if (TestLineBreak(rg, testW, out split_cur, out split_next))
- {
-
- if (split_next == rg)
- {
-
- if (curLine.RegionCount == 0)
- {
-
- curLine.AddRegion(rg);
- mLines.Add(curLine);
- curLine = new Line(this);
- curX = 0;
- }
- else
- {
-
- mLines.Add(curLine);
- curLine = new Line(this);
- curX = 0;
-
- --i;
- }
- }
- else
- {
-
- mBlocks.RemoveAt(i);
- mBlocks.Insert(i, split_cur);
- mBlocks.Insert(i + 1, split_next);
- rg.Dispose();
-
- curLine.AddRegion(split_cur);
- mLines.Add(curLine);
- curLine = new Line(this);
- curX = 0;
- }
- }
- else
- {
-
- curLine.AddRegion(rg);
- curX += rg.mBounds.width;
-
- if (i == (mBlocks.Count - 1))
- {
- mLines.Add(curLine);
- }
- }
- }
- }
- else
- {
- Line curLine = new Line(this);
- for (int i = 0; i < mBlocks.Count; i++)
- {
- Region rg = mBlocks[i];
- Region split_cur;
- Region split_next;
- TestLineBreak(rg, int.MaxValue, out split_cur, out split_next);
- curLine.AddRegion(rg);
- }
- mLines.Add(curLine);
- }
- }
- ResetLines();
- mIsColorDirty = true;
- }
- private void ResetLines()
- {
- mContentWidth = 1;
- mContentHeigh = 0;
- float c_left = float.MaxValue;
- float c_right = 0;
- for (int i = 0; i < mLines.Count; i++)
- {
- Line line = mLines[i];
- line.mIndex = i;
- float dw = 0;
- float dh = 0;
-
- {
- line.mAnchor = RichTextAlignment.taNA;
- for (int c = 0; c < line.mBlocks.Count; c++)
- {
- Region rg = line.mBlocks[c];
- rg.mBounds.x = dw;
- rg.mBounds.y = mContentHeigh;
- dw += rg.mBounds.width;
- dh = Math.Max(dh, rg.mBounds.height);
- if (rg.Attribute.anchor != RichTextAlignment.taNA)
- {
- line.mAnchor = rg.Attribute.anchor;
- }
- }
- line.mBounds.width = dw;
- line.mBounds.height = dh;
- line.mBounds.x = 0;
- line.mBounds.y = mContentHeigh;
- if (line.mAnchor == RichTextAlignment.taNA)
- {
- line.mAnchor = mAlignment;
- }
- }
-
- {
- float dx = 0;
- switch (line.mAnchor)
- {
- case RichTextAlignment.taLEFT:
- break;
- case RichTextAlignment.taCENTER:
- dx += (mWidth - dw) / 2;
- break;
- case RichTextAlignment.taRIGHT:
- dx += (mWidth - dw);
- break;
- }
- for (int c = 0; c < line.mBlocks.Count; c++)
- {
- Region rg = line.mBlocks[c];
- rg.mBounds.x += dx;
- rg.mBounds.y = rg.mBounds.y + dh - rg.mBounds.height;
- }
- line.mBounds.x += dx;
- }
- c_left = Math.Min(line.mBounds.x, c_left);
- c_right = Math.Max(line.mBounds.x + line.mBounds.width, c_right);
- if (mFixedLineSpace > 0)
- {
- mContentHeigh += mFixedLineSpace;
- }
- else
- {
- mContentHeigh += dh + mLineSpace;
- }
- }
- if (c_left < c_right)
- {
- mContentWidth = c_right - c_left;
- }
- else
- {
- mContentWidth = 1;
- }
- OnEndResetLines();
- if (event_EndResetLines != null) event_EndResetLines.Invoke(this);
- }
-
-
-
-
-
-
-
-
- private bool TestLineBreak(Region rg, float testW, out Region split_cur, out Region split_next)
- {
- rg.mBounds.width = 0;
- rg.mBounds.height = 0;
- split_cur = null;
- split_next = null;
- TextAttribute ta = rg.mAttribute;
- float last_tw = 0;
- float last_th = 0;
- float tw = 0;
- float th = 0;
- int textLength = rg.mText.Length;
- for (int ci = 0; ci < textLength; ++ci)
- {
- int cci = ci;
- int emoji_extra_len = 0;
- bool isemoji = Driver.Instance.IsEmoji(rg.mText, ci, out emoji_extra_len);
- if (isemoji)
- {
-
- emoji_extra_len -= 1;
- ci += emoji_extra_len;
- }
- string text = rg.mText.Substring(0, ci + 1);
- if (TestLineBreak2(text, ta, testW, out tw, out th))
- {
- if (cci == 0)
- {
-
- split_next = rg;
- split_cur = rg;
- rg.mBounds.width = tw;
- rg.mBounds.height = th;
- }
- else
- {
-
- Region[] splits = rg.Split(isemoji ? ci - emoji_extra_len : ci);
- rg.Dispose();
- split_cur = splits[0];
-
- split_cur.mBounds.width = last_tw;
- split_cur.mBounds.height = last_th;
- split_next = splits[1];
- }
- return true;
- }
- else
- {
- rg.mBounds.width = tw;
- rg.mBounds.height = th;
- }
- last_tw = tw;
- last_th = th;
- }
- return false;
- }
-
-
-
-
-
-
-
-
-
- private bool TestLineBreak2(String text, TextAttribute ta, float testW, out float tw, out float th)
- {
- tw = 0;
- th = 0;
- if (text.Equals("\n"))
- {
- TestTextLineBreak(text, ta, testW, out tw, out th);
- tw = 0;
- return true;
- }
- else if (ta.drawable != null)
- {
- tw = ta.drawable.CharWidth * text.Length;
- th = ta.drawable.CharHeight;
- if (tw > testW)
- {
- tw = (float)Math.Ceiling(testW - ta.drawable.CharWidth);
- return true;
- }
- }
- else if (!string.IsNullOrEmpty(ta.resImage))
- {
- if (ta.resImageZoom != null)
- {
- tw = ta.resImageZoom.Width * text.Length;
- th = ta.resImageZoom.Height;
- if (tw > testW)
- {
- tw = (float)Math.Ceiling(testW - ta.resImageZoom.Width);
- return true;
- }
- }
- else
- {
- TImageRegion img = AddImage(ta);
- if (img.image != null)
- {
- tw = img.sw * text.Length;
- th = img.sh;
- if (tw > testW)
- {
- tw = (float)Math.Ceiling(testW - img.sw);
- return true;
- }
- }
- }
- }
- else if (!string.IsNullOrEmpty(ta.resSprite))
- {
- TSpriteMetaAnimateFrame spr = AddSprite(ta);
- if (spr.sprite != null)
- {
- CCD bounds = spr.sprite.getVisibleBounds(spr.anim);
- tw = bounds.Width * text.Length;
- th = bounds.Height;
- if (tw > testW)
- {
- tw = (float)Math.Ceiling(testW - bounds.Width);
- return true;
- }
- }
- }
- else if (this.TestTextLineBreak(text, ta, testW, out tw, out th))
- {
- return true;
- }
- return false;
- }
-
-
-
-
-
-
- protected virtual bool TestSplitByAttribute(TextAttribute rg, TextAttribute ta)
- {
- return rg.Equals(ta);
- }
-
-
-
-
-
-
-
-
-
- protected virtual bool TestTextLineBreak(string text, TextAttribute ta, float testW, out float tw, out float th)
- {
- return Driver.Instance.testTextLineBreak(text, ta.fontSize, ta.fontStyle, mBorderCount, testW, out tw, out th);
- }
-
- private void CreateRegionBuffs()
- {
- mIsColorDirty = false;
-
- for (int i = 0; i < mBlocks.Count; i++)
- {
- Region rg = mBlocks[i];
- rg.mIndex = i;
- CreateRegionBuffer(rg);
- }
- }
- private Drawable CreateRegionBuffer(Region rg)
- {
- if (rg.IsBreak)
- {
- rg.Buffer = null;
- }
- else if (rg.mAttribute.drawable != null)
- {
- rg.Buffer = this.CreateDrawable(rg, rg.mAttribute.drawable);
- }
- else if (!string.IsNullOrEmpty(rg.mAttribute.resImage))
- {
- TImageRegion img = AddImage(rg.mAttribute);
- if (img.image != null)
- {
- rg.Buffer = this.CreateDrawable(rg, img);
- }
- }
- else if (!string.IsNullOrEmpty(rg.mAttribute.resSprite))
- {
- TSpriteMetaAnimateFrame spr = AddSprite(rg.mAttribute);
- if (spr.sprite != null)
- {
- rg.Buffer = this.CreateDrawable(rg, spr);
- }
- }
- else
- {
- rg.Buffer = this.CreateDrawable(rg, rg.Text);
- }
- return rg.Buffer;
- }
- private TImageRegion AddImage(TextAttribute ta)
- {
- TImageRegion ret = new TImageRegion();
- if (mImageCache.TryGetValue(ta.resImage, out ret))
- {
- return ret;
- }
- if (ta.resImage.StartsWith("#"))
- {
- string[] kvs = ta.resImage.Split(',');
- if (kvs.Length >= 3)
- {
- string file = kvs[0].Substring(1);
- Cell.CPJResource res = this.AddCPJResource(file);
- if (res != null)
- {
- Cell.CPJAtlas atlas = res.GetAtlas(kvs[1]);
- int tid;
- if (atlas != null && int.TryParse(kvs[2], out tid))
- {
- Image image = atlas.GetTile(tid);
- if (image != null)
- {
- Rectangle2D rect = atlas.GetAtlasRegion(tid);
- ret.sx = rect.x;
- ret.sy = rect.y;
- ret.sw = rect.width;
- ret.sh = rect.height;
- ret.image = image;
- mImageCache.Add(ta.resImage, ret);
- return ret;
- }
- }
- }
- }
- }
- else
- {
- string file = ta.resImage;
- Image image = AddImage(file);
- if (image != null)
- {
- ret.sw = image.Width;
- ret.sh = image.Height;
- ret.image = image;
- mImageCache.Add(ta.resImage, ret);
- return ret;
- }
- }
- return ret;
- }
- private TSpriteMetaAnimateFrame AddSprite(TextAttribute ta)
- {
- TSpriteMetaAnimateFrame ret;
- if (mSpriteCache.TryGetValue(ta.resSprite, out ret))
- {
- return ret;
- }
- string[] resSpr = ta.resSprite.Split(',');
- string file = resSpr[0];
- Cell.CPJResource res = this.AddCPJResource(file);
- if (res != null)
- {
- int anim;
- string spr_name = null;
- if (resSpr.Length >= 2)
- {
- spr_name = resSpr[1];
- }
- else
- {
- spr_name = res.Loader.DefaultSpriteName;
- }
- if (resSpr.Length >= 3)
- {
- int.TryParse(resSpr[2], out anim);
- }
- else
- {
- anim = 0;
- }
- if (spr_name != null)
- {
- CSpriteMeta spr = res.GetSpriteMeta(spr_name);
- if (spr != null)
- {
- ret.sprite = spr;
- ret.anim = anim;
- mSpriteCache.Add(ta.resSprite, ret);
- return ret;
- }
- }
- }
- return ret;
- }
-
- protected abstract Image AddImage(string path);
- protected abstract Cell.CPJResource AddCPJResource(string path);
- public abstract Drawable CreateDrawable(Region rg, object content);
- public interface Drawable : IDisposable
- {
- float CharWidth { get; }
- float CharHeight { get; }
- void Render(Graphics g, Region self, float x, float y);
- void Hide(Region self, float x, float y);
- }
-
- #region _LineAndRegion_
-
-
-
- public class Region
- {
- private readonly BaseRichTextLayer mLayer;
- public bool IsBreak { get { return mText.EndsWith("\n"); } }
- public int CharStartIndex { get { return mStartIndex; } }
- public int CharEndIndex { get { return mEndIndex; } }
- public int CharCount { get { return mEndIndex - mStartIndex; } }
- public Rectangle2D Bounds { get { return mBounds; } }
- public TextAttribute Attribute { get { return mAttribute; } }
- public string Text { get { return mText; } }
- public int Index { get { return mIndex; } }
- internal Drawable Buffer
- {
- get { return m_buffer; }
- set
- {
- if (m_buffer != null) m_buffer.Dispose();
- m_buffer = value;
- }
- }
- private Drawable m_buffer;
- internal readonly TextAttribute mAttribute;
- internal int mStartIndex;
- internal int mEndIndex;
- internal string mText;
- internal Rectangle2D mBounds = new Rectangle2D();
-
-
-
- internal int mIndex;
- internal Region(BaseRichTextLayer layer, TextAttribute ta)
- {
- this.mLayer = layer;
- this.mAttribute = ta;
- }
- internal Region[] Split(int charIndex)
- {
- if (charIndex >= 0 && charIndex < mText.Length)
- {
- Region a = new Region(mLayer, mAttribute);
- {
- a.mStartIndex = this.mStartIndex;
- a.mEndIndex = this.mStartIndex + charIndex;
- a.mText = this.mText.Substring(0, charIndex);
- }
- Region b = new Region(mLayer, mAttribute);
- {
- b.mStartIndex = this.mStartIndex + charIndex;
- b.mEndIndex = this.mEndIndex;
- b.mText = this.mText.Substring(charIndex);
- }
- return new Region[] { a, b };
- }
- return null;
- }
- public void Render(Graphics g, float px, float py)
- {
- if (m_buffer != null)
- {
- m_buffer.Render(g, this, mBounds.x + px, mBounds.y + py);
- }
- this.mLayer.OnDrawRegion(g, this, px, py);
- }
- public void Hide(float px, float py)
- {
- if (m_buffer != null)
- {
- m_buffer.Hide(this, mBounds.x + px, mBounds.y + py);
- }
- }
- internal void Dispose()
- {
- if (m_buffer != null)
- {
- m_buffer.Dispose();
- m_buffer = null;
- }
- }
- public override string ToString()
- {
- return string.Format("Region({0})", mText);
- }
- }
- public class Line
- {
- private readonly BaseRichTextLayer mLayer;
- internal int mIndex = 0;
- internal readonly Rectangle2D mBounds = new Rectangle2D();
- internal readonly List<Region> mBlocks = new List<Region>();
- internal RichTextAlignment mAnchor = RichTextAlignment.taNA;
- public int Index
- {
- get
- {
- return mIndex;
- }
- }
- public Rectangle2D Bounds
- {
- get
- {
- return mBounds;
- }
- }
- public int CharStartIndex
- {
- get
- {
- if (mBlocks.Count > 0)
- {
- return mBlocks[0].mStartIndex;
- }
- return -1;
- }
- }
- public int RegionCount
- {
- get
- {
- return mBlocks.Count;
- }
- }
- public int CharEndIndex
- {
- get
- {
- if (mBlocks.Count > 0)
- {
- return mBlocks[mBlocks.Count - 1].mEndIndex;
- }
- return -1;
- }
- }
- public RichTextAlignment Anchor
- {
- get { return mAnchor; }
- }
- internal Line(BaseRichTextLayer layer)
- {
- this.mLayer = layer;
- }
- internal void AddRegion(Region rg)
- {
- mBlocks.Add(rg);
- if (rg.Attribute.anchor != RichTextAlignment.taNA)
- {
- this.mAnchor = rg.Attribute.anchor;
- }
- }
- public void RenderLine(Graphics g, float px, float py)
- {
- for (int i = 0; i < mBlocks.Count; i++)
- {
- mBlocks[i].Render(g, px, py);
- }
- mLayer.OnDrawLine(g, this, px, py);
- }
- public void HideLine(float px, float py)
- {
- for (int i = 0; i < mBlocks.Count; i++)
- {
- mBlocks[i].Hide(px, py);
- }
- }
- }
- #endregion
-
- }
-
- public struct RichTextClickInfo
- {
- public BaseRichTextLayer.Region mRegion;
- public BaseRichTextLayer.Line mLine;
- }
- public enum RichTextAlignment
- {
- taNA = 0,
- taLEFT = 1,
- taCENTER = 2,
- taRIGHT = 3,
- }
-
- public class RichTextLayer : BaseRichTextLayer
- {
- public static bool TestDraw = false;
- public static uint TestFillContentSize = 0x80808080;
- public static uint TestDrawRegionSize = 0x000000ff;
- public static string DefaultImageRoot = "";
- public string ImageRoot = DefaultImageRoot;
- protected HashMap<string, Image> mImageMap = new HashMap<string, Image>();
- protected HashMap<string, Cell.CPJResource> mResMap = new HashMap<string, Cell.CPJResource>();
-
-
-
- protected HashMap<string, Image> mSelfImageMap = new HashMap<string, Image>();
-
-
-
- protected HashMap<string, Cell.CPJResource> mSelfResMap = new HashMap<string, Cell.CPJResource>();
- public RichTextLayer(float width = 100, RichTextAlignment anchor = RichTextAlignment.taLEFT)
- : base(width, anchor)
- {
- }
- protected override Image AddImage(string file)
- {
- Image img = mImageMap.Get(file);
- if (img == null)
- {
- img = Driver.Instance.createImage(ImageRoot + file);
- if (img != null)
- {
- mSelfImageMap.Put(file, img);
- mImageMap.Put(file, img);
- }
- }
- return img;
- }
- protected override Cell.CPJResource AddCPJResource(string file)
- {
- Cell.CPJResource res = mResMap.Get(file);
- if (res == null)
- {
- res = Cell.CPJResource.CreateResource(ImageRoot + file);
- if (res != null)
- {
- mSelfResMap.Put(file, res);
- mResMap.Put(file, res);
- }
- }
- return res;
- }
-
-
-
-
-
-
- public virtual void AddImage(string file, Image img)
- {
- if (img != null)
- {
- mImageMap.Put(file, img);
- }
- }
-
-
-
-
-
-
- public virtual void AddResource(string file, Cell.CPJResource res)
- {
- if (res != null)
- {
- mResMap.Put(file, res);
- }
- }
- public override void Render(Graphics g, float px, float py, float pw, float ph, float cx, float cy)
- {
- base.BeginRender(g);
- Blend cur_blend = g.getBlend();
- try
- {
- if (!IsEnable)
- {
- g.setBlend(Blend.BLEND_MODE_GRAY);
- }
-
- if (TestDraw && ContentWidth > 0 && ContentHeight > 0)
- {
- g.setColor(TestFillContentSize);
- switch (Alignment)
- {
- case RichTextAlignment.taLEFT:
- g.fillRect(0, 0, ContentWidth, ContentHeight);
- break;
- case RichTextAlignment.taRIGHT:
- g.fillRect(Width - ContentWidth, 0, ContentWidth, ContentHeight);
- break;
- case RichTextAlignment.taCENTER:
- g.fillRect((Width - ContentWidth) / 2, 0, ContentWidth, ContentHeight);
- break;
- }
- }
- base.InternalRender(g, px, py, pw, ph, cx, cy);
- }
- finally
- {
- g.setBlend(cur_blend);
- }
- base.AfterRender(g);
- }
- protected override void OnDrawRegion(Graphics g, Region rg, float px, float py)
- {
- if (TestDraw)
- {
- g.setColor(TestDrawRegionSize);
- g.drawRect(rg.Bounds.x + px, rg.Bounds.y + py, rg.Bounds.width, rg.Bounds.height);
- }
- }
- public override void Dispose()
- {
- base.Dispose();
- if (mSelfImageMap != null)
- {
- foreach (KeyValuePair<string, Image> kvp in mSelfImageMap)
- {
- kvp.Value.Dispose();
- }
- mSelfImageMap.Clear();
- }
- if (mSelfResMap != null)
- {
- foreach (KeyValuePair<string, Cell.CPJResource> kvp in mSelfResMap)
- {
- kvp.Value.Dispose();
- }
- mSelfResMap.Clear();
- }
- }
- public override Drawable CreateDrawable(Region rg, object content)
- {
- if (content is TextDrawable)
- {
- return content as TextDrawable;
- }
- if (content is TImageRegion)
- {
- return new DrawImage(this, rg, (TImageRegion)content);
- }
- if (content is TSpriteMetaAnimateFrame)
- {
- return new DrawSprite(this, rg, (TSpriteMetaAnimateFrame)content);
- }
- return new DrawText(this, rg, content.ToString());
- }
- public class DrawText : Drawable
- {
- private TextLayer text;
- public DrawText(RichTextLayer layer, Region rg, string content)
- {
- TextAttribute ta = rg.Attribute;
- this.text = Driver.Instance.createTextLayer(content, ta.fontSize, ta.fontStyle);
- text.IsEnable = layer.IsEnable;
- text.FontColor = ta.fontColor;
- if (ta.borderCount > 0)
- {
- text.BorderColor = ta.borderColor;
- text.BorderTime = (int)ta.borderCount;
- }
- else
- {
- text.BorderColor = layer.BorderColor;
- text.BorderTime = layer.BorderCount;
- }
- }
- public float CharWidth { get { return text.Width; } }
- public float CharHeight { get { return text.Height; } }
- public void Render(Graphics g, Region rg, float x, float y)
- {
- g.drawTextLayer(text, x, y, CommonUI.Display.Anchor.NONE);
- }
- public void Hide(Region self, float x, float y) { }
- public void Dispose()
- {
- text.Dispose();
- }
- }
- public class DrawImage : Drawable
- {
- private TImageRegion image;
- private TextAttribute ta;
- public DrawImage(RichTextLayer layer, Region rg, TImageRegion img)
- {
- this.image = img;
- this.ta = rg.Attribute;
- }
- public float CharWidth
- {
- get
- {
- if (ta.resImageZoom != null) { return ta.resImageZoom.Width; }
- return image.sw;
- }
- }
- public float CharHeight
- {
- get
- {
- if (ta.resImageZoom != null) { return ta.resImageZoom.Height; }
- return image.sh;
- }
- }
- public void Render(Graphics g, Region rg, float x, float y)
- {
- string text = rg.mText;
- int len = text.Length;
- if (ta.resImageZoom != null)
- {
- float tw = ta.resImageZoom.Width;
- float th = ta.resImageZoom.Height;
- for (int i = 0; i < len; i++)
- {
- g.drawImageZoom(image.image, x + i * tw, y, tw, th);
- }
- }
- else
- {
- for (int i = 0; i < len; i++)
- {
- g.drawImage(image.image, x + i * image.sw, y);
- }
- }
- }
- public void Hide(Region self, float x, float y) { }
- public void Dispose() { }
- }
- public class DrawSprite : Drawable
- {
- private CSpriteMeta spr;
- private int frame_count;
- private int curframe;
- private int curanim;
- private CCD bounds;
- public DrawSprite(RichTextLayer layer, Region rg, TSpriteMetaAnimateFrame spr)
- {
- this.spr = spr.sprite;
- this.curanim = spr.anim;
- this.frame_count = spr.sprite.getFrameCount(spr.anim);
- this.bounds = spr.sprite.getVisibleBounds(spr.anim);
- }
- public float CharWidth { get { return bounds.Width; } }
- public float CharHeight { get { return bounds.Height; } }
- public void Render(Graphics g, Region rg, float x, float y)
- {
- if (frame_count > 0)
- {
- string text = rg.mText;
- int len = text.Length;
- float px;
- for (int i = 0; i < len; i++)
- {
- px = x + i * bounds.Width;
- spr.render(g, curanim, curframe, px - bounds.X1, y - bounds.Y1);
- }
- curframe++;
- curframe = curframe % frame_count;
- }
- }
- public void Hide(Region self, float x, float y) { }
- public void Dispose() { }
- }
- }
-
- }
|