【问题标题】:Ensure SkiaSharp font and Xamarin Forms default font match确保 SkiaSharp 字体和 Xamarin Forms 默认字体匹配
【发布时间】:2021-01-03 21:39:35
【问题描述】:

我在 Xamarin 表单中使用 SkiaSharp。我的目标是确保 Xamarin 控件中显示的字体,例如一个标签,匹配 SkiaSharp 绘图中使用的字体。

此外,我想使用默认字体,以便应用在其各自平台上看起来正确并符合用户偏好。

在我的简单应用程序中,我有一些 Xamarin 标签,并且我有一个由 SkiaSharp 绘制的自定义控件。两者有不同的字体,尽管它们非常接近。 SkiaSharp 具有相同的外观,但小了约 10%。 Xamarin 具有更广泛的抗锯齿功能。

查看截图片段(顶部:SkiaSharp,底部:Xamarin):

我不确定如何解决这个问题。至少有两种方法:

  1. 如何确定用于 Xamarin 标签的字体?如果我能确定这一点,我应该可以为 SkiaSharp 绘图设置它。
  2. 或者,如何将 Xamarin 字体设置为 SkiaSharp 使用的字体。我可以在运行时从 SkiaSharp 获取字体系列,但我不知道如何在运行时在 Xamarin 中设置它。

我想第三种选择是通过 SkiaSharp 处理所有字体。但是我将无法使用任何显示文本的 Xamarin 控件。

【问题讨论】:

  • 你好,关于在运行时修改字体,你可以看看this discussion,它可能会有所帮助。
  • 我希望有一个 Xamarin 解决方案。该链接有一个适用于 Android 的解决方案和一个适用于 iOS 的单独解决方案。 UWP 没有解决方案(尽管我确定有一个)。此外,它们不是使用 Xamarin Forms 编写的,并且可能使用完全不同的 API。

标签: xamarin.forms fonts skiasharp


【解决方案1】:

SkiaSharp一般使用系统默认字体绘制文字。

如果您可以将TextSize 设置为适合默认的FontSize,您将看到它们将显示相同。

看看这个截图:

Xaml中,上面是Label,下面是SKCanvasView

<Label Text="Hello SkiaSharp!" x:Name="mylabel" VerticalOptions="Start" FontSize="Large" HorizontalOptions="CenterAndExpand" />
<forms:SKCanvasView PaintSurface="OnCanvasViewPaintSurface" />

OnCanvasViewPaintSurface 方法是:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    SKImageInfo info = args.Info;
    SKSurface surface = args.Surface;
    SKCanvas canvas = surface.Canvas;

    canvas.Clear();

    string str = "Hello SkiaSharp!";

    // Create an SKPaint object to display the text
    SKPaint textPaint = new SKPaint
    {
        Color = SKColors.Chocolate
    };

    // Adjust TextSize property so text is 90% of screen width
    float textWidth = textPaint.MeasureText(str);
    //textPaint.TextSize = 0.9f * info.Width * textPaint.TextSize / textWidth;
    textPaint.TextSize = (float)((float)mylabel.FontSize*(2.6));

    //textPaint.Typeface = SKTypeface.FromFamilyName("monospace");

    // Find the text bounds
    SKRect textBounds = new SKRect();
    textPaint.MeasureText(str, ref textBounds);

    // Calculate offsets to center the text on the screen
    float xText = info.Width / 2 - textBounds.MidX;
    float yText = info.Height / 2 - textBounds.MidY;

    // And draw the text
    canvas.DrawText(str, xText, yText, textPaint);

    // Create a new SKRect object for the frame around the text
    SKRect frameRect = textBounds;
    frameRect.Offset(xText, yText);
    frameRect.Inflate(10, 10);

    // Create an SKPaint object to display the frame
    SKPaint framePaint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        StrokeWidth = 5,
        Color = SKColors.Blue
    };

    // Draw one frame
    canvas.DrawRoundRect(frameRect, 20, 20, framePaint);

    // Inflate the frameRect and draw another
    frameRect.Inflate(10, 10);
    framePaint.Color = SKColors.DarkBlue;
    canvas.DrawRoundRect(frameRect, 30, 30, framePaint);
}

【讨论】:

  • 谢谢。您声称默认字体应该相同。在您的示例中,它们看起来确实是相同的。就我而言,即使我调整大小,它们也不相同。
  • @PeriHartman 嗨,它们是相同的 Font。从共享图像来看,Text 的大小似乎不一样。但是Font 是一样的。如果为Lable(Android系统字体之一)的FamilyFont设置monospace,并在OnCanvasViewPaintSurface方法中添加代码textPaint.Typeface = SKTypeface.FromFamilyName("monospace");。您可以检查它是否适用于您的项目。
  • 好的,我相信你的话。那么,问题一定出在渲染中。也许是不同的抗锯齿算法。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-14
  • 1970-01-01
  • 2017-12-10
  • 2016-02-27
  • 2018-10-13
  • 1970-01-01
相关资源
最近更新 更多