0

If user changes the Font Size from default to large or largest in androids accessibility settings all labels are scaled up. But drawing text with DrawText method on a canvas has no effect.

Is this the expected behaviour? I thought that text which was drawn with skia sharp also scales up.
What is the correct way to work with android accessibility changes in skia sharp?

Thank you

Saftpresse99
  • 849
  • 7
  • 16

1 Answers1

0

The only way I know to find the scaling is via a deprecated Android API:

// First, test this in YourApp.Android project's MainActivity.cs.

// Returns "1" at default scale. Larger value when font should be larger.
public float CurrentFontScale()
{
    Android.Util.DisplayMetrics metrics = new Android.Util.DisplayMetrics();
    // Deprecated. But if it compiles, it works.
    WindowManager.DefaultDisplay.GetMetrics(metrics);
    float scaledDensity = metrics.ScaledDensity;
    return scaledDensity;
}

// Call it from here:
protected override void OnCreate(Bundle bundle){
{
    ...
    base.OnCreate(bundle);

    float fontScale = CurrentFontScale();

    ...
}

MULTIPLY all Skia font sizes by this.

After confirming the code works in MainActivity.cs, to use this in a cross-platform Xamarin project, create a Xamarin.Forms DependencyService. How to do that is beyond scope of this answer.


As a practical matter, consider "limiting" how large a given font size grows. Otherwise, layout becomes difficult. E.g. myFontSize = Math.Min(20 * fontScale, 48); for a text string that would be too large at fontsize greater than 48.

An alternative is to use SKPaint.MeasureText(somestring), after creating an skpaint with desired font size, and limit the fontSize if text gets too long:

// --- Auto-fit Skia text. ---
// These are typically parameters.
string somestring = "Hello, World";
float MaxAllowedWidth = 100;   // Pixels.
float fontSize = 20 * fontScale;

SKFont font = new SKFont(typeface, fontSize);
SKPaint textPaint = new SKPaint(font);
float textWidth = textPaint.MeasureText(somestring);
if (textWidth > MaxAllowedWidth)
{
    // --- Shrink as needed. ---
    // "Floor" to avoid being slightly too wide sometimes.
    fontSize = Math.Floor(fontSize * MaxAllowedWidth / textWidth);
    font = new SKFont(typeface, fontSize);
    textPaint = new SKPaint(font);

    // OPTIONAL VERIFY: This should now be less than MaxAllowedWidth.
    textWidth = textPaint.MeasureText(somestring);
}

... paint the text ...
ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196