上回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 *);
是一个函数指针:
- 输入参数为 QSvgNode *, const QXmlStreamAttributes &, QSvgHandler *
- 返回类型:QSvgNode *
- 函数指针名为 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源码就做到了