using FastReport.Utils; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; namespace FastReport.Controls { internal class ToolStripFontComboBox : ToolStripComboBox { private List mruFonts; private List existingFonts; private FontStyle[] styles; private string fontName; public new Control Owner { get; set; } public event EventHandler FontSelected; [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string FontName { get { return (string)ComboBox.SelectedItem; } set { fontName = value; int i = ComboBox.Items.IndexOf(value); if (i != -1) ComboBox.SelectedIndex = i; else ComboBox.SelectedItem = null; } } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string MruFonts { get { string result = ""; foreach (string s in mruFonts) result += "," + s; if (result.StartsWith(",")) result = result.Substring(1); return result; } set { mruFonts.Clear(); if (!String.IsNullOrEmpty(value)) { string[] fonts = value.Split(','); foreach (string s in fonts) mruFonts.Add(s); } UpdateFonts(); } } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new System.Windows.Forms.ComboBox.ObjectCollection Items { get { return base.Items; } } private FontStyle GetFirstAvailableFontStyle(FontFamily family) { foreach (FontStyle style in styles) { if (family.IsStyleAvailable(style)) return style; } return FontStyle.Regular; } private void ComboBox_DrawItem(object sender, DrawItemEventArgs e) { if (!Enabled) return; Graphics g = e.Graphics; e.DrawBackground(); if ((e.State & DrawItemState.ComboBoxEdit) > 0) { if (!String.IsNullOrEmpty(fontName)) TextRenderer.DrawText(g, fontName, e.Font, e.Bounds, e.ForeColor, TextFormatFlags.VerticalCenter); } else if (e.Index >= 0) { string name = (string)Items[e.Index]; if (!existingFonts.Contains(name)) return; int _16 = Owner.LogicalToDevice(16); int _20 = Owner.LogicalToDevice(20); int _28 = Owner.LogicalToDevice(28); using (FontFamily family = FontManager.GetFontFamilyOrDefault(name)) using (Font font = Owner.LogicalToDevice(new Font(family, 14, GetFirstAvailableFontStyle(family)), true)) { g.DrawImage(Owner.GetImage(59), e.Bounds.X + 2, e.Bounds.Y + (e.Bounds.Height - _16) / 2); LOGFONT lf = new LOGFONT(); font.ToLogFont(lf); if (lf.lfCharSet == 2) { var sz = g.MeasureString(name, e.Font); int w = (int)sz.Width; TextRenderer.DrawText(g, name, e.Font, new Point(e.Bounds.X + _20, e.Bounds.Y + (e.Bounds.Height - (int)sz.Height) / 2), e.ForeColor); sz = g.MeasureString(name, font); TextRenderer.DrawText(g, name, font, new Point(e.Bounds.X + w + _28, e.Bounds.Y + (e.Bounds.Height - (int)sz.Height) / 2), e.ForeColor); } else { var sz = g.MeasureString(name, font); TextRenderer.DrawText(g, name, font, new Point(e.Bounds.X + _20, e.Bounds.Y + (e.Bounds.Height - (int)sz.Height) / 2), e.ForeColor); } if (e.Index == mruFonts.Count - 1) { int _1 = Owner.LogicalToDevice(1); int _3 = Owner.LogicalToDevice(3); g.DrawLine(Pens.Gray, e.Bounds.Left, e.Bounds.Bottom - _3, e.Bounds.Right, e.Bounds.Bottom - _3); g.DrawLine(Pens.Gray, e.Bounds.Left, e.Bounds.Bottom - _1, e.Bounds.Right, e.Bounds.Bottom - _1); } } } } private void ComboBox_MeasureItem(object sender, MeasureItemEventArgs e) { if (Owner != null) e.ItemHeight = Owner.LogicalToDevice(24); } private void ComboBox_SelectionChangeCommitted(object sender, EventArgs e) { OnFontSelected(); if (mruFonts.Contains(FontName)) mruFonts.Remove(FontName); mruFonts.Insert(0, FontName); while (mruFonts.Count > 5) mruFonts.RemoveAt(5); UpdateFonts(); FontName = fontName; } private void OnFontSelected() { if (FontSelected != null) FontSelected(this, EventArgs.Empty); } private void UpdateFonts() { Items.Clear(); foreach (string s in mruFonts) { if (existingFonts.Contains(s)) Items.Add(s); } foreach (string s in existingFonts) { Items.Add(s); } } public void UpdateDpiDependencies() { ComboBox.ItemHeight = Owner.LogicalToDevice(15); DropDownHeight = Owner.LogicalToDevice(302); DropDownWidth = Owner.LogicalToDevice(270); } public void SetStyle(UIStyle style) { } public ToolStripFontComboBox() { mruFonts = new List(); existingFonts = new List(); styles = new FontStyle[] { FontStyle.Regular, FontStyle.Bold, FontStyle.Italic, FontStyle.Strikeout, FontStyle.Underline }; foreach (FontFamily family in FontManager.AllFamilies) { existingFonts.Add(family.Name); } existingFonts.Sort(); AutoSize = false; ComboBox.DrawMode = DrawMode.OwnerDrawVariable; ComboBox.DropDownStyle = ComboBoxStyle.DropDownList; ComboBox.DrawItem += ComboBox_DrawItem; ComboBox.MeasureItem += ComboBox_MeasureItem; ComboBox.SelectionChangeCommitted += ComboBox_SelectionChangeCommitted; UpdateFonts(); } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] private class LOGFONT { public int lfHeight; public int lfWidth; public int lfEscapement; public int lfOrientation; public int lfWeight; public byte lfItalic; public byte lfUnderline; public byte lfStrikeOut; public byte lfCharSet; public byte lfOutPrecision; public byte lfClipPrecision; public byte lfQuality; public byte lfPitchAndFamily; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string lfFaceName; } } }