Integrazione di testo e grafica

Informazioni su come determinare le dimensioni della stringa di testo di cui è stato eseguito il rendering per integrare il testo con la grafica SkiaSharp

Questo articolo illustra come misurare il testo, ridimensionare il testo in una determinata dimensione e integrare il testo con altre immagini:

Testo racchiuso tra rettangoli

Tale immagine include anche un rettangolo arrotondato. La classe SkiaSharp Canvas include DrawRect metodi per disegnare un rettangolo e DrawRoundRect metodi per disegnare un rettangolo con angoli arrotondati. Questi metodi consentono di definire il rettangolo come SKRect valore o in altri modi.

La pagina Testo incorniciato centra una stringa di testo breve nella pagina e la circonda con una cornice composta da una coppia di rettangoli arrotondati. La FramedTextPage classe mostra come viene eseguita.

In SkiaSharp si usa la SKPaint classe per impostare gli attributi di testo e carattere, ma è anche possibile usarlo per ottenere la dimensione di testo sottoposta a rendering. L'inizio del gestore eventi seguente PaintSurface chiama due metodi diversi MeasureText . La prima MeasureText chiamata ha un argomento semplice string e restituisce la larghezza in pixel del testo in base agli attributi correnti del tipo di carattere. Il programma calcola quindi una nuova TextSize proprietà dell'oggetto SKPaint in base alla larghezza di cui è stato eseguito il rendering, alla proprietà corrente TextSize e alla larghezza dell'area di visualizzazione. Questo calcolo è progettato per impostare TextSize in modo che il rendering della stringa di testo venga eseguito al 90% della larghezza dello schermo:

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);
    ...
}

La seconda MeasureText chiamata ha un SKRect argomento, quindi ottiene sia una larghezza che un'altezza del testo sottoposto a rendering. La Height proprietà di questo SKRect valore dipende dalla presenza di lettere maiuscole, ascendenti e discendenti nella stringa di testo. Per le stringhe di testo "mom", "cat" e "dog", ad esempio, vengono segnalati valori diversi Height .

Le Left proprietà e Top della SKRect struttura indicano le coordinate dell'angolo superiore sinistro del testo sottoposto a rendering se il testo viene visualizzato da una DrawText chiamata con posizioni X e Y pari a 0. Ad esempio, quando questo programma è in esecuzione in un simulatore i Telefono 7, TextSize viene assegnato il valore 90,6254 come risultato del calcolo dopo la prima chiamata a MeasureText. Il SKRect valore ottenuto dalla seconda chiamata a MeasureText ha i valori di proprietà seguenti:

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

Tenere presente che le coordinate X e Y passate al DrawText metodo specificano il lato sinistro del testo nella linea di base. Il Top valore indica che il testo estende 68 pixel al di sopra della linea di base e (sottraendo 68 da 88) 20 pixel al di sotto della linea di base. Il Left valore 6 indica che il testo inizia sei pixel a destra del valore X nella DrawText chiamata. Ciò consente la spaziatura tra caratteri normale. Se si desidera visualizzare il testo in modo angolare nell'angolo superiore sinistro dello schermo, passare i negativi di questi Left valori e Top come coordinate X e Y di DrawText, in questo esempio, -6 e 68.

La SKRect struttura definisce diverse proprietà e metodi utili, alcuni dei quali vengono usati nel resto del PaintSurface gestore. I MidX valori e MidY indicano le coordinate del centro del rettangolo. (Nell'esempio i Telefono 7, questi valori sono 338.4107 e -24. Il codice seguente usa questi valori per il calcolo più semplice delle coordinate per centrare il testo sullo schermo:

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);
    ...
}

La SKImageInfo struttura delle informazioni definisce anche una Rect proprietà di tipo SKRect, in modo da poter anche calcolare xText e yText come segue:

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

Il PaintSurface gestore termina con due chiamate a DrawRoundRect, entrambe le quali richiedono argomenti di SKRect. Questo SKRect valore è basato sul SKRect valore ottenuto dal MeasureText metodo , ma non può essere lo stesso. In primo luogo, deve essere un po 'più grande in modo che il rettangolo arrotondato non disegnare sui bordi del testo. In secondo luogo, deve essere spostato nello spazio in modo che i Left valori e Top corrispondano all'angolo superiore sinistro in cui deve essere posizionato il rettangolo. Questi due processi vengono eseguiti dai Offset metodi e Inflate definiti da SKRect:

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);
}

In seguito, il resto del metodo è semplice. Crea un altro SKPaint oggetto per i bordi e chiama DrawRoundRect due volte. La seconda chiamata usa un rettangolo gonfiato da un altro 10 pixel. La prima chiamata specifica un raggio dell'angolo di 20 pixel. Il secondo ha un raggio dell'angolo di 30 pixel, quindi sembrano essere paralleli:

Screenshot triplo della pagina Testo incorniciato

È possibile ruotare il telefono o il simulatore lateralmente per visualizzare l'aumento delle dimensioni del testo e della cornice.

Se devi solo centrare del testo sullo schermo, puoi farlo approssimativamente senza misurare il testo. Impostare invece la TextAlign proprietà di sul membro SKTextAlign.Centerdi SKPaint enumerazione . La coordinata X specificata nel DrawText metodo indica quindi dove è posizionato il centro orizzontale del testo. Se passi il punto intermedio dello schermo al DrawText metodo, il testo verrà centrato orizzontalmente e quasi verticalmente centrato perché la linea di base verrà allineata al centro verticalmente.

Il testo può essere trattato in modo analogo a qualsiasi altro oggetto grafico. Una semplice opzione consiste nel visualizzare la struttura dei caratteri di testo:

Screenshot triplo della pagina Testo delineato

Questa operazione viene eseguita semplicemente modificando la proprietà normale Style dell'oggetto dall'impostazione SKPaint predefinita di SKPaintStyle.Fill a SKPaintStyle.Strokee specificando una larghezza del tratto. Il PaintSurface gestore della pagina Testo delineato mostra come viene eseguita:

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);
}

Un altro oggetto grafico comune è la bitmap. Questo è un argomento di grandi dimensioni trattato in dettaglio nella sezione SkiaSharp Bitmaps, ma l'articolo successivo, Bitmap Basics in SkiaSharp, fornisce una breve introduzione.