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:
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
= 6Top
= –68Width
= 664,8214Height
= 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:
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.Center
de 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:
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.