Integración de texto y gráficos
Vea cómo determinar el tamaño de la cadena de texto representada para integrar texto con gráficos SkiaSharp
En este artículo se muestra cómo medir texto, escalar el texto a un tamaño determinado e integrar texto con otros gráficos:
Esa imagen también incluye un rectángulo redondeado. La clase SkiaSharp Canvas
incluye los métodos DrawRect
para dibujar un rectángulo y los métodos DrawRoundRect
para dibujar un rectángulo con esquinas redondeadas. Estos métodos permiten definir el rectángulo como un valor de SKRect
o de otras maneras.
La página Texto enmarcadocentra una corta cadena de texto en la página y la rodea con un marco compuesto por un par de rectángulos redondeados. En la clase FramedTextPage
se muestra cómo se hace.
En SkiaSharp, se usa la clase SKPaint
para establecer atributos de texto y fuente, pero también se puede usar para obtener el tamaño representado del texto. El principio del siguiente controlador de eventos PaintSurface
llama a dos diferentes métodos MeasureText
. La primera llamada MeasureText
tiene un argumento string
simple y devuelve el ancho de píxel del texto en función de los atributos de fuente actuales. A continuación, el programa calcula una nueva propiedad TextSize
del objeto SKPaint
en función de ese ancho representado, la propiedad TextSize
actual y el ancho del área de visualización. Este cálculo está pensado para establecer TextSize
para que la cadena de texto se represente al 90 % del ancho de la pantalla:
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 segunda llamada MeasureText
tiene un argumento SKRect
, por lo que obtiene tanto un ancho como un alto del texto representado. La propiedad Height
de este valor de SKRect
depende de la presencia de letras mayúsculas, ascendentes y descendientes en la cadena de texto. Se notifican valores de Height
diferentes para las cadenas de texto "mom", "cat" y "dog", por ejemplo.
Las propiedades Left
y Top
de la estructura SKRect
indican las coordenadas de la esquina superior izquierda del texto representado si se muestra el texto mediante una llamada DrawText
con posiciones X e Y de 0. Por ejemplo, cuando este programa se ejecuta en un simulador de iPhone 7, TextSize
se asigna el valor 90.6254 como resultado del cálculo después de la primera llamada a MeasureText
. El valor SKRect
obtenido de la segunda llamada a MeasureText
tiene los siguientes valores de propiedad:
Left
= 6Top
= –68Width
= 664.8214Height
= 88;
Tenga en cuenta que las coordenadas X e Y que pasan al método DrawText
especifican el lado izquierdo del texto en la línea base. El valor Top
indica que el texto extiende 68 píxeles por encima de esa línea de base y (restando 68 de 88) 20 píxeles por debajo de la línea base. El valor Left
de 6 indica que el texto comienza seis píxeles a la derecha del valor X en la llamada a DrawText
. Esto permite el espaciado entre caracteres normal. Si desea mostrar el texto correctamente en la esquina superior izquierda de la pantalla, pase los negativos de estos valores Left
y Top
como coordenadas X e Y de DrawText
, en este ejemplo, –6 y 68.
La estructura SKRect
define varias propiedades y métodos útiles, algunos de los cuales se usan en el resto del controlador de PaintSurface
. Los valores MidX
y MidY
indican las coordenadas del centro del rectángulo. (En el ejemplo de iPhone 7, esos valores son 338.4107 y –24). El código siguiente usa estos valores para el cálculo más sencillo de las coordenadas para centrar el texto en la pantalla:
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 estructura de información SKImageInfo
también define una propiedad Rect
de tipo SKRect
, por lo que también puede calcular xText
y yText
de esta manera:
float xText = info.Rect.MidX - textBounds.MidX;
float yText = info.Rect.MidY - textBounds.MidY;
El controlador de PaintSurface
concluye con dos llamadas a DrawRoundRect
, que requieren argumentos de SKRect
. Este valor SKRect
se basa en el valor de SKRect
obtenido del método MeasureText
, pero no puede ser el mismo. En primer lugar, debe ser un poco más grande para que el rectángulo redondeado no dibuje sobre los bordes del texto. En segundo lugar, debe desplazarse en el espacio para que los valores Left
y Top
correspondan a la esquina superior izquierda donde se colocará el rectángulo. Estos dos trabajos se realizan mediante los métodos Offset
y 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);
}
Después de eso, el resto del método es sencillo. Crea otro objeto SKPaint
para los bordes y llama a DrawRoundRect
dos veces. La segunda llamada usa un rectángulo inflado por otros 10 píxeles. La primera llamada especifica un radio de esquina de 20 píxeles. El segundo tiene un radio de esquina de 30 píxeles, por lo que parecen ser paralelos:
Puede girar el teléfono o el simulador lateralmente para ver el texto y el aumento del tamaño del marco.
Si solo necesita centrar algún texto en la pantalla, puede hacerlo aproximadamente sin medir el texto. En su lugar, establezca la propiedad TextAlign
de SKPaint
en el miembro de enumeración SKTextAlign.Center
. La coordenada X que especifique en el método DrawText
indica dónde se coloca el centro horizontal del texto. Si pasa el punto medio de la pantalla al método DrawText
, el texto se centrará horizontalmente y casi centrado verticalmente porque la línea base se centrará verticalmente.
El texto se puede tratar como cualquier otro objeto gráfico. Una opción sencilla es mostrar el contorno de los caracteres de texto:
Esto se logra simplemente cambiando la propiedad normal Style
del objeto SKPaint
de su valor predeterminado de SKPaintStyle.Fill
a SKPaintStyle.Stroke
y especificando un ancho de trazo. El controlador PaintSurface
de la página Texto delineado muestra cómo se realiza:
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);
}
Otro objeto gráfico común es el mapa de bits. Este es un tema amplio que se trata en profundidad en la sección mapas de bits SkiaSharp, pero el siguiente artículo, conceptos básicos de mapa de bits en SkiaSharp, proporciona una breve introducción.