Res.DesignExt.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Windows.Forms;
  4. using System.Drawing;
  5. using System.Reflection;
  6. using System.IO;
  7. #if !MONO
  8. using FastReport.DevComponents.DotNetBar;
  9. #endif
  10. namespace FastReport.Utils
  11. {
  12. partial class Res
  13. {
  14. private class ImageInfo
  15. {
  16. private int dpi;
  17. private List<Bitmap> images;
  18. private ImageList imageList;
  19. private bool imagesLoaded = false;
  20. public List<Bitmap> Images
  21. {
  22. get
  23. {
  24. if (!imagesLoaded)
  25. LoadImages();
  26. return images;
  27. }
  28. }
  29. private Bitmap AddImage(Bitmap srcImage, int x, int y, int srcImageSize)
  30. {
  31. int destImageSize = (int)Math.Round(16 * dpi / 96f);
  32. Bitmap image = new Bitmap(destImageSize, destImageSize);
  33. // Upscaling images contained in buttons.png produces artifacts.
  34. // Copy the portion of image to slice then upscale it.
  35. Bitmap slice = null;
  36. if (srcImage.Width > srcImageSize)
  37. {
  38. slice = new Bitmap(srcImageSize, srcImageSize);
  39. using (Graphics g = Graphics.FromImage(slice))
  40. {
  41. g.DrawImage(srcImage, new Rectangle(0, 0, srcImageSize, srcImageSize), x, y, srcImageSize, srcImageSize, GraphicsUnit.Pixel);
  42. }
  43. x = 0;
  44. y = 0;
  45. srcImage = slice;
  46. }
  47. using (Graphics g = Graphics.FromImage(image))
  48. {
  49. g.DrawImage(srcImage, new Rectangle(0, 0, destImageSize, destImageSize), x, y, srcImageSize, srcImageSize, GraphicsUnit.Pixel);
  50. }
  51. images.Add(image);
  52. if (slice != null)
  53. slice.Dispose();
  54. return image;
  55. }
  56. private void LoadImages()
  57. {
  58. imagesLoaded = true;
  59. images = new List<Bitmap>();
  60. const string resName = "buttons.png"; // the image must contain 10 icons in a row
  61. using (Bitmap allImages = LoadResourceImage(resName, dpi))
  62. {
  63. int srcImageSize = allImages.Width / 10;
  64. int x = 0;
  65. int y = 0;
  66. bool done = false;
  67. do
  68. {
  69. AddImage(allImages, x, y, srcImageSize);
  70. x += srcImageSize;
  71. if (x >= allImages.Width)
  72. {
  73. x = 0;
  74. y += srcImageSize;
  75. }
  76. done = y > allImages.Height;
  77. }
  78. while (!done);
  79. }
  80. }
  81. private void CreateImageList()
  82. {
  83. imageList = new ImageList();
  84. int imageSize = images[0].Width;
  85. imageList.ImageSize = new Size(imageSize, imageSize);
  86. imageList.ColorDepth = ColorDepth.Depth32Bit;
  87. foreach (Bitmap bmp in images)
  88. {
  89. imageList.Images.Add(bmp);
  90. }
  91. }
  92. public ImageList GetImages()
  93. {
  94. if (!imagesLoaded)
  95. LoadImages();
  96. if (imageList == null)
  97. CreateImageList();
  98. return imageList;
  99. }
  100. public Bitmap GetImage(int index)
  101. {
  102. if (index < 0)
  103. return null;
  104. if (!imagesLoaded)
  105. LoadImages();
  106. return images[index];
  107. }
  108. // for images added by user
  109. public int AddImage(Bitmap img)
  110. {
  111. // ensure everything is loaded
  112. GetImages();
  113. Bitmap image = AddImage(img, 0, 0, img.Width);
  114. imageList.Images.Add(image);
  115. return images.Count - 1;
  116. }
  117. public ImageInfo(int dpi)
  118. {
  119. this.dpi = dpi;
  120. }
  121. }
  122. private readonly static Dictionary<int, ImageInfo> dpiAwareImages = new Dictionary<int, ImageInfo>();
  123. private static Bitmap LoadResourceImage(string name, int dpi, bool scaleToTargetSize = false)
  124. {
  125. // loads appropriate image for given dpi and current icon pack
  126. // - original name: "name.png"
  127. // - high dpi: "name-hi.png"
  128. // - other image pack: "name-1.png", "name-1-hi.png"
  129. //
  130. // Notes:
  131. // - the image with original name (for 96dpi) must exist. It will be used to determine the target size.
  132. // - if no image pack or hi-version of image exists, the original image is used. Scaling is performed if needed.
  133. string originalName = name;
  134. Bitmap originalImage = ResourceLoader.GetBitmap(originalName);
  135. Bitmap srcImage = null;
  136. Size destImageSize = new Size((int)Math.Round(originalImage.Width * dpi / 96f), (int)Math.Round(originalImage.Height * dpi / 96f));
  137. int iconPack = Config.IconPack;
  138. if (iconPack != 0)
  139. name = Path.GetFileNameWithoutExtension(originalName) + "-" + iconPack.ToString() + Path.GetExtension(originalName);
  140. // high dpi images
  141. if (dpi >= 144)
  142. name = Path.GetFileNameWithoutExtension(name) + "-hi" + Path.GetExtension(originalName);
  143. srcImage = ResourceLoader.GetBitmap(name);
  144. if (srcImage == null)
  145. {
  146. // no image exist, use the original one
  147. srcImage = originalImage;
  148. }
  149. // scale to target size
  150. if (scaleToTargetSize)
  151. {
  152. Bitmap destImage = new Bitmap(destImageSize.Width, destImageSize.Height);
  153. using (Graphics g = Graphics.FromImage(destImage))
  154. {
  155. g.DrawImage(srcImage, new Rectangle(0, 0, destImageSize.Width, destImageSize.Height));
  156. }
  157. return destImage;
  158. }
  159. return srcImage;
  160. }
  161. private static int CheckDpi(int dpi)
  162. {
  163. if (!dpiAwareImages.ContainsKey(dpi))
  164. dpiAwareImages.Add(dpi, new ImageInfo(dpi));
  165. return dpi;
  166. }
  167. private static int CheckUserImages(int dpi)
  168. {
  169. if (dpi != 96)
  170. {
  171. // if image list has less images than 96-dpi image list, add user images to image list
  172. List<Bitmap> images96 = dpiAwareImages[CheckDpi(96)].Images;
  173. List<Bitmap> images = dpiAwareImages[CheckDpi(dpi)].Images;
  174. for (int i = images.Count; i < images96.Count; i++)
  175. dpiAwareImages[dpi].AddImage(images96[i]);
  176. }
  177. return dpi;
  178. }
  179. /// <summary>
  180. /// Adds user image to 96 dpi images.
  181. /// </summary>
  182. /// <param name="img">User image (16x16 pixels).</param>
  183. /// <returns>Image index in the image list.</returns>
  184. internal static int AddImage(Bitmap img)
  185. {
  186. return dpiAwareImages[CheckDpi(96)].AddImage(img);
  187. }
  188. /// <summary>
  189. /// Gets the standard images used in FastReport as an <b>ImageList</b>.
  190. /// </summary>
  191. /// <returns><b>ImageList</b> object that contains standard images.</returns>
  192. /// <remarks>
  193. /// FastReport contains about 240 truecolor images of 16x16 size that are stored in one
  194. /// big image side-by-side. This image can be found in FastReport resources (the "buttons.png" resource).
  195. /// </remarks>
  196. public static ImageList GetImages(int dpi)
  197. {
  198. return dpiAwareImages[CheckUserImages(CheckDpi(dpi))].GetImages();
  199. }
  200. /// <summary>
  201. /// Gets an image with specified index.
  202. /// </summary>
  203. /// <param name="index">Image index (zero-based).</param>
  204. /// <param name="dpi">Dpi value (96 for base dpi).</param>
  205. /// <returns>The image with specified index.</returns>
  206. /// <remarks>
  207. /// FastReport contains about 240 truecolor images of 16x16 size that are stored in one
  208. /// big image side-by-side. This image can be found in FastReport resources (the "buttons.png" resource).
  209. /// </remarks>
  210. public static Bitmap GetImage(int index, int dpi)
  211. {
  212. return dpiAwareImages[CheckUserImages(CheckDpi(dpi))].GetImage(index);
  213. }
  214. /// <summary>
  215. /// Gets an image with specified name from resources.
  216. /// </summary>
  217. /// <param name="name">The name of image resource.</param>
  218. /// <param name="dpi">Dpi value (96 for base dpi).</param>
  219. /// <returns>The image.</returns>
  220. public static Bitmap GetImage(string name, int dpi)
  221. {
  222. return LoadResourceImage(name, dpi, true);
  223. }
  224. /// <summary>
  225. /// Gets an image with specified index and converts it to <b>Icon</b>.
  226. /// </summary>
  227. /// <param name="index">Image index (zero-based).</param>
  228. /// <param name="dpi">Dpi value (96 for base dpi).</param>
  229. /// <returns>The <b>Icon</b> object.</returns>
  230. public static Icon GetIcon(int index, int dpi)
  231. {
  232. return Icon.FromHandle(GetImage(index, dpi).GetHicon());
  233. }
  234. #if !MONO
  235. static partial void ResDesignExt()
  236. {
  237. // for using FastReport.dll without FastReport.Bars.dll if the designer is not shown
  238. foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
  239. {
  240. if (a.ManifestModule.Name == "FastReport.Bars.dll")
  241. {
  242. RegisterLocalizeStringEventHandler();
  243. break;
  244. }
  245. }
  246. }
  247. private static void RegisterLocalizeStringEventHandler()
  248. {
  249. LocalizationKeys.LocalizeString += new DotNetBarManager.LocalizeStringEventHandler(LocalizationKeys_LocalizeString);
  250. }
  251. private static void LocalizationKeys_LocalizeString(object sender, LocalizeEventArgs e)
  252. {
  253. switch (e.Key)
  254. {
  255. case "barsys_autohide_tooltip":
  256. e.LocalizedValue = Res.Get("Designer,ToolWindow,AutoHide");
  257. e.Handled = true;
  258. break;
  259. case "barsys_close_tooltip":
  260. e.LocalizedValue = Res.Get("Designer,ToolWindow,Close");
  261. e.Handled = true;
  262. break;
  263. case "cust_mnu_addremove":
  264. e.LocalizedValue = Res.Get("Designer,Toolbar,AddOrRemove");
  265. e.Handled = true;
  266. break;
  267. case "sys_morebuttons":
  268. e.LocalizedValue = Res.Get("Designer,Toolbar,MoreButtons");
  269. e.Handled = true;
  270. break;
  271. }
  272. }
  273. #endif
  274. }
  275. }