From cecb4c90ddc73d564c3fbad6167faa9d5635534c Mon Sep 17 00:00:00 2001 From: "13.beta2" <temp.13.beta2@mail.ru> Date: Mon, 11 Jan 2016 00:23:48 +0300 Subject: [PATCH] Implement basic font rendering tuning for code editor. (1/2: Main+AddIns part) Ability to disable anti-aliasing for 'pixel-perfect' fonts like Courier New. Ability to disable hinting to forget about jagged default WPF rendering. --- data/resources/StringResources.resx | 6 + .../Src/Options/GeneralEditorOptions.xaml | 10 +- .../Project/ZoomScrollViewer.cs | 120 ++++++++++++++++++ .../Project/ZoomScrollViewer.xaml | 21 +++ 4 files changed, 156 insertions(+), 1 deletion(-) diff --git a/data/resources/StringResources.resx b/data/resources/StringResources.resx index d9f7fd02b7..214ba99511 100644 --- a/data/resources/StringResources.resx +++ b/data/resources/StringResources.resx @@ -8445,5 +8445,11 @@ Press Esc to cancel this operation.</value> </data> <data name="ICSharpCode.WpfDesign.AddIn.Options.EnableAppXamlParsing" xml:space="preserve"> <value>Enable App.xaml parsing</value> + </data> + <data name="Dialog.Options.IDEOptions.TextEditor.General.EnableTextAntialiasing" xml:space="preserve"> + <value>Enable anti-aliasing</value> + </data> + <data name="Dialog.Options.IDEOptions.TextEditor.General.EnableTextHinting" xml:space="preserve"> + <value>Enable hinting</value> </data> </root> \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/GeneralEditorOptions.xaml b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/GeneralEditorOptions.xaml index 576ec15bef..0720da5ae0 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/GeneralEditorOptions.xaml +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/GeneralEditorOptions.xaml @@ -4,7 +4,15 @@ <StackPanel> <GroupBox Header="{core:Localize Dialog.Options.IDEOptions.TextEditor.General.FontGroupBox}"> - <gui:FontSelector x:Name="fontSelectionPanel" /> + <widgets:StackPanelWithSpacing SpaceBetweenItems="5"> + <gui:FontSelector x:Name="fontSelectionPanel" /> + <CheckBox + IsChecked="{core:OptionBinding local:CodeEditorOptions.EnableTextAntialiasing}" + Content="{core:Localize Dialog.Options.IDEOptions.TextEditor.General.EnableTextAntialiasing}" /> + <CheckBox + IsChecked="{core:OptionBinding local:CodeEditorOptions.EnableTextHinting}" + Content="{core:Localize Dialog.Options.IDEOptions.TextEditor.General.EnableTextHinting}" /> + </widgets:StackPanelWithSpacing> </GroupBox> <GroupBox Header="{core:Localize Dialog.Options.IDEOptions.TextEditor.General.GeneralOptionsGroupBox}"> diff --git a/src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ZoomScrollViewer.cs b/src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ZoomScrollViewer.cs index 969c4812f7..bafd6a0e74 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ZoomScrollViewer.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ZoomScrollViewer.cs @@ -186,4 +186,124 @@ namespace ICSharpCode.SharpDevelop.Widgets throw new NotImplementedException(); } } + + sealed class ZoomToTextFormattingModeConverter : IMultiValueConverter + { + public static readonly ZoomToTextFormattingModeConverter Instance = new ZoomToTextFormattingModeConverter(); + + public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + var zoom = value[0] != null ? (double) value[0] : 1.0; + var antialiasing = value[1] != DependencyProperty.UnsetValue ? (bool) value[1] : true; + var hinting = value[2] != DependencyProperty.UnsetValue ? (bool) value[2] : true; + + if (antialiasing) + { + if (hinting) + { + if (zoom == 1.0) + { + return TextFormattingMode.Display; + } + else + { + return TextFormattingMode.Ideal; + } + } + else + { + return TextFormattingMode.Ideal; + } + } + else + { + return TextFormattingMode.Display; + } + } + + public object[] ConvertBack(object value, Type[] targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } + + sealed class ZoomToTextRenderingModeConverter : IMultiValueConverter + { + public static readonly ZoomToTextRenderingModeConverter Instance = new ZoomToTextRenderingModeConverter(); + + public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + var zoom = value[0] != null ? (double) value[0] : 1.0; + var antialiasing = value[1] != DependencyProperty.UnsetValue ? (bool) value[1] : true; + var hinting = value[2] != DependencyProperty.UnsetValue ? (bool) value[2] : true; + + if (antialiasing) + { + if (hinting) + { + if (zoom == 1.0) + { + return TextRenderingMode.ClearType; + } + else + { + return TextRenderingMode.Grayscale; + } + } + else + { + return TextRenderingMode.Grayscale; + } + } + else + { + return TextRenderingMode.Aliased; + } + } + + public object[] ConvertBack(object value, Type[] targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } + + sealed class ZoomToTextHintingModeConverter : IMultiValueConverter + { + public static readonly ZoomToTextHintingModeConverter Instance = new ZoomToTextHintingModeConverter(); + + public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + var zoom = value[0] != null ? (double) value[0] : 1.0; + var antialiasing = value[1] != DependencyProperty.UnsetValue ? (bool) value[1] : true; + var hinting = value[2] != DependencyProperty.UnsetValue ? (bool) value[2] : true; + + if (antialiasing) + { + if (hinting) + { + if (zoom == 1.0) + { + return TextHintingMode.Fixed; + } + else + { + return TextHintingMode.Fixed; + } + } + else + { + return TextHintingMode.Animated; + } + } + else + { + return TextHintingMode.Fixed; + } + } + + public object[] ConvertBack(object value, Type[] targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } } diff --git a/src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ZoomScrollViewer.xaml b/src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ZoomScrollViewer.xaml index 6034140ef0..674e076538 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ZoomScrollViewer.xaml +++ b/src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ZoomScrollViewer.xaml @@ -24,6 +24,27 @@ <ScrollContentPresenter.LayoutTransform> <ScaleTransform ScaleX="{Binding Path=CurrentZoom, RelativeSource={RelativeSource Mode=TemplatedParent}}" ScaleY="{Binding Path=CurrentZoom, RelativeSource={RelativeSource Mode=TemplatedParent}}"/> </ScrollContentPresenter.LayoutTransform> + <TextOptions.TextFormattingMode> + <MultiBinding Converter="{x:Static Controls:ZoomToTextFormattingModeConverter.Instance}"> + <Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" Path="CurrentZoom" /> + <Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" Path="Content.Options.EnableTextAntialiasing" /> + <Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" Path="Content.Options.EnableTextHinting" /> + </MultiBinding> + </TextOptions.TextFormattingMode> + <TextOptions.TextRenderingMode> + <MultiBinding Converter="{x:Static Controls:ZoomToTextRenderingModeConverter.Instance}"> + <Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" Path="CurrentZoom" /> + <Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" Path="Content.Options.EnableTextAntialiasing" /> + <Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" Path="Content.Options.EnableTextHinting" /> + </MultiBinding> + </TextOptions.TextRenderingMode> + <TextOptions.TextHintingMode> + <MultiBinding Converter="{x:Static Controls:ZoomToTextHintingModeConverter.Instance}"> + <Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" Path="CurrentZoom" /> + <Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" Path="Content.Options.EnableTextAntialiasing" /> + <Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" Path="Content.Options.EnableTextHinting" /> + </MultiBinding> + </TextOptions.TextHintingMode> </ScrollContentPresenter> <ScrollBar Name="PART_VerticalScrollBar" Grid.Column="2" Grid.Row="0" Minimum="0" Maximum="{TemplateBinding ScrollableHeight}" ViewportSize="{TemplateBinding ViewportHeight}" Value="{TemplateBinding VerticalOffset}" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" /> <ScrollBar Name="PART_HorizontalScrollBar" Orientation="Horizontal" Grid.Column="1" Grid.Row="1" Minimum="0" Maximum="{TemplateBinding ScrollableWidth}" ViewportSize="{TemplateBinding ViewportWidth}" Value="{TemplateBinding HorizontalOffset}" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />