Skip to content

Instantly share code, notes, and snippets.

@adamsmith
Created February 10, 2017 01:30
Show Gist options
  • Select an option

  • Save adamsmith/2cd59c775b3768f6f811fe8f63e6b53d to your computer and use it in GitHub Desktop.

Select an option

Save adamsmith/2cd59c775b3768f6f811fe8f63e6b53d to your computer and use it in GitHub Desktop.

Revisions

  1. adamsmith created this gist Feb 10, 2017.
    84 changes: 84 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    // 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;
    }
    }
    }