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] == '@';
}
}
}