Skip to content

Instantly share code, notes, and snippets.

@adamsmith
Created October 5, 2011 00:41
Show Gist options
  • Save adamsmith/1263295 to your computer and use it in GitHub Desktop.
Save adamsmith/1263295 to your computer and use it in GitHub Desktop.
Sets fonts in forms to the first-available font in a list of fonts. Adjusts size of fonts to match a baseline font, so e.g. 9pt Calibri will be the same size as 9pt Verdana.
// Author: Adam Smith <adam@adamsmith.cc>
// License: public domain
internal static class FontFamilies {
static FontFamilies() {
DefaultAppFontFamily = GetFirstAvailableFontFamily(new string[] { "Segoe UI", "Calibri", "Verdana" });
Log.Logger.Debug(string.Format("Using font family {0}", DefaultAppFontFamily.Name));
HeightTargetFontFamily = GetFirstAvailableFontFamily(new string[] { "Verdana" });
}
internal static void SetFontFamilyForDescendents(Graphics g, Control control) {
if (DefaultAppFontFamily == null || HeightTargetFontFamily == null) {
return;
}
try {
foreach (Control child in control.Controls) {
if (child is ContainerControl) {
// don't change the fonts of container controls
// they will often have an AutoScaleMode that will change the size of the control depending on the
// font size.
} else {
if (DefaultAppFontFamily.IsStyleAvailable(child.Font.Style)) {
var newFont = new Font(DefaultAppFontFamily, child.Font.Size, child.Font.Style, child.Font.Unit);
// measure difference in font height
// some fonts like Calibri are noticible smaller, unfortunately
var newFamilyTestSize = MeasureRealFontSize(g, newFont);
var oldFamilyTestSize = MeasureRealFontSize(g, child.Font);
var sizeRatio = oldFamilyTestSize / newFamilyTestSize;
newFont = new Font(newFont.FontFamily, newFont.Size * sizeRatio, newFont.Style, newFont.Unit);
child.Font = newFont;
}
}
SetFontFamilyForDescendents(g, child);
}
} catch (Exception e) {
Log.Logger.ErrorException("Error setting font family of control's descendents", e);
}
}
private static FontFamily DefaultAppFontFamily { get; set; }
private static FontFamily HeightTargetFontFamily { get; set; }
private static float MeasureRealFontSize(Graphics g, Font font) {
var testString = "Test String";
using (var format = new StringFormat()) {
format.SetMeasurableCharacterRanges(new CharacterRange[] { new CharacterRange(0, testString.Length) });
using (var region = g.MeasureCharacterRanges(testString, font,
new RectangleF(PointF.Empty, new SizeF(1000, 1000)), format)[0]) {
var bounds = region.GetBounds(g);
return (float)Math.Sqrt(Math.Pow(bounds.Height, 2) + Math.Pow(bounds.Width, 2));
}
}
}
private static FontFamily GetFirstAvailableFontFamily(string[] fontFamilyStack) {
foreach (var fontFamily in fontFamilyStack) {
try {
return new FontFamily(fontFamily);
} catch {
Log.Logger.Debug(string.Format("Exception getting {0} font. Falling back to next default...", fontFamily));
}
}
return FontFamily.GenericSansSerif;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment