From ace0bd8c3584bca9769e7dca5f18dba92e8dac72 Mon Sep 17 00:00:00 2001 From: reduckted Date: Wed, 30 Oct 2024 21:33:42 +1000 Subject: [PATCH] Calculated the correct font size for use in WPF. The font size specified in the FontInfo object is in points. WPF does not use points for font sizes, so the font size was always smaller than it should have been. --- .../BaseFontAndColorCategory.cs | 2 +- .../FontsAndColors/ConfiguredFont.cs | 47 +++++++++++++++---- .../ConfiguredFontAndColorSet.cs | 9 ++-- .../FontsAndColors/FontsAndColors.cs | 4 +- .../IFontAndColorChangeListener.cs | 2 +- 5 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/BaseFontAndColorCategory.cs b/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/BaseFontAndColorCategory.cs index 813fb51..93b88a5 100644 --- a/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/BaseFontAndColorCategory.cs +++ b/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/BaseFontAndColorCategory.cs @@ -246,7 +246,7 @@ int IVsFontAndColorEvents.OnFontChanged(ref Guid rguidCategory, FontInfo[] pInfo // only want to handle the changes for this category. if (rguidCategory.Equals(_categoryGuid)) { - EmitChange((x) => x.SetFont(ref pInfo[0])); + EmitChange((x) => x.SetFont(ref pLOGFONT[0], ref pInfo[0])); } return VSConstants.S_OK; } diff --git a/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/ConfiguredFont.cs b/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/ConfiguredFont.cs index c8cac9d..5037fc1 100644 --- a/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/ConfiguredFont.cs +++ b/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/ConfiguredFont.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using System; +using System.ComponentModel; using System.Windows.Media; using Microsoft.VisualStudio.PlatformUI; using Microsoft.VisualStudio.Shell.Interop; @@ -22,14 +23,16 @@ public class ConfiguredFont : ObservableObject private FontFamily? _family; private bool _hasFamily; private string _familyName; + private int _pointSize; private double _size; private byte _characterSet; - internal ConfiguredFont(ref FontInfo info) + internal ConfiguredFont(ref LOGFONTW logfont, ref FontInfo fontInfo) { - _familyName = info.bstrFaceName; - _size = info.wPointSize; - _characterSet = info.iCharSet; + _familyName = fontInfo.bstrFaceName; + _pointSize = fontInfo.wPointSize; + _size = CalculateFontSize(ref logfont); + _characterSet = fontInfo.iCharSet; } /// @@ -61,7 +64,14 @@ public FontFamily? Family public string FamilyName => _familyName; /// - /// The font size. + /// The font size, in points. This is the value specified on the Fonts and Colors options page. + /// + public int PointSize => _pointSize; + + /// + /// The font size, for use in WPF. This is the font size that can be used in WPF controls. + /// For example, the value can be used directly in the + /// property. /// public double Size => _size; @@ -70,17 +80,19 @@ public FontFamily? Family /// public byte CharacterSet => _characterSet; - internal bool Update(ref FontInfo info) + internal bool Update(ref LOGFONTW logfont, ref FontInfo info) { bool changed = false; string oldFaceName = _familyName; + int oldPointSize = _pointSize; double oldSize = _size; byte oldCharacterSet = _characterSet; // Update all of the fields first so that // everything is set before we raise the events. _familyName = info.bstrFaceName; - _size = info.wPointSize; + _pointSize = info.wPointSize; + _size = CalculateFontSize(ref logfont); _characterSet = info.iCharSet; if (!string.Equals(oldFaceName, _familyName)) @@ -92,6 +104,12 @@ internal bool Update(ref FontInfo info) NotifyPropertyChanged(nameof(FamilyName)); } + if (oldPointSize != _pointSize) + { + changed = true; + NotifyPropertyChanged(nameof(PointSize)); + } + if (oldSize != _size) { changed = true; @@ -106,5 +124,18 @@ internal bool Update(ref FontInfo info) return changed; } + + private static double CalculateFontSize(ref LOGFONTW logfont) + { + return Math.Abs(logfont.lfHeight) * 96.0 / +#if VS14 + // `DpiAwareness` does not exist in VS 14, so default + // to 96.0, which is the standard system DPI. + 96.0 +#else + Microsoft.VisualStudio.Utilities.DpiAwareness.SystemDpiY +#endif + ; + } } } diff --git a/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/ConfiguredFontAndColorSet.cs b/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/ConfiguredFontAndColorSet.cs index 2b5e3be..120a071 100644 --- a/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/ConfiguredFontAndColorSet.cs +++ b/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/ConfiguredFontAndColorSet.cs @@ -14,13 +14,14 @@ namespace Community.VisualStudio.Toolkit internal ConfiguredFontAndColorSet( T category, - ref FontInfo font, + ref LOGFONTW logfont, + ref FontInfo fontInfo, Dictionary colors, Action onDispose ) { Category = category; - Font = new ConfiguredFont(ref font); + Font = new ConfiguredFont(ref logfont, ref fontInfo); _colors = colors; _onDispose = onDispose; } @@ -64,9 +65,9 @@ public ConfiguredColor GetColor(ColorDefinition definition) /// public event EventHandler? ColorChanged; - void IFontAndColorChangeListener.SetFont(ref FontInfo info) + void IFontAndColorChangeListener.SetFont(ref LOGFONTW logfont, ref FontInfo info) { - if (Font.Update(ref info)) + if (Font.Update(ref logfont, ref info)) { FontChanged?.Invoke(this, EventArgs.Empty); } diff --git a/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/FontsAndColors.cs b/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/FontsAndColors.cs index f6178d6..256b2a0 100644 --- a/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/FontsAndColors.cs +++ b/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/FontsAndColors.cs @@ -37,10 +37,12 @@ internal FontsAndColors() T category = BaseFontAndColorCategory.Instance; FontInfo[] fontInfo = new FontInfo[1]; - ErrorHandler.ThrowOnFailure(storage.GetFont(null, fontInfo)); + LOGFONTW[] logfont = new LOGFONTW[1]; + ErrorHandler.ThrowOnFailure(storage.GetFont(logfont, fontInfo)); ConfiguredFontAndColorSet set = new( category, + ref logfont[0], ref fontInfo[0], await GetColorsAsync(category, categoryGuid, storage), category.UnregisterChangeListener diff --git a/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/IFontAndColorChangeListener.cs b/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/IFontAndColorChangeListener.cs index a9fa542..012622c 100644 --- a/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/IFontAndColorChangeListener.cs +++ b/src/toolkit/Community.VisualStudio.Toolkit.Shared/FontsAndColors/IFontAndColorChangeListener.cs @@ -4,7 +4,7 @@ namespace Community.VisualStudio.Toolkit { internal interface IFontAndColorChangeListener { - void SetFont(ref FontInfo info); + void SetFont(ref LOGFONTW logfont, ref FontInfo info); void SetColor(ColorDefinition definition, uint background, uint foreground, FontStyle fontStyle); }