FontComboBoxItem.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using System.ComponentModel;
  5. using System.Drawing;
  6. using System.Windows.Forms;
  7. using FastReport.Utils;
  8. using FastReport.DevComponents.DotNetBar;
  9. namespace FastReport.Controls
  10. {
  11. internal class FontComboBoxItem : ComboBoxItem
  12. {
  13. private List<string> mruFonts;
  14. private List<string> existingFonts;
  15. private FontStyle[] styles;
  16. private string fontName;
  17. public event EventHandler FontSelected;
  18. public Control Owner { get; set; }
  19. [Browsable(false)]
  20. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  21. public string FontName
  22. {
  23. get { return (string)SelectedItem; }
  24. set
  25. {
  26. fontName = value;
  27. int i = Items.IndexOf(value);
  28. if (i != -1)
  29. SelectedIndex = i;
  30. else
  31. SelectedItem = null;
  32. }
  33. }
  34. [Browsable(false)]
  35. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  36. public string MruFonts
  37. {
  38. get
  39. {
  40. string result = "";
  41. foreach (string s in mruFonts)
  42. result += "," + s;
  43. if (result.StartsWith(","))
  44. result = result.Substring(1);
  45. return result;
  46. }
  47. set
  48. {
  49. mruFonts.Clear();
  50. if (!String.IsNullOrEmpty(value))
  51. {
  52. string[] fonts = value.Split(',');
  53. foreach (string s in fonts)
  54. mruFonts.Add(s);
  55. }
  56. UpdateFonts();
  57. }
  58. }
  59. [Browsable(false)]
  60. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  61. public new System.Windows.Forms.ComboBox.ObjectCollection Items
  62. {
  63. get { return base.Items; }
  64. }
  65. private FontStyle GetFirstAvailableFontStyle(FontFamily family)
  66. {
  67. foreach (FontStyle style in styles)
  68. {
  69. if (family.IsStyleAvailable(style))
  70. return style;
  71. }
  72. return FontStyle.Regular;
  73. }
  74. private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
  75. {
  76. if ((e.State & DrawItemState.Disabled) > 0)
  77. return;
  78. Graphics g = e.Graphics;
  79. e.DrawBackground();
  80. if ((e.State & DrawItemState.ComboBoxEdit) > 0)
  81. {
  82. TextRenderer.DrawText(g, Text, e.Font, e.Bounds.Location, e.ForeColor);
  83. }
  84. else if (e.Index >= 0)
  85. {
  86. string name = (string)Items[e.Index];
  87. if (!existingFonts.Contains(name))
  88. return;
  89. using (FontFamily family = new FontFamily(name))
  90. using (Font font = Owner.LogicalToDevice(new Font(name, 14, GetFirstAvailableFontStyle(family)), true))
  91. {
  92. g.DrawImage(Owner.GetImage(59), e.Bounds.X + 2, e.Bounds.Y + 2);
  93. LOGFONT lf = new LOGFONT();
  94. font.ToLogFont(lf);
  95. SizeF sz;
  96. if (lf.lfCharSet == 2)
  97. {
  98. sz = g.MeasureString(name, e.Font);
  99. int w = (int)sz.Width;
  100. TextRenderer.DrawText(g, name, e.Font, new Point(e.Bounds.X + 20, e.Bounds.Y + (e.Bounds.Height - (int)sz.Height) / 2), e.ForeColor);
  101. sz = g.MeasureString(name, font);
  102. TextRenderer.DrawText(g, name, font, new Point(e.Bounds.X + w + 28, e.Bounds.Y + (e.Bounds.Height - (int)sz.Height) / 2), e.ForeColor);
  103. }
  104. else
  105. {
  106. sz = g.MeasureString(name, font);
  107. TextRenderer.DrawText(g, name, font, new Point(e.Bounds.X + 20, e.Bounds.Y + (e.Bounds.Height - (int)sz.Height) / 2), e.ForeColor);
  108. }
  109. if (e.Index == mruFonts.Count - 1)
  110. {
  111. g.DrawLine(Pens.Gray, e.Bounds.Left, e.Bounds.Bottom - 3, e.Bounds.Right, e.Bounds.Bottom - 3);
  112. g.DrawLine(Pens.Gray, e.Bounds.Left, e.Bounds.Bottom - 1, e.Bounds.Right, e.Bounds.Bottom - 1);
  113. }
  114. }
  115. }
  116. }
  117. private void ComboBox_MeasureItem(object sender, MeasureItemEventArgs e)
  118. {
  119. if (Owner != null)
  120. e.ItemHeight = Owner.LogicalToDevice(24);
  121. }
  122. private void ComboBox_SelectionChangeCommitted(object sender, EventArgs e)
  123. {
  124. OnFontSelected();
  125. string fontName = FontName;
  126. if (mruFonts.Contains(fontName))
  127. mruFonts.Remove(fontName);
  128. mruFonts.Insert(0, fontName);
  129. while (mruFonts.Count > 5)
  130. mruFonts.RemoveAt(5);
  131. UpdateFonts();
  132. Text = fontName;
  133. }
  134. private void ComboBoxEx_EnabledChanged(object sender, EventArgs e)
  135. {
  136. if (ComboBoxEx.Enabled)
  137. ComboBoxEx.DropDownStyle = ComboBoxStyle.DropDown;
  138. else
  139. ComboBoxEx.DropDownStyle = ComboBoxStyle.DropDownList;
  140. }
  141. private void OnFontSelected()
  142. {
  143. if (FontSelected != null)
  144. FontSelected(this, EventArgs.Empty);
  145. }
  146. private void UpdateFonts()
  147. {
  148. Items.Clear();
  149. foreach (string s in mruFonts)
  150. {
  151. if (existingFonts.Contains(s))
  152. Items.Add(s);
  153. }
  154. foreach (string s in existingFonts)
  155. {
  156. Items.Add(s);
  157. }
  158. }
  159. public new void UpdateDpiDependencies()
  160. {
  161. base.UpdateDpiDependencies();
  162. ItemHeight = Owner.LogicalToDevice(14);
  163. ComboWidth = Owner.LogicalToDevice(130);
  164. DropDownHeight = Owner.LogicalToDevice(300);
  165. DropDownWidth = Owner.LogicalToDevice(370);
  166. }
  167. public FontComboBoxItem()
  168. {
  169. mruFonts = new List<string>();
  170. existingFonts = new List<string>();
  171. styles = new FontStyle[] { FontStyle.Regular, FontStyle.Bold, FontStyle.Italic,
  172. FontStyle.Strikeout, FontStyle.Underline };
  173. foreach (FontFamily family in FontFamily.Families)
  174. {
  175. existingFonts.Add(family.Name);
  176. }
  177. ComboBoxEx.DrawMode = DrawMode.OwnerDrawVariable;
  178. ComboBoxEx.DropDownStyle = ComboBoxStyle.DropDown;
  179. ComboBoxEx.DrawItem += new DrawItemEventHandler(ComboBox_DrawItem);
  180. ComboBoxEx.MeasureItem += new MeasureItemEventHandler(ComboBox_MeasureItem);
  181. ComboBoxEx.SelectionChangeCommitted += new EventHandler(ComboBox_SelectionChangeCommitted);
  182. ComboBoxEx.EnabledChanged += new EventHandler(ComboBoxEx_EnabledChanged);
  183. ComboBoxEx.DisableInternalDrawing = true;
  184. UpdateFonts();
  185. }
  186. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  187. private class LOGFONT
  188. {
  189. public int lfHeight;
  190. public int lfWidth;
  191. public int lfEscapement;
  192. public int lfOrientation;
  193. public int lfWeight;
  194. public byte lfItalic;
  195. public byte lfUnderline;
  196. public byte lfStrikeOut;
  197. public byte lfCharSet;
  198. public byte lfOutPrecision;
  199. public byte lfClipPrecision;
  200. public byte lfQuality;
  201. public byte lfPitchAndFamily;
  202. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
  203. public string lfFaceName;
  204. }
  205. }
  206. }