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 ...