using System.Drawing; using Developpez.Dotnet.Collections; namespace Developpez.Dotnet.Drawing { /// /// Gère un cache de polices de caractères, ce qui permet d'éviter de recréer des instances de Font /// lorsqu'on veut réutiliser la même police. Appeler la méthode GetFont avec les mêmes paramètres /// renverra toujours la même instance de Font. /// public class FontCache { private class FontProperties { public FontProperties() { this.GdiCharSet = 1; this.Style = FontStyle.Regular; this.Unit = GraphicsUnit.Point; } public FontProperties(Font font) { this.FontFamily = font.FontFamily; this.GdiCharSet = font.GdiCharSet; this.GdiVerticalFont = font.GdiVerticalFont; this.Size = font.Size; this.Style = font.Style; this.Unit = font.Unit; } public FontFamily FontFamily { get; set; } public byte GdiCharSet { get; set; } public bool GdiVerticalFont { get; set; } public float Size { get; set; } public FontStyle Style { get; set; } public GraphicsUnit Unit { get; set; } public override bool Equals(object obj) { FontProperties other = obj as FontProperties; if (other == null) return false; if (!this.FontFamily.SafeEquals(other.FontFamily)) return false; if (this.GdiCharSet != other.GdiCharSet) return false; if (this.GdiVerticalFont != other.GdiVerticalFont) return false; if (this.Size != other.Size) return false; if (this.Style != other.Style) return false; if (this.Unit != other.Unit) return false; return true; } public override int GetHashCode() { int hash = 983; if (this.FontFamily != null) hash = hash * 457 + this.FontFamily.GetHashCode(); hash = hash * 457 + this.GdiCharSet.GetHashCode(); hash = hash * 457 + this.GdiVerticalFont.GetHashCode(); hash = hash * 457 + this.Size.GetHashCode(); hash = hash * 457 + this.Style.GetHashCode(); hash = hash * 457 + this.Unit.GetHashCode(); return hash; } public Font CreateFont() { Font font = new Font(this.FontFamily, this.Size, this.Style, this.Unit, this.GdiCharSet, this.GdiVerticalFont); return font; } } private readonly DefaultDictionary _cache; /// /// Initialise une nouvelle instance de FontCache /// public FontCache() { _cache = new DefaultDictionary(GetFontInternal, true); } /// /// Retourne une police à partir d'une police existante et du style spécifié /// /// Police à partir de laquelle obtenir une nouvelle police /// Style de la police souhaitée /// Une police avec les caractéristiques spécifiées public Font GetFont(Font prototype, FontStyle newStyle) { FontProperties prop = new FontProperties(prototype) { Style = newStyle }; return GetFont(prop); } /// /// Retourne une police avec la famille de la taille spécifiées /// /// Famille de la police à obtenir /// Taille en points de la police souhaitée /// Une police avec les caractéristiques spécifiées public Font GetFont(FontFamily family, float emSize) { FontProperties prop = new FontProperties { FontFamily = family, Size = emSize }; return GetFont(prop); } /// /// Retourne une police de la famille et de la taille spécifiées /// /// Nom de la famille de la police à obtenir /// Taille en points de la police souhaitée /// Une police avec les caractéristiques spécifiées public Font GetFont(string familyName, float emSize) { FontProperties prop = new FontProperties { FontFamily = GetFontFamily(familyName), Size = emSize, GdiVerticalFont = IsVerticalName(familyName) }; return GetFont(prop); } /// /// Retourne une police avec la famille, la taille et le style spécifiés /// /// Famille de la police à obtenir /// Taille en points de la police souhaitée /// Style de la police souhaitée /// Une police avec les caractéristiques spécifiées public Font GetFont(FontFamily family, float emSize, FontStyle style) { FontProperties prop = new FontProperties { FontFamily = family, Size = emSize, Style = style }; return GetFont(prop); } /// /// Retourne une police avec la famille, la taille et l'unité spécifiées /// /// Famille de la police à obtenir /// Taille de la police souhaitée, dans l'unité spécifiée /// Unité de taille à utiliser /// Une police avec les caractéristiques spécifiées public Font GetFont(FontFamily family, float emSize, GraphicsUnit unit) { FontProperties prop = new FontProperties { FontFamily = family, Size = emSize, Unit = unit }; return GetFont(prop); } /// /// Retourne une police avec la famille, la taille et le style spécifiés /// /// Nom de la famille de la police à obtenir /// Taille en points de la police souhaitée /// Style de la police souhaitée /// Une police avec les caractéristiques spécifiées public Font GetFont(string familyName, float emSize, FontStyle style) { FontProperties prop = new FontProperties { FontFamily = GetFontFamily(familyName), Size = emSize, Style = style, GdiVerticalFont = IsVerticalName(familyName) }; return GetFont(prop); } /// /// Retourne une police avec la famille, la taille et l'unité spécifiées /// /// Nom de la famille de la police à obtenir /// Taille de la police souhaitée, dans l'unité spécifiée /// Unité de taille à utiliser /// Une police avec les caractéristiques spécifiées public Font GetFont(string familyName, float emSize, GraphicsUnit unit) { FontProperties prop = new FontProperties { FontFamily = GetFontFamily(familyName), Size = emSize, Unit = unit, GdiVerticalFont = IsVerticalName(familyName) }; return GetFont(prop); } /// /// Retourne une police avec les caractéristiques spécifiées /// /// Famille de la police à obtenir /// Taille de la police souhaitée, dans l'unité spécifiée /// Style de la police souhaitée /// Unité de taille à utiliser /// Une police avec les caractéristiques spécifiées public Font GetFont(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit) { FontProperties prop = new FontProperties { FontFamily = family, Size = emSize, Style = style, Unit = unit }; return GetFont(prop); } /// /// Retourne une police avec les caractéristiques spécifiées /// /// Nom de la famille de la police à obtenir /// Taille de la police souhaitée, dans l'unité spécifiée /// Style de la police souhaitée /// Unité de taille à utiliser /// Une police avec les caractéristiques spécifiées public Font GetFont(string familyName, float emSize, FontStyle style, GraphicsUnit unit) { FontProperties prop = new FontProperties { FontFamily = GetFontFamily(familyName), Size = emSize, Style = style, Unit = unit, GdiVerticalFont = IsVerticalName(familyName) }; return GetFont(prop); } /// /// Retourne une police avec les caractéristiques spécifiées /// /// Famille de la police à obtenir /// Taille de la police souhaitée, dans l'unité spécifiée /// Style de la police souhaitée /// Unité de taille à utiliser /// Jeu de caractère GDI à utiliser /// Une police avec les caractéristiques spécifiées public Font GetFont(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) { FontProperties prop = new FontProperties { FontFamily = family, Size = emSize, Style = style, Unit = unit, GdiCharSet = gdiCharSet }; return GetFont(prop); } /// /// Retourne une police avec les caractéristiques spécifiées /// /// Nom de la famille de la police à obtenir /// Taille de la police souhaitée, dans l'unité spécifiée /// Style de la police souhaitée /// Unité de taille à utiliser /// Jeu de caractère GDI à utiliser /// Une police avec les caractéristiques spécifiées public Font GetFont(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) { FontProperties prop = new FontProperties { FontFamily = GetFontFamily(familyName), Size = emSize, Style = style, Unit = unit, GdiCharSet = gdiCharSet, GdiVerticalFont = IsVerticalName(familyName) }; return GetFont(prop); } /// /// Retourne une police avec les caractéristiques spécifiées /// /// Famille de la police à obtenir /// Taille de la police souhaitée, dans l'unité spécifiée /// Style de la police souhaitée /// Unité de taille à utiliser /// Jeu de caractère GDI à utiliser /// Valeur booléenne indiquant si la police est dérivée d'une police verticale GDI /// Une police avec les caractéristiques spécifiées public Font GetFont(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) { FontProperties prop = new FontProperties { FontFamily = family, Size = emSize, Style = style, Unit = unit, GdiCharSet = gdiCharSet, GdiVerticalFont = gdiVerticalFont }; return GetFont(prop); } /// /// Retourne une police avec les caractéristiques spécifiées /// /// Nom de la famille de la police à obtenir /// Taille de la police souhaitée, dans l'unité spécifiée /// Style de la police souhaitée /// Unité de taille à utiliser /// Jeu de caractère GDI à utiliser /// Valeur booléenne indiquant si la police est dérivée d'une police verticale GDI /// Une police avec les caractéristiques spécifiées public Font GetFont(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) { FontProperties prop = new FontProperties { FontFamily = GetFontFamily(familyName), Size = emSize, Style = style, Unit = unit, GdiCharSet = gdiCharSet, GdiVerticalFont = gdiVerticalFont }; return GetFont(prop); } /// /// Vide le cache /// public void Clear() { _cache.Clear(); } private Font GetFont(FontProperties prop) { return _cache[prop]; } private static Font GetFontInternal(FontProperties prop) { return prop.CreateFont(); } private static FontFamily GetFontFamily(string familyName) { return new FontFamily(StripVerticalName(familyName)); } private static string StripVerticalName(string name) { if (IsVerticalName(name)) { return name.Substring(1); } return name; } private static bool IsVerticalName(string name) { return !string.IsNullOrEmpty(name) && name[0] == '@'; } } }