Windows平台下Skia使用技巧二

2019-09-30

www.qt-ui.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;
            }

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

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

Qt商用模板项目

支持C++/Python语言,支持Windows\Linux\MacOS系统,支持X86\ARM\MIPS架构

img02

Qt Stock Exchange Sys

View more

Qt股票交易系统

Qt Stock Exchange System

img02

Qt Robot

View more

QtRobot 视频高清机器人控制系统

Qt Robot System

img02

Qt LED Editor

View more

Qt LED 灯效编辑器

Qt LED Editor

img02

Qt IOT Bike

View more

Qt IOT 物联网自行车

Qt IOT Bike

img02

Qt ECG Monitor

View more

Qt嵌入式床旁心电监护仪

Qt ECG Monitor

img02

Qt AutoDashboard

View more

Qt汽车仪表盘系统

Qt Auto Dashboard

img02

Qt DataMonitor

View more

Qt数据监控系统

Qt Data Monitor

img02

Qt Conference

View more

Qt会议终端系统

Qt Conference System

img02

Qt Video Player

View more

Qt视频播放器

Qt Video Player

img02

Qt NetDisk

View more

Qt网盘系统

Qt SkyDrive

img02

Qt IM

View more

Qt即时通讯系统

Qt IM

img02

Qt Cashier

View more

Qt便利店收银系统

Qt CashierSystem

产品文档

0基础赋能高级Qt界面开发

author

Qt控件库 API

author

使用视频教程

author

New Qt Designer使用文档

author

模板项目文档



武汉维仕杰科技有限公司 ( Wuhan VisualGear Co.,ltd )
Copyright © 2018-2024 www.qt-ui.com
鄂ICP备20004169号