RichTextBox.Layer.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. using UnityEngine;
  2. using CommonUI.Cell.Game;
  3. using CommonUI.Display;
  4. using UnityImage = CommonUI_Unity3D.Impl.UnityImage;
  5. using AttributedString = CommonUI.Display.Text.AttributedString;
  6. using BaseRichTextLayer = CommonUI.Display.Text.BaseRichTextLayer;
  7. using TextAttribute = CommonUI.Display.Text.TextAttribute;
  8. using CommonUI.Display.Text;
  9. using UnityEngine.EventSystems;
  10. using System;
  11. using CommonUI.Data;
  12. namespace CommonUnity3D.UGUI
  13. { //----------------------------------------------------------------------------------------
  14. /// <summary>
  15. /// 富文本渲染器
  16. /// </summary>
  17. public class UGUIRichTextLayer : BaseRichTextLayer
  18. {
  19. /// <summary>
  20. /// 使用系统字
  21. /// </summary>
  22. public bool UseBitmapFont
  23. {
  24. get { return mUseBitmapFont; }
  25. set { mUseBitmapFont = value; }
  26. }
  27. public Font DefaultFont
  28. {
  29. get { return mFont; }
  30. set
  31. {
  32. this.mFont = value;
  33. this.mTextGenSetting.font = value;
  34. this.mTextGenSetting.fontSize = value.fontSize;
  35. }
  36. }
  37. public DisplayNode Binding
  38. {
  39. get { return mOwner; }
  40. }
  41. public TextAttribute DefaultTextAttribute
  42. {
  43. get { return mDefaultTextAttribute; }
  44. set { mDefaultTextAttribute = value; }
  45. }
  46. public string UnityRichText
  47. {
  48. set { this.XmlText = UIUtils.UnityRichTextToXmlText(value); }
  49. }
  50. public string XmlText
  51. {
  52. set
  53. {
  54. try
  55. {
  56. var atext = UIFactory.Instance.DecodeAttributedString(value, mDefaultTextAttribute);
  57. if (atext != null)
  58. {
  59. this.SetString(atext);
  60. }
  61. else
  62. {
  63. this.Text = value;
  64. }
  65. }
  66. catch (Exception err)
  67. {
  68. #if UNITY_5
  69. Debug.LogWarningFormat("{0}\n{1}", err.Message, value);
  70. #endif
  71. this.Text = value;
  72. }
  73. }
  74. }
  75. private bool mUseBitmapFont = false;
  76. private DisplayNode mOwner;
  77. private UnityEngine.Font mFont;
  78. private TextAttribute mDefaultTextAttribute;
  79. private TextGenerator mTextGen;
  80. private TextGenerationSettings mTextGenSetting = new TextGenerationSettings();
  81. private Rect mCaretBounds = new Rect(0, 0, 0, 0);
  82. private CommonUI.Data.TextAnchor mAnchor = CommonUI.Data.TextAnchor.L_T;
  83. public UGUIRichTextLayer(DisplayNode parent, bool useBitmapFont)
  84. {
  85. this.mUseBitmapFont = useBitmapFont;
  86. this.mOwner = parent;
  87. this.mFont = UIFactory.Instance.DefaultFont;
  88. this.mTextGen = UIFactory.Instance.DefaultTextGenerator;
  89. this.mTextGenSetting.color = UnityEngine.Color.white;
  90. this.mTextGenSetting.font = mFont;
  91. this.mTextGenSetting.fontSize = mFont.fontSize;
  92. this.mTextGenSetting.fontStyle = UnityEngine.FontStyle.Normal;
  93. this.mTextGenSetting.generateOutOfBounds = true;
  94. this.mTextGenSetting.generationExtents = Vector2.zero;
  95. this.mTextGenSetting.horizontalOverflow = HorizontalWrapMode.Overflow;
  96. this.mTextGenSetting.lineSpacing = 1;
  97. this.mTextGenSetting.pivot = Vector2.zero;
  98. this.mTextGenSetting.resizeTextForBestFit = false;
  99. this.mTextGenSetting.resizeTextMaxSize = 1;
  100. this.mTextGenSetting.resizeTextMinSize = 1;
  101. this.mTextGenSetting.richText = false;
  102. this.mTextGenSetting.scaleFactor = 1;
  103. this.mTextGenSetting.textAnchor = UnityEngine.TextAnchor.LowerLeft;
  104. this.mTextGenSetting.updateBounds = true;
  105. this.mTextGenSetting.verticalOverflow = VerticalWrapMode.Overflow;
  106. this.mDefaultTextAttribute = new TextAttribute(
  107. UIUtils.Color_To_UInt32_RGBA(mTextGenSetting.color),
  108. mTextGenSetting.fontSize,
  109. mTextGenSetting.font.name);
  110. }
  111. public override void Dispose()
  112. {
  113. this.mOwner = null;
  114. this.mFont = null;
  115. this.mTextGen = null;
  116. base.Dispose();
  117. }
  118. protected override Image AddImage(string file)
  119. {
  120. Image img = Driver.Instance.createImage(file);
  121. return img;
  122. }
  123. protected override CommonUI.Cell.CPJResource AddCPJResource(string file)
  124. {
  125. CommonUI.Cell.CPJResource res = CommonUI.Cell.CPJResource.CreateResource(file);
  126. return res;
  127. }
  128. protected override void OnBeginResetChars()
  129. {
  130. this.mCaretBounds.y = 0;
  131. this.mCaretBounds.x = 0;
  132. this.mCaretBounds.size = UIFactory.Instance.DefaultCaretSize;
  133. base.OnBeginResetChars();
  134. }
  135. protected override void OnEndResetLines()
  136. {
  137. base.OnEndResetLines();
  138. if (AllRegions.Count > 0)
  139. {
  140. var rg = AllRegions[AllRegions.Count - 1];
  141. var bounds = rg.Bounds;
  142. this.mCaretBounds.height = bounds.height;
  143. this.mCaretBounds.width = UIFactory.Instance.DefaultCaretSize.x;
  144. if (rg.IsBreak)
  145. {
  146. this.mCaretBounds.y = bounds.y + bounds.height;
  147. this.mCaretBounds.x = 0;
  148. }
  149. else
  150. {
  151. this.mCaretBounds.y = bounds.y;
  152. this.mCaretBounds.x = bounds.x + bounds.width;
  153. }
  154. }
  155. }
  156. protected override bool TestTextLineBreak(string text, TextAttribute ta, float testW, out float tw, out float th)
  157. {
  158. if (UseBitmapFont)
  159. {
  160. return Driver.Instance.testTextLineBreak(text, ta.fontSize, ta.fontStyle, this.BorderCount, testW, out tw, out th);
  161. }
  162. else
  163. {
  164. int fsize = (int)ta.fontSize;
  165. UnityEngine.FontStyle fstyle = (UnityEngine.FontStyle)ta.fontStyle;
  166. TextGenerationSettings setting = mTextGenSetting;
  167. setting.fontSize = fsize;
  168. setting.fontStyle = fstyle;
  169. tw = mTextGen.GetPreferredWidth(text, setting);
  170. th = mTextGen.GetPreferredHeight(text, setting);
  171. if (testW < tw)
  172. {
  173. return true;
  174. }
  175. return false;
  176. }
  177. }
  178. //--------------------------------------------------------------------------------------------
  179. #region ITextComponent
  180. public string Text
  181. {
  182. get { return base.GetText().ToString(); }
  183. set { base.SetString(new AttributedString(value, mDefaultTextAttribute)); }
  184. }
  185. public int FontSize
  186. {
  187. get { return (int)mDefaultTextAttribute.fontSize; }
  188. set { mDefaultTextAttribute.fontSize = value; }
  189. }
  190. public UnityEngine.Color FontColor
  191. {
  192. get { return UIUtils.UInt32_RGBA_To_Color(mDefaultTextAttribute.fontColor); }
  193. set { mDefaultTextAttribute.fontColor = UIUtils.Color_To_UInt32_RGBA(value); }
  194. }
  195. public CommonUI.Data.FontStyle Style
  196. {
  197. get { bool underline; return UIUtils.ToFontStyle(mDefaultTextAttribute.fontStyle, out underline); }
  198. set { mDefaultTextAttribute.fontStyle = UIUtils.ToTextLayerFontStyle(value, mDefaultTextAttribute.underline); }
  199. }
  200. public bool IsUnderline
  201. {
  202. get { return mDefaultTextAttribute.underline; }
  203. set { mDefaultTextAttribute.underline = value; }
  204. }
  205. public Vector2 TextOffset
  206. {
  207. get { return Vector2.zero; }
  208. set { }
  209. }
  210. public CommonUI.Data.TextAnchor Anchor
  211. {
  212. get { return mAnchor; }
  213. set
  214. {
  215. if (mAnchor != value)
  216. {
  217. mAnchor = value;
  218. base.SetAnchor(UIUtils.ToRichTextAnchor(value));
  219. }
  220. }
  221. }
  222. public Vector2 PreferredSize
  223. {
  224. get { return new Vector2(base.ContentWidth, base.ContentHeight); }
  225. }
  226. public Rect LastCaretPosition
  227. {
  228. get { return mCaretBounds; }
  229. }
  230. public void SetBorder(UnityEngine.Color bc, Vector2 distance)
  231. {
  232. mDefaultTextAttribute.borderCount = TextBorderCount.Border;
  233. mDefaultTextAttribute.borderColor = UIUtils.Color_To_UInt32_RGBA(bc);
  234. }
  235. public void SetShadow(UnityEngine.Color bc, Vector2 distance)
  236. {
  237. mDefaultTextAttribute.borderCount = UIUtils.ToTextShadowCount(distance);
  238. mDefaultTextAttribute.borderColor = UIUtils.Color_To_UInt32_RGBA(bc);
  239. }
  240. public void SetFont(Font font)
  241. {
  242. this.DefaultFont = font;
  243. this.mDefaultTextAttribute.fontName = font.name;
  244. }
  245. #endregion
  246. //--------------------------------------------------------------------------------------------
  247. #region Drawable
  248. public override Drawable CreateDrawable(Region rg, object content)
  249. {
  250. DisplayNode region = null;
  251. if (content is TextDrawable)
  252. {
  253. region = content as DisplayNode;
  254. }
  255. else if (content is TImageRegion)
  256. {
  257. region = new DrawImage(this, rg, (TImageRegion)content);
  258. }
  259. else if (content is TSpriteMetaAnimateFrame)
  260. {
  261. region = new DrawSprite(this, rg, (TSpriteMetaAnimateFrame)content);
  262. }
  263. else if (UseBitmapFont)
  264. {
  265. region = new DrawBitmapText(this, rg, content.ToString());
  266. }
  267. else
  268. {
  269. region = new DrawText(this, rg, content.ToString());
  270. }
  271. mOwner.AddChild(region);
  272. return region as Drawable;
  273. }
  274. //--------------------------------------------------------------------------------------------
  275. public class DrawText : TextSprite, Drawable
  276. {
  277. public DrawText(UGUIRichTextLayer layer, Region rg, string text)
  278. : base(string.Format("region {0}({1}-{2}):\"{3}\"", rg.Index, rg.CharStartIndex, rg.CharEndIndex, rg.Text))
  279. {
  280. TextAttribute ta = rg.Attribute;
  281. this.Text = text;
  282. this.Graphics.supportRichText = false;
  283. this.SetTextFont(layer.mFont, (int)ta.fontSize, (UnityEngine.FontStyle)ta.fontStyle);
  284. this.Graphics.alignment = UnityEngine.TextAnchor.UpperLeft;
  285. this.Graphics.resizeTextForBestFit = false;
  286. this.Graphics.IsUnderline = rg.Attribute.underline;
  287. this.Graphics.color = UIUtils.UInt32_RGBA_To_Color(ta.fontColor);
  288. switch (rg.Attribute.borderCount)
  289. {
  290. case CommonUI.Data.TextBorderCount.Null:
  291. break;
  292. case CommonUI.Data.TextBorderCount.Border:
  293. this.AddBorder(UIUtils.UInt32_RGBA_To_Color(ta.borderColor), new Vector2(1, 1));
  294. break;
  295. default:
  296. this.AddShadow(UIUtils.UInt32_RGBA_To_Color(ta.borderColor), UIUtils.ToTextBorderOffset(rg.Attribute.borderCount));
  297. break;
  298. }
  299. this.Size2D = new Vector2(rg.Bounds.width, rg.Bounds.height);
  300. this.Position2D = new Vector2(rg.Bounds.x, rg.Bounds.y);
  301. }
  302. public float CharWidth { get { return this.Size2D.x; } }
  303. public float CharHeight { get { return this.Size2D.y; } }
  304. public void Render(CommonUI.Display.Graphics g, Region rg, float x, float y)
  305. {
  306. this.Position2D = new Vector2(x, y);
  307. this.VisibleInParent = true;
  308. }
  309. public void Hide(BaseRichTextLayer.Region self, float x, float y)
  310. {
  311. this.Position2D = new Vector2(x, y);
  312. this.VisibleInParent = false;
  313. }
  314. }//--------------------------------------------------------------------------------------------
  315. public class DrawBitmapText : BitmapTextSprite, Drawable
  316. {
  317. public DrawBitmapText(UGUIRichTextLayer layer, Region rg, string text)
  318. : base(string.Format("region {0}({1}-{2}):\"{3}\"", rg.Index, rg.CharStartIndex, rg.CharEndIndex, rg.Text))
  319. {
  320. TextAttribute ta = rg.Attribute;
  321. this.FontSize = (int)ta.fontSize;
  322. this.FontColor = UIUtils.UInt32_RGBA_To_Color(ta.fontColor);
  323. this.Graphics.LayerFontStyle = ta.fontStyle;
  324. this.Text = text;
  325. this.Anchor = CommonUI.Data.TextAnchor.L_T;
  326. switch (rg.Attribute.borderCount)
  327. {
  328. case CommonUI.Data.TextBorderCount.Null:
  329. break;
  330. case CommonUI.Data.TextBorderCount.Border:
  331. this.Graphics.SetBorder(UIUtils.UInt32_RGBA_To_Color(ta.borderColor), new Vector2(1, 1));
  332. break;
  333. default:
  334. this.Graphics.SetShadow(UIUtils.UInt32_RGBA_To_Color(ta.borderColor), UIUtils.ToTextBorderOffset(rg.Attribute.borderCount));
  335. break;
  336. }
  337. this.Size2D = new Vector2(rg.Bounds.width, rg.Bounds.height);
  338. this.Position2D = new Vector2(rg.Bounds.x, rg.Bounds.y);
  339. }
  340. public float CharWidth { get { return this.Size2D.x; } }
  341. public float CharHeight { get { return this.Size2D.y; } }
  342. public void Render(CommonUI.Display.Graphics g, Region rg, float x, float y)
  343. {
  344. this.Position2D = new Vector2(x, y);
  345. this.VisibleInParent = true;
  346. }
  347. public void Hide(BaseRichTextLayer.Region self, float x, float y)
  348. {
  349. this.Position2D = new Vector2(x, y);
  350. this.VisibleInParent = false;
  351. }
  352. }
  353. //--------------------------------------------------------------------------------------------
  354. public class DrawImage : ImageSprite, Drawable
  355. {
  356. private TImageRegion image;
  357. private TextAttribute ta;
  358. private Vector2 csize;
  359. public DrawImage(UGUIRichTextLayer layer, Region rg, TImageRegion img)
  360. : base(string.Format("region {0}({1}-{2}):\"{3}\"", rg.Index, rg.CharStartIndex, rg.CharEndIndex, rg.Text))
  361. {
  362. this.ta = rg.Attribute;
  363. this.image = img;
  364. this.SetImage(img.image as UnityImage, new UnityEngine.Rect(img.sx, img.sy, img.sw, img.sh), new UnityEngine.Vector2(0, 0));
  365. this.Graphics.material = (img.image as UnityImage).TextureMaterial;
  366. if (rg.CharCount > 1)
  367. {
  368. this.Graphics.type = UnityEngine.UI.Image.Type.Tiled;
  369. }
  370. else
  371. {
  372. this.Graphics.type = UnityEngine.UI.Image.Type.Sliced;
  373. }
  374. if (ta.resImageZoom != null)
  375. {
  376. this.Size2D = new Vector2(ta.resImageZoom.Width * rg.CharCount, ta.resImageZoom.Height);
  377. this.csize = new Vector2(ta.resImageZoom.Width, ta.resImageZoom.Height);
  378. }
  379. else
  380. {
  381. this.Size2D = new Vector2(image.sw * rg.CharCount, image.sh);
  382. this.csize = new Vector2(image.sw, image.sh);
  383. }
  384. this.Position2D = new Vector2(rg.Bounds.x, rg.Bounds.y);
  385. }
  386. public float CharWidth { get { return csize.x; } }
  387. public float CharHeight { get { return csize.y; } }
  388. public void Render(CommonUI.Display.Graphics g, Region rg, float x, float y)
  389. {
  390. this.Position2D = new Vector2(x, y);
  391. this.VisibleInParent = true;
  392. }
  393. public void Hide(BaseRichTextLayer.Region self, float x, float y)
  394. {
  395. this.Position2D = new Vector2(x, y);
  396. this.VisibleInParent = false;
  397. }
  398. }
  399. //--------------------------------------------------------------------------------------------
  400. public class DrawSprite : CPJSprite, Drawable
  401. {
  402. private CCD bounds;
  403. public DrawSprite(UGUIRichTextLayer layer, Region rg, TSpriteMetaAnimateFrame spr)
  404. : base(string.Format("region {0}({1}-{2}):\"{3}\"", rg.Index, rg.CharStartIndex, rg.CharEndIndex, rg.Text))
  405. {
  406. this.bounds = spr.sprite.getVisibleBounds(spr.anim);
  407. this.SpriteMeta = spr.sprite;
  408. this.Controller.SetCurrentAnimate(spr.anim);
  409. if (rg.CharCount > 1)
  410. {
  411. this.Graphics.drawType = CPJSpriteGraphics.DrawType.FillGrid;
  412. this.Graphics.drawGridSize = new Vector2(bounds.Width, bounds.Height);
  413. }
  414. else
  415. {
  416. this.Graphics.drawType = CPJSpriteGraphics.DrawType.Simple;
  417. }
  418. this.Size2D = new Vector2(bounds.Width * rg.CharCount, bounds.Height);
  419. this.Position2D = new Vector2(rg.Bounds.x, rg.Bounds.y);
  420. }
  421. public float CharWidth { get { return bounds.Width; } }
  422. public float CharHeight { get { return bounds.Height; } }
  423. public void Render(CommonUI.Display.Graphics g, Region rg, float x, float y)
  424. {
  425. this.Position2D = new Vector2(x, y);
  426. this.VisibleInParent = true;
  427. }
  428. public void Hide(BaseRichTextLayer.Region self, float x, float y)
  429. {
  430. this.Position2D = new Vector2(x, y);
  431. this.VisibleInParent = false;
  432. }
  433. }
  434. #endregion
  435. //--------------------------------------------------------------------------------------------
  436. }
  437. }