【问题标题】:Fit text in a rectangle using SkiaSharp使用 SkiaSharp 在矩形中调整文本
【发布时间】:2018-04-16 08:49:38
【问题描述】:

我需要绘制文本来填充(即适合的最大合理尺寸)一个矩形。我怎样才能做到这一点?我看不到任何缩放/适合文本的方法 - 所以我假设(希望是错误的)我将不得不设置字体大小并测量它是否适合,并相应地调整字体大小。

【问题讨论】:

    标签: drawtext skiasharp


    【解决方案1】:

    我想出了一个稍微低效的方法,从一个小的 TextSize 开始,然后增加它并测量直到它不适合矩形 - 然后取最后一个适合的尺寸。

    为了提高效率,我将 TextSize 缓存为给定的控件大小。

    不理想,但效果很好!

    【讨论】:

    • 另一种方法可能是使用某种算法。例如,以较小的尺寸测量文本,然后计算出所需的尺寸。由于文本大小只是文本高度,您可以通过基本数学计算出来。假设文本大小为 12,宽度为 100。如果可用的总宽度为 250,则 250/100=2.5,因此,12*2.5=30。可能的文本大小是 30。大多数文本是线性缩放的,但即使不是,您也可以从那里向上/向下工作。只是猜测。
    • 好主意,谢谢。但是,我的循环而不是算法运行良好,并且在缓存方面非常有效。
    • 你看SKPaint.MeasureText(string text, ref SKRect bounds)方法了吗?它将使用您拥有的当前绘制设置为您提供要绘制的文本的边界。这样你就可以同时得到宽度和高度。然后,您可以迭代地优化绘图的文本大小,以使文本按照您的建议自动适应您的矩形。
    【解决方案2】:

    我知道这是一个非常古老的问题,但我不妨为其他想知道如何有效地做到这一点的人回答这个问题。

    我最近不得不为我的一个项目这样做。这就是我想出的。

    澄清一下:

    扇区大小:文本的最大纵向大小。

    Max Font:我们要测试的最大字体大小。

    cmets 解释了这是如何工作的。

    public float GetMaxFontSize(double sectorSize, SKTypeface typeface, string text, float degreeOfCertainty = 1f, float maxFont = 100f)
    {
       var max = maxFont; // The upper bound. We know the font size is below this value
       var min = 0f; // The lower bound, We know the font size is equal to or above this value
       var last = -1f; // The last calculated value.
       float value;
       while (true)
       {
          value = min + ((max - min) / 2); // Find the half way point between Max and Min
          using (SKFont ft = new SKFont(typeface, value))
          using (SKPaint paint = new SKPaint(ft))
          {
             if (paint.MeasureText(text) > sectorSize) // Measure the string size at this font size
             {
                // The text size is too large
                // therefore the max possible size is below value
                last = value;
                max = value;
             }
             else
             {
                // The text fits within the area
                // therefore the min size is above or equal to value
                min = value;
    
                // Check if this value is within our degree of certainty
                if (Math.Abs(last - value) <= degreeOfCertainty)
                return last; // Value is within certainty range, we found the best font size!
    
                //This font difference is not within our degree of certainty
                last = value;
             }
          }
       }
    }
    

    在我的用例中,计算 54.68px 的字体大小需要 7 个步骤,平均执行持续时间超过 10000 个周期,250 个刻度 (0.025ms),确定度为 1px。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-19
      • 1970-01-01
      • 2017-03-08
      • 1970-01-01
      • 1970-01-01
      • 2015-07-06
      • 2020-08-23
      • 1970-01-01
      相关资源
      最近更新 更多