qt svg模块源码解析2

上回qt svg模块源码解析1 说到 解析标签名的首字母判断标签的含义,我们继续

看一下怎么解析出圆等形状
svg 圆代码

  <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />

标签名为: circle

首先传入标签名 name = circle
根据首字母 name.at(0).unicode() 识别 ,进入switch
如果剩下的字符串是:“ircle” 判断为 圆
返回createCircleNode

static FactoryMethod findGraphicsFactory(const QString &name)
{
    if (name.isEmpty())
        return 0;
    QStringRef ref(&name, 1, name.length() - 1);
    switch (name.at(0).unicode()) {
    case 'a':
        if (ref == QLatin1String("nimation")) return createAnimationNode;
        break;
    case 'c':
        if (ref == QLatin1String("ircle")) return createCircleNode;
        break;
    case 'e':
        if (ref == QLatin1String("llipse")) return createEllipseNode;
        break;
    case 'i':
        if (ref == QLatin1String("mage")) return createImageNode;
        break;
    case 'l':
        if (ref == QLatin1String("ine")) return createLineNode;
        break;
    case 'p':
        if (ref == QLatin1String("ath")) return createPathNode;
        if (ref == QLatin1String("olygon")) return createPolygonNode;
        if (ref == QLatin1String("olyline")) return createPolylineNode;
        break;
    case 'r':
        if (ref == QLatin1String("ect")) return createRectNode;
        break;
    case 't':
        if (ref == QLatin1String("ext")) return createTextNode;
        if (ref == QLatin1String("extArea")) return createTextAreaNode;
        if (ref == QLatin1String("span")) return createTspanNode;
        break;
    case 'u':
        if (ref == QLatin1String("se")) return createUseNode;
        break;
    case 'v':
        if (ref == QLatin1String("ideo")) return createVideoNode;
        break;
    default:
        break;
    }
    return 0;
}

其中 createCircleNode 是 FactoryMethod 类型

typedef QSvgNode *(*FactoryMethod)(QSvgNode *, const QXmlStreamAttributes &, QSvgHandler *);

是一个函数指针:

  1. 输入参数为 QSvgNode *, const QXmlStreamAttributes &, QSvgHandler *
  2. 返回类型:QSvgNode *
  3. 函数指针名为 FactoryMethod

具体 创建圆的函数如下:

static QSvgNode *createCircleNode(QSvgNode *parent,
                                  const QXmlStreamAttributes &attributes,
                                  QSvgHandler *)
{
    const QStringRef cx      = attributes.value(QLatin1String("cx"));
    const QStringRef cy      = attributes.value(QLatin1String("cy"));
    const QStringRef r       = attributes.value(QLatin1String("r"));
    qreal ncx = toDouble(cx);
    qreal ncy = toDouble(cy);
    qreal nr  = toDouble(r);
    QRectF rect(ncx-nr, ncy-nr, nr*2, nr*2);
    QSvgNode *circle = new QSvgCircle(parent, rect);
    return circle;
}


//调用
if (FactoryMethod method = findGroupFactory(localName))
{
    //group
    node = method(m_doc ? m_nodes.top() : 0, attributes, this);
}

如果函数指针创建成功,则把attributes传给函数
这时进入具体的创建图元的函数,解析图元特有的参数
并new 一个 QSvgCircle,返回基类指针 QSvgNode

消化吸收

第一次看见返回函数指针的做法,如果是我写findGraphicsFactory 函数:
主要功能拆解 字符串name,创建并返回一个 基类指针 QSvgNode
在new QSvgCircle的时候,需要传入attributes 以及 this

所以我写出来的findGraphicsFactory 函数参数就至少包含
const QString & ,SvgNode *, const QXmlStreamAttributes &, QSvgHandler *

这样就显得很冗长,本质上我应该写一个单纯的解析 字符串name 的函数,再写一些new 图元的函数

qt源码就做到了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值