Partilhar via


Integração de texto e elementos gráficos

Veja como determinar o tamanho da cadeia de caracteres de texto renderizado para integrar texto com gráficos SkiaSharp

Este artigo demonstra como medir texto, dimensionar o texto para um tamanho específico e integrar texto com outros elementos gráficos:

Texto cercado por retângulos

Essa imagem também inclui um retângulo arredondado. A classe SkiaSharp Canvas inclui DrawRect métodos para desenhar um retângulo e DrawRoundRect métodos para desenhar um retângulo com cantos arredondados. Esses métodos permitem que o retângulo seja definido como um SKRect valor ou de outras maneiras.

A página Texto Enquadrado centraliza uma cadeia de texto curta na página e a envolve com um quadro composto por um par de retângulos arredondados. A FramedTextPage aula mostra como é feito.

No SkiaSharp, você usa a SKPaint classe para definir atributos de texto e fonte, mas também pode usá-la para obter o tamanho renderizado do texto. O início do manipulador de eventos a seguir PaintSurface chama dois métodos diferentes MeasureText . A primeira MeasureText chamada tem um argumento simples string e retorna a largura de pixel do texto com base nos atributos de fonte atuais. Em seguida, o programa calcula SKPaint uma nova TextSize propriedade do objeto com base nessa largura renderizada, na propriedade atual TextSize e na largura da área de exibição. Este cálculo destina-se a definir TextSize de modo que a cadeia de texto a ser renderizada em 90% da largura da tela:

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

A segunda MeasureText chamada tem um SKRect argumento, portanto, obtém uma largura e altura do texto renderizado. A Height propriedade desse SKRect valor depende da presença de letras maiúsculas, ascendentes e descendentes na cadeia de caracteres de texto. Valores diferentes Height são relatados para as cadeias de texto "mãe", "gato" e "cachorro", por exemplo.

As Left propriedades e Top da SKRect estrutura indicam as coordenadas do canto superior esquerdo do texto renderizado se o texto for exibido por uma DrawText chamada com as posições X e Y de 0. Por exemplo, quando este programa está sendo executado em um simulador do iPhone 7, TextSize é atribuído o valor 90.6254 como resultado do cálculo após a primeira chamada para MeasureText. O SKRect valor obtido da segunda chamada para MeasureText tem os seguintes valores de propriedade:

  • Left = 6
  • Top = –68
  • Width = 664,8214
  • Height = 88;

Lembre-se de que as coordenadas X e Y passadas para o DrawText método especificam o lado esquerdo do texto na linha de base. O Top valor indica que o texto se estende 68 pixels acima dessa linha de base e (subtraindo 68 de 88) 20 pixels abaixo da linha de base. O Left valor 6 indica que o texto começa seis pixels à direita do valor X na DrawText chamada. Isso permite o espaçamento normal entre caracteres. Se você quiser exibir o texto confortavelmente no canto superior esquerdo da tela, passe os negativos desses Left e Top valores como as coordenadas X e Y de DrawText, neste exemplo, –6 e 68.

A SKRect estrutura define várias propriedades e métodos úteis, alguns dos quais são usados no restante do PaintSurface manipulador. Os MidX valores e MidY indicam as coordenadas do centro do retângulo. (No exemplo do iPhone 7, esses valores são 338.4107 e –24.) O código a seguir usa esses valores para o cálculo mais fácil de coordenadas para centralizar o texto na exibição:

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

A SKImageInfo estrutura de informações também define uma Rect propriedade do tipo SKRect, para que você também possa calcular xText e yText assim:

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

O PaintSurface manipulador conclui com duas chamadas para DrawRoundRect, ambas exigindo argumentos de SKRect. Esse SKRect valor é baseado no SKRect valor obtido do MeasureText método, mas não pode ser o mesmo. Primeiro, ele precisa ser um pouco maior para que o retângulo arredondado não se desenhe sobre as bordas do texto. Em segundo lugar, ele precisa ser deslocado no espaço para que os Left valores e Top correspondam ao canto superior esquerdo onde o retângulo deve ser posicionado. Estes dois trabalhos são realizados pelos Offset métodos e Inflate definidos por 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);
}

Depois disso, o restante do método é simples. Ele cria outro SKPaint objeto para as bordas e chama DrawRoundRect duas vezes. A segunda chamada usa um retângulo inflado por outros 10 pixels. A primeira chamada especifica um raio de canto de 20 pixels. O segundo tem um raio de canto de 30 pixels, então eles parecem ser paralelos:

Captura de tela tripla da página Texto emoldurado

Você pode virar seu telefone ou simulador para os lados para ver o texto e o quadro aumentarem de tamanho.

Se você só precisa centralizar algum texto na tela, você pode fazê-lo aproximadamente sem medir o texto. Em vez disso, defina a TextAlign propriedade de para o membro SKTextAlign.Centerde SKPaint enumeração . A coordenada X especificada no DrawText método indica onde o centro horizontal do texto está posicionado. Se você passar o ponto médio da tela para o DrawText método, o texto será centralizado horizontalmente e quase verticalmente centralizado porque a linha de base será centralizada verticalmente.

O texto pode ser tratado como qualquer outro objeto gráfico. Uma opção simples é exibir o contorno dos caracteres de texto:

Captura de tela tripla da página Texto Destacado

Isso é feito simplesmente alterando a propriedade normal Style do objeto de sua configuração padrão de para SKPaintStyle.Stroke, e especificando uma largura de SKPaintStyle.Fill traçado.SKPaint O PaintSurface manipulador da página Texto Destacado mostra como é feito:

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

Outro objeto gráfico comum é o bitmap. Esse é um grande tópico abordado em profundidade na seção SkiaSharp Bitmaps, mas o próximo artigo, Noções básicas de bitmap no SkiaSharp, fornece uma breve introdução.