Windows平台下Skia使用技巧二

www.visual-gear.com 原创技术文章

在上一篇文章中我们介绍了如何在一张内存位图上使用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;
            }

 

通过以上的计算我们就可以将文字正确的绘制出来。

下一篇文档我们将介绍多行文字的绘制方法。

posted @ 2018-09-30 10:51  Visual-Gear  阅读(1435)  评论(0编辑  收藏  举报