Created
February 10, 2017 01:30
-
-
Save adamsmith/2cd59c775b3768f6f811fe8f63e6b53d to your computer and use it in GitHub Desktop.
C# FontStack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// License: public domain | |
using System; | |
using System.Collections.Generic; | |
using System.Drawing; | |
using System.Text; | |
using System.Windows.Forms; | |
namespace CommonCode { | |
public static class FontStack { | |
static FontStack() { | |
DefaultAppFontFamily = GetFirstAvailableFontFamily(new string[] { "Segoe UI", "Calibri", "Verdana" }); | |
//DefaultAppFontFamily = GetFirstAvailableFontFamily(new string[] { "Verdana" }); | |
Log.Logger.Debug(string.Format("Using font family {0}", DefaultAppFontFamily.Name)); | |
HeightTargetFontFamily = GetFirstAvailableFontFamily(new string[] { "Verdana" }); | |
} | |
public static void SetFontFamilyForDescendents(Control control, Graphics g) { | |
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(child, g); | |
} | |
} 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