TextDrawable.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. using CommonLang;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. namespace CommonUI.Display.Text
  7. {
  8. //---------------------------------------------------------------------------------------------------------
  9. public interface TextDrawable : BaseRichTextLayer.Drawable, ICloneable
  10. {
  11. bool Equals(TextDrawable obj);
  12. bool FromText(string text);
  13. }
  14. //---------------------------------------------------------------------------------------------------------
  15. public abstract class ITextDrawableFactory
  16. {
  17. static ITextDrawableFactory() { new DefaultTextDrawableFactory(); }
  18. public static ITextDrawableFactory Instance { get; private set; }
  19. public ITextDrawableFactory()
  20. {
  21. Instance = this;
  22. }
  23. public abstract TextDrawable CreateTextDrawable(string name, string value);
  24. private class DefaultTextDrawableFactory : ITextDrawableFactory
  25. {
  26. public override TextDrawable CreateTextDrawable(string name, string value)
  27. {
  28. return null;
  29. }
  30. }
  31. }
  32. //---------------------------------------------------------------------------------------------------------
  33. public class TextDrawableFactory : ITextDrawableFactory
  34. {
  35. public const string TYPE_IMAGE = "image";
  36. public const string TYPE_ATLAS = "atlas";
  37. public const string TYPE_SPRITE = "sprite";
  38. public string ResourceRoot { get; set; }
  39. protected HashMap<string, Image> mImageMap = new HashMap<string, Image>();
  40. protected HashMap<string, Cell.CPJResource> mResMap = new HashMap<string, Cell.CPJResource>();
  41. protected HashMap<string, Image> mSelfImageMap = new HashMap<string, Image>();
  42. protected HashMap<string, Cell.CPJResource> mSelfResMap = new HashMap<string, Cell.CPJResource>();
  43. private static TextDrawableFactory mInstance;
  44. public TextDrawableFactory()
  45. {
  46. ResourceRoot = "";
  47. mInstance = this;
  48. }
  49. public override TextDrawable CreateTextDrawable(string name, string value)
  50. {
  51. switch (name)
  52. {
  53. case TYPE_IMAGE:
  54. {
  55. ImageDraw ret = new ImageDraw();
  56. if (ret.FromText(value)) return ret;
  57. }
  58. break;
  59. case TYPE_ATLAS:
  60. {
  61. AtlasDraw ret = new AtlasDraw();
  62. if (ret.FromText(value)) return ret;
  63. }
  64. break;
  65. case TYPE_SPRITE:
  66. {
  67. SpriteDraw ret = new SpriteDraw();
  68. if (ret.FromText(value)) return ret;
  69. }
  70. break;
  71. }
  72. return null;
  73. }
  74. public virtual Image LoadImage(string file)
  75. {
  76. Image img = mImageMap.Get(file);
  77. if (img == null)
  78. {
  79. img = Driver.Instance.createImage(ResourceRoot + file);
  80. if (img != null)
  81. {
  82. mSelfImageMap.Put(file, img);
  83. mImageMap.Put(file, img);
  84. }
  85. }
  86. return img;
  87. }
  88. public virtual Cell.CPJResource LoadResource(string file)
  89. {
  90. Cell.CPJResource res = mResMap.Get(file);
  91. if (res == null)
  92. {
  93. res = Cell.CPJResource.CreateResource(file);
  94. if (res != null)
  95. {
  96. mSelfResMap.Put(file, res);
  97. mResMap.Put(file, res);
  98. }
  99. }
  100. return res;
  101. }
  102. public virtual void CacheImage(string file, Image img)
  103. {
  104. if (img != null)
  105. {
  106. mImageMap.Put(file, img);
  107. }
  108. }
  109. public virtual void CacheResource(string file, Cell.CPJResource res)
  110. {
  111. if (res != null)
  112. {
  113. mResMap.Put(file, res);
  114. }
  115. }
  116. public void Dispose()
  117. {
  118. mImageMap.Clear();
  119. mResMap.Clear();
  120. foreach (KeyValuePair<string, Image> kvp in mSelfImageMap)
  121. {
  122. kvp.Value.Dispose();
  123. }
  124. mSelfImageMap.Clear();
  125. foreach (KeyValuePair<string, Cell.CPJResource> kvp in mSelfResMap)
  126. {
  127. kvp.Value.Dispose();
  128. }
  129. mSelfResMap.Clear();
  130. }
  131. //---------------------------------------------------------------------------------------------------------
  132. /// <summary>
  133. /// image = "/xxx/bbb/icon.png,32,32"
  134. /// </summary>
  135. public class ImageDraw : TextDrawable
  136. {
  137. public Image ImageSrc { get; private set; }
  138. public float CharWidth { get { return zoom_w; } }
  139. public float CharHeight { get { return zoom_h; } }
  140. private float zoom_w = 0;
  141. private float zoom_h = 0;
  142. public bool FromText(string text)
  143. {
  144. string[] kvs = text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  145. if (kvs.Length > 0)
  146. {
  147. ImageSrc = mInstance.LoadImage(kvs[0]);
  148. if (ImageSrc != null)
  149. {
  150. zoom_w = ImageSrc.Width;
  151. zoom_h = ImageSrc.Height;
  152. if (kvs.Length >= 3)
  153. {
  154. float.TryParse(kvs[1], out zoom_w);
  155. float.TryParse(kvs[2], out zoom_h);
  156. }
  157. return true;
  158. }
  159. }
  160. return false;
  161. }
  162. public bool Equals(TextDrawable obj)
  163. {
  164. if (obj is ImageDraw)
  165. {
  166. var b = obj as ImageDraw;
  167. if (this.ImageSrc != b.ImageSrc) return false;
  168. if (this.zoom_w != b.zoom_w) return false;
  169. if (this.zoom_h != b.zoom_h) return false;
  170. return true;
  171. }
  172. return false;
  173. }
  174. public object Clone()
  175. {
  176. ImageDraw ret = new ImageDraw();
  177. ret.ImageSrc = this.ImageSrc;
  178. ret.zoom_w = this.zoom_w;
  179. ret.zoom_h = this.zoom_h;
  180. return ret;
  181. }
  182. public void Render(Graphics g, RichTextLayer.Region rg, float x, float y)
  183. {
  184. g.drawImageZoom(ImageSrc, x, y, zoom_w, zoom_h);
  185. }
  186. public void Hide(BaseRichTextLayer.Region self, float x, float y) { }
  187. public void Dispose()
  188. {
  189. }
  190. }
  191. //---------------------------------------------------------------------------------------------------------
  192. /// <summary>
  193. /// atlas = "/xxx/bbb/output/icons.xml,image_icon,32"
  194. /// </summary>
  195. public class AtlasDraw : TextDrawable
  196. {
  197. public Cell.CPJAtlas Atlas { get; private set; }
  198. public float CharWidth { get; private set; }
  199. public float CharHeight { get; private set; }
  200. private int tile_id = 0;
  201. public bool FromText(string text)
  202. {
  203. string[] kvs = text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  204. if (kvs.Length >= 3)
  205. {
  206. Cell.CPJResource res = mInstance.LoadResource(kvs[0]);
  207. if (res != null)
  208. {
  209. this.Atlas = res.GetAtlas(kvs[1]);
  210. if (Atlas != null && int.TryParse(kvs[2], out tile_id))
  211. {
  212. CharWidth = Atlas.getWidth(tile_id);
  213. CharHeight = Atlas.getHeight(tile_id);
  214. return true;
  215. }
  216. }
  217. }
  218. return false;
  219. }
  220. public bool Equals(TextDrawable obj)
  221. {
  222. if (obj is AtlasDraw)
  223. {
  224. var b = obj as AtlasDraw;
  225. if (this.Atlas != b.Atlas)
  226. return false;
  227. if (this.tile_id != b.tile_id)
  228. return false;
  229. return true;
  230. }
  231. return false;
  232. }
  233. public object Clone()
  234. {
  235. AtlasDraw ret = new AtlasDraw();
  236. ret.Atlas = this.Atlas;
  237. ret.tile_id = this.tile_id;
  238. ret.CharWidth = this.CharWidth;
  239. ret.CharHeight = this.CharHeight;
  240. return ret;
  241. }
  242. public void Render(Graphics g, RichTextLayer.Region rg, float x, float y)
  243. {
  244. Atlas.render(g, tile_id, x, y, Trans.TRANS_NONE);
  245. }
  246. public void Hide(BaseRichTextLayer.Region self, float x, float y) { }
  247. public void Dispose()
  248. {
  249. }
  250. }
  251. //---------------------------------------------------------------------------------------------------------
  252. public class SpriteDraw : TextDrawable
  253. {
  254. public CommonUI.Cell.Game.CSpriteMeta SpriteSrc { get; private set; }
  255. public float CharWidth { get { return bounds.Width; } }
  256. public float CharHeight { get { return bounds.Height; } }
  257. private int anim;
  258. private int frame_count;
  259. private int frame = 0;
  260. private CommonUI.Cell.Game.CCD bounds;
  261. public bool FromText(string text)
  262. {
  263. string[] kvs = text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  264. if (kvs.Length >= 3)
  265. {
  266. Cell.CPJResource res = mInstance.LoadResource(kvs[0]);
  267. if (res != null)
  268. {
  269. this.SpriteSrc = res.GetSpriteMeta(kvs[1]);
  270. if (SpriteSrc != null && int.TryParse(kvs[2], out anim))
  271. {
  272. this.bounds = SpriteSrc.getVisibleBounds(anim);
  273. this.frame_count = SpriteSrc.getFrameCount(anim);
  274. return true;
  275. }
  276. }
  277. }
  278. return false;
  279. }
  280. public bool Equals(TextDrawable obj)
  281. {
  282. if (obj is SpriteDraw)
  283. {
  284. var b = obj as SpriteDraw;
  285. if (this.SpriteSrc != b.SpriteSrc)
  286. return false;
  287. if (this.anim != b.anim)
  288. return false;
  289. return true;
  290. }
  291. return false;
  292. }
  293. public object Clone()
  294. {
  295. SpriteDraw ret = new SpriteDraw();
  296. ret.SpriteSrc = this.SpriteSrc;
  297. ret.anim = this.anim;
  298. ret.frame_count = this.frame_count;
  299. ret.bounds = this.bounds;
  300. return ret;
  301. }
  302. public void Render(Graphics g, RichTextLayer.Region rg, float x, float y)
  303. {
  304. SpriteSrc.render(g, anim, frame, x - bounds.X1, y - bounds.Y1);
  305. frame++;
  306. frame = frame % frame_count;
  307. }
  308. public void Hide(BaseRichTextLayer.Region self, float x, float y) { }
  309. public void Dispose()
  310. {
  311. }
  312. }
  313. //---------------------------------------------------------------------------------------------------------
  314. }
  315. }