-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Platform accessibility text scaling #20292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Platform accessibility text scaling #20292
Conversation
7cc5c10 to
f164333
Compare
|
API diff for review: Avalonia.Base (net10.0, net8.0) namespace Avalonia.Platform
{
public class DefaultPlatformSettings : Avalonia.Platform.IPlatformSettings
{
- protected void OnColorValuesChanged(Avalonia.Platform.PlatformColorValues colorValues);
+ protected virtual void OnColorValuesChanged(Avalonia.Platform.PlatformColorValues colorValues);
+ public event System.EventHandler<System.EventArgs>? TextScalingChanged { add; remove; }
+ public virtual double GetScaledFontSize(double baseFontSize);
+ protected virtual void OnTextScaleChanged();
}
public interface IPlatformSettings
{
+ event System.EventHandler<System.EventArgs>? TextScalingChanged;
+ double GetScaledFontSize(double baseFontSize);
}
}Avalonia.Controls (net10.0, net8.0) namespace Avalonia.Controls
{
public class TextBlock : Avalonia.Controls.Control, Avalonia.LogicalTree.ILogical, Avalonia.Controls.IPlatformTextScaleable
{
+ public static readonly Avalonia.StyledProperty<bool> IsPlatformTextScalingEnabledProperty;
+ protected double EffectiveFontSize { get; }
+ public bool IsPlatformTextScalingEnabled { get; set; }
}
+ public interface IPlatformTextScaleable
+ {
+ double GetScaledFontSize(double baseFontSize);
+ void OnPlatformTextScalingChanged();
+ bool IsPlatformTextScalingEnabled { get; }
+ }
}
namespace Avalonia.Controls.Documents
{
public abstract class TextElement : Avalonia.StyledElement
{
+ public static readonly Avalonia.AttachedProperty<bool> IsPlatformTextScalingEnabledProperty;
+ public static bool GetIsPlatformTextScalingEnabled(Avalonia.Controls.Control control);
+ public static void SetIsPlatformTextScalingEnabled(Avalonia.Controls.Control control, bool value);
+ public bool IsPlatformTextScalingEnabled { get; set; }
}
}
namespace Avalonia.Controls.Presenters
{
public class TextPresenter : Avalonia.Controls.Control, Avalonia.Controls.IPlatformTextScaleable
{
+ public static readonly Avalonia.StyledProperty<bool> IsPlatformTextScalingEnabledProperty;
+ protected double EffectiveFontSize { get; }
+ public bool IsPlatformTextScalingEnabled { get; set; }
}
} |
Only TextBlock, Inline, and TextPresenter scale text by themselves No change to low-level text rendering or FontSize values Implemented for iOS and Windows Windows scaling is currently uniform regardless of base font size, which is incorrect
f164333 to
bf2a577
Compare
Fixed TextBox.MaxLines and TextBox.MinLines calculations when text scaling is active Fixed TextBox not updating when LineSpacing changes Removed EffectiveFontSize, since it's no longer the only property which scales
|
Notes from the API review meeting: To be more generic, we'd like the text scale factor to be configurable and inherited, with its default coming from the platform. Proposed name: We're fine with making the platform scaling the default in v12. This PR won't be backported to v11. |
This can't be done. Text scaling is not a factor but a per-platform algorithm. On Windows this algorthim is a complicated mathematical function, while on iOS it's an absolute point increase or decrease, plus a minimum size. Android may do something else.
Alright, but my iOS project targets v11, is due for release in Q1 next year, and we would like it to support text scaling. We'll probably make a cheeky custom build by opening a backport PR despite this decision. |
We may want to consider backporting it, but having it turned off by default? |
@TomEdwardsEnscape Indeed. Sorry, by doing the API review without having looked at the implementation in details, we were under the wrong assumption that there was only one (non-linear) algorithm, with a factor determined per platform. Still, we want to let the user customize the scale factor. Flutter had a Have a This would also allow each |
Added ITextScaler to support custom text scaling Calculate a font scale factor and use this to adjust height and spacing values Fixed TextBox not updating when LineHeight changes and MaxLines or MinLines are active
|
I implemented the TextScaler abstract class as requested, see e1dd366. However, I didn't like this approach. It's opaque and hard to use. It doesn't match Flutter's implementation either: they have a parent item in the hierarchy, like So what I've pushed to the PR branch is a reinterpretation of Flutter's solution in Avalonia's style. There are four attached properties:
The last of these is a read-only interface that can provide custom scaling (if null, platform scaling is used). The rest provide built-in functionality for the common use cases identified by Flutter. Flutter's documentation states that "it's rarely needed to create a custom TextScaler subclass". I agree, and the properties listed above enable Avalonia to provide the same built-in functionality that Flutter offers. |
Many platforms support text scaling, an accessibility feature which allows the user to request that text be drawn larger (or on some platforms smaller) than normal, without altering other UI elements. Avalonia currently has no support for this feature. This PR adds support for iOS and Windows, and creates the infrastructure necessary to extend support to more platforms in the future.
The feature is disabled by default, so there are no breaking changes. It has been enabled for the Control Gallery.
Only
TextBlock,Inline, andTextPresenterscale text by themselves. There is no change to low-level text measurement or rendering.What is the updated/expected behavior with this PR?
The Control Gallery now looks like this with 150% text scaling on Windows:
Note that the window, tiles, scrollbars and other non-text elements are the same size as before. Only the text is larger.
How was the solution implemented (if it's not obvious)?
Text scaling is provided via
IPlatformSettings.TextBlock,Inline, andTextPresenterget the platform settings object from theirTopLeveland ask it to adjust their assignedFontSizewhen they are building their text layout objects. The value ofFontSizedoes not change; platform text scaling is an extra layer on top which affects only measurement and rendering. This is how WinUI3 handles the feature.Each individual control can configure the inherited
TextElement.IsPlatformTextScalingEnabledproperty to control whether text scaling is applied to it and its children. Inline elements use the value of their host.Breaking changes
None.
Obsoletions / Deprecations
None.