Windows平台下Skia使用技巧三

2019-10-01

www.qt-ui.com 原创技术文章

上一篇中我们介绍了单行文字的绘制方法,这里我们介绍多行文字的绘制。

Skia中没有多行文字的绘制API,给我们多行文字的绘制造成了麻烦。需要计算出每行文字的内容,然后逐行进行绘制。

还在Skia的文字计算处理非常准确,也让我们可以增加行高,不同行对齐等复杂的多行处理特性。

在绘制多行字符串钱,我们需要先对字符串进行分割,分割的字符为 "\n"

std::vector<std::wstring>* vecStrings = NULL;
SplitStringW(text, L"\n", vecStrings);
...
void SplitStringW(UIGearsCore::wstrPtr strInput, UIGearsCore::wstrPtr splitWord, std::vector<std::wstring>*& vecRet)
    {
        if (vecRet != UIGNull)
        {
            return;
        }       

        if (strInput == UIGNull || splitWord == UIGNull)
        {
            return;
        }

        s32 wordLen = wcslen(splitWord);
        if (wordLen == 0)
        {
            return;
        }

        s32 strLen = wcslen(strInput);
        if (strLen == 0)
        {
            return;
        }

        vecRet = new std::vector<std::wstring>();

        std::wstring str = strInput;

        s32 startPos = 0;
        s32 pos = str.find(splitWord);
        while (pos != -1)
        {
            std::wstring subStr = str.substr(startPos, pos - startPos);
            vecRet->push_back(subStr);
            startPos = pos + wordLen;
            pos = str.find(splitWord, pos + wordLen);
        }

        if (startPos != str.length())
        {
            std::wstring subStr = str.substr(startPos, -1);
            vecRet->push_back(subStr);
        }
    }

通过SplitStringW我们将字符进行了分割处理。

通过SkPaint的breakText方法可以计算给定宽度可以容纳的字符数量,如果等于字符字节数则代表不需要换行。 如果小于字符字节数则代表需要换行处理。

    SkScalar measuredWidth;
    s32 txtLength = (s32)wcslen(text) * 2;
    s32 curTxtLength = txtLength;
    std::vector<s32> linePos;
    wstrPtr newLineText = text;
    for (size_t j = 0; j < txtLength;)
    {
        s32 widthByte = paint.breakText(newLineText, curTxtLength, w, &measuredWidth);
        if (widthByte < 2)
        {
            break;
        }

        newLineText += widthByte / 2;
        curTxtLength -= widthByte;
        j += widthByte;

        linePos.push_back(widthByte);
    }

linePos中存放了每行的字节数量。 最后我们逐行进行字符串绘制。

if (linePos.size() > 0)
{
    SkScalar posX = 0;
    s32 offset = 0;
    for (size_t i = 0; i < linePos.size(); i++)
    {
        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;
        }

        if (offsetY == 0)
        {
            offsetY += -metrics.fTop;
        }
        else
        {
            offsetY += -metrics.fTop + metrics.fBottom;
        }

        if (i == 0)
        {
            _canvas->drawText(text, linePos[i], posX, y + offsetY, paint);
        }
        else
        {
            wstrPtr newLineText = text + offset / 2;
            _canvas->drawText(newLineText, linePos[i], posX, y + offsetY, paint);
        }
        offset += linePos[i];
    }
}

offsetY 为累计的行起始位置。 posX为该行的字符X坐标位置。

下一节我们将介绍富文本内容的绘制方法。

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

使用视频教程

author

New Qt Designer使用文档

author

Qt控件库 API

author

模板项目文档



Copyright © 2018-2021 www.qt-ui.com
鄂ICP备20004169号