在上一篇文章中我们介绍了如何在一张内存位图上使用Skia进行绘制。
这里我们将介绍Skia的文字绘制处理方法。 文字处理一直是一个比较复杂的处理流程,计算机需要把文字进行栅格化处理,然后变成图片绘制到窗口上。 目前开源的文字栅格化库如FreeType库,就是专门将文字转换成图片的栅格化库。
Skia当中文字处理也比较麻烦,只能绘制单行文字,所以所有的换行处理,对齐处理都需要我们自己进行计算。
下面我们演示文字的绘制流程:
首先需要定义个painter对象。
SkPaint paint;
paint.setAntiAlias(true);
if (isLCD)
{
paint.setLCDRenderText(true);
}
else
{
paint.setSubpixelText(true);
}
paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
setAntiAlias 打开文字抗锯齿特性 setLCDRenderText 会让字体显示得更加浑厚一些,也更加清晰,但是需要注意的是如果文字的背景是透明的,那么会出现透明混合异常,此时我们需要把LCD字体特性关闭掉。
setTextEncoding 提交给skia的文字字符串的格式为Unicode
paint.setColor(color);
BYTE style = SkTypeface::kNormal;
if (isBold)
{
style |= SkTypeface::kBold;
}
if (isItalic)
{
style |= SkTypeface::kItalic;
}
以上代码依次设置文字颜色,粗体和斜体
SkTypeface *typeFace = SkTypeface::CreateFromName(fontFamily, (SkTypeface::Style)style);
paint.setTypeface(typeFace);
paint.setTextSize(size);
SkTypeface::CreateFromName 用来创建字体对象并设置给painter
通过以上的设置之后我们就可以进行文字绘制了。
s32 txtLength = (s32)wcslen(text);
_canvas->drawText(text, txtLength * 2, posX, posY, paint);
需要注意的是 drawText 的第二个参数是文本的字节数,不是文字个数,由于是Unicode编码,所以字节数等于文字个数乘以2。
文字的垂直对齐处理需要我们自己在给定的范围内自己计算,靠上,垂直居中,靠下。水平居中Skia可以通过参数进行设置。
水平对齐设置过程如下:
SkScalar posX = 0;
SkScalar posY = (SkScalar)y;
switch (horAlignType)
{
case HOR_RIGHT:
posX = (SkScalar)(x + w);
paint.setTextAlign(SkPaint::kRight_Align);
break;
case HOR_CENTER:
posX = (SkScalar)(x + w / 2.0);
paint.setTextAlign(SkPaint::kCenter_Align);
break;
case HOR_LEFT:
default:
posX = (SkScalar)x;
paint.setTextAlign(SkPaint::kLeft_Align);
break;
}
posX是文字的水平坐标位置。
垂直对齐设置过程如下: 我们首先需要得到文字的高度,通过getFontMetrics可以得到字体的高度。
f32 fontHeight, textHeight;
SkPaint::FontMetrics metrics;
paint.getFontMetrics(&metrics);
fontHeight = -metrics.fAscent;
这里我们得到文字的Ascent,由于是从上往下算的,所以是一个负值,我们换成正值就是字体高度。
其他FontMetrics字体参数定义请看下图。
然后我们计算垂直位置
switch (verAlignType)
{
case VER_TOP:
posY = (SkScalar)y + fontHeight;
break;
case VER_BOTTOM:
posY = (SkScalar)(y + h - fontHeight / 2);
break;
case VER_MIDDLE:
default:
posY = (SkScalar)(y + (h + fontHeight) / 2.0f);
break;
}
通过以上的计算我们就可以将文字正确的绘制出来。
下一篇文档我们将介绍多行文字的绘制方法。