共用方式為


整合文字與圖形

瞭解如何判斷轉譯文字字串的大小,以整合文字與SkiaSharp圖形

本文示範如何測量文字、將文字調整為特定大小,以及將文字與其他圖形整合:

以矩形括住的文字

該影像也包含圓角矩形。 SkiaSharp Canvas 類別包含 DrawRect 繪製矩形的方法,以及 DrawRoundRect 繪製圓角矩形的方法。 這些方法可讓矩形定義為 SKRect 值或其他方式。

[ 框架文字 ] 頁面會在頁面上置中一個簡短的文字字串,並以由一對圓角矩形組成的框架括住它。 類別 FramedTextPage 會顯示其完成方式。

在 SkiaSharp 中 SKPaint ,您可以使用 類別來設定文字和字型屬性,但您也可以使用它來取得轉譯的文字大小。 下列 PaintSurface 事件處理程式的開頭會呼叫兩個不同的 MeasureText 方法。 第一 MeasureText 次呼叫具有簡單的 string 自變數,並根據目前的字型屬性傳回文字的圖元寬度。 然後,程式會根據呈現的SKPaint寬度、目前的TextSize屬性和顯示區域的寬度,計算物件的新TextSize屬性。 此計算設定 TextSize 文字字串,以 90% 的螢幕寬度呈現:

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;

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

第二 MeasureText 個呼叫具有自 SKRect 變數,因此它會取得轉譯文字的寬度和高度。 Height這個SKRect值的 屬性取決於文字字串中大寫字母、遞增和子系的存在。 例如,會針對文字字串 「mom」、“cat” 和 “dog” 報告不同的 Height 值。

結構的 LeftTop 屬性 SKRect 會指出轉譯文字左上角的座標,如果文字是由 DrawText 具有 X 和 Y 位置 0 的呼叫所顯示。 例如,當此程式在 i 電話 7 模擬器上執行時,TextSize會在第一次呼叫 MeasureText之後,指派值 90.6254。 SKRect從 第二個 呼叫MeasureText取得的值具有下列屬性值:

  • Left = 6
  • Top = –68
  • Width = 664.8214
  • Height = 88;

請記住,您傳遞給 DrawText 方法的 X 和 Y 座標會指定基準文字的左側。 值 Top 表示文字會擴充該基準的 68 圖元,並在基準下方減去 68 像素(從 88 減去 68 圖元)。 Left 6 的值表示文字會在呼叫中 DrawText X 值的右邊開始六個圖元。 這允許一般字元間間距。 如果您想要在顯示左上角顯示文字,請將這些 LeftTop 值的負值當做 的 X 和 Y 座標 DrawText傳遞,在此範例中為 –6 和 68。

結構 SKRect 會定義數個方便的屬性和方法,其中部分用於處理程序的 PaintSurface 其餘部分。 MidXMidY 值表示矩形中央的座標。 (在 i 電話 7 範例中,這些值為 338.4107 和 –24。下列程式代碼會使用這些值來計算座標,以將顯示器上的文字置中:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    ...
    // 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);
    ...
}

SKImageInfo資訊結構也會定義 Rect 類型的SKRect屬性,因此您也可以計算xTextyText如下所示:

float xText = info.Rect.MidX - textBounds.MidX;
float yText = info.Rect.MidY - textBounds.MidY;

處理程式最後 PaintSurface 會呼叫 DrawRoundRect兩個 ,這兩個呼叫都需要 的 SKRect自變數。 此值SKRect是以從 MeasureText 方法取得的值為基礎SKRect,但不能相同。 首先,它必須變大一點,讓圓角矩形不會繪製文字邊緣。 其次,它必須在空格中移位, Left 讓和 Top 值對應至矩形所在的左上角。 這兩個作業是由 所SKRect定義的 和 Inflate 方法所完成Offset

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    ...
    // 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);
}

接下來,方法的其餘部分是直接的。 它會為框線建立另一個 SKPaint 物件,並呼叫 DrawRoundRect 兩次。 第二個呼叫會使用另一個 10 像素擴充的矩形。 第一次呼叫會指定 20 像素的圓角半徑。 第二個角半徑為 30 像素,因此它們看起來是平行的:

[框架文字] 頁面的三重螢幕快照

您可以側邊轉手機或模擬器,以查看文字和畫面大小增加。

如果您只需要將畫面上的某些文字置中,您可以大致執行此動作,而不測量文字。 請改為將 TextAlignSKPaint 屬性設定為 列舉成員 SKTextAlign.Center。 您在 方法中指定的 DrawText X 座標接著會指出文字的水準置中位置。 如果您將畫面 DrawText 的中間點傳遞給 方法,文字會水準置中, 而且幾乎 垂直置中,因為基準會垂直置中。

文字可以像任何其他圖形化對象一樣處理。 其中一個簡單的選項是顯示文字字元的外框:

大綱文字頁面的三個螢幕快照

只要將 物件的一般 Style 屬性 SKPaint 從其預設設定 SKPaintStyle.Fill 變更為 SKPaintStyle.Stroke,並藉由指定筆劃寬度來完成。 [PaintSurface大綱文字] 頁面的處理程序會顯示其完成方式:

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

    canvas.Clear();

    string text = "OUTLINE";

    // Create an SKPaint object to display the text
    SKPaint textPaint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        StrokeWidth = 1,
        FakeBoldText = true,
        Color = SKColors.Blue
    };

    // Adjust TextSize property so text is 95% of screen width
    float textWidth = textPaint.MeasureText(text);
    textPaint.TextSize = 0.95f * info.Width * textPaint.TextSize / textWidth;

    // Find the text bounds
    SKRect textBounds = new SKRect();
    textPaint.MeasureText(text, 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(text, xText, yText, textPaint);
}

另一個常見的圖形對像是位圖。 這是SkiaSharp位陣陣圖一中深入討論的大型主題,但下一篇文章:SkiaSharp中的點陣圖基本概念提供更簡短的簡介。