我需要解析一些SVG文件的路径,它们是简单的行。检索数据时,我最终得到这个字符串:
m 0,666.6479 254.28571,0
根据SVG规格,m表示新的当前点,则后面的2个数字是位置,而后者是与第一个相对的位置。
这样会创建一条从(0,666.6479)到(254.28,666.64)
的线我如何在Objective-C中解析它,以便最终得到那些CGPoint
或更多?{/ p>
我知道如果它找到m
,则以下2个逗号分隔的数字应该是我的第一个点,并且在每个空格之后有2个逗号分隔的数字,我应该总和到当前点以获得下一个
我不知道如何正确解析这个问题。
谢谢!
答案 0 :(得分:2)
我会直接使用C,因为:
const char *str = [myString UTF8String];
while(*str)
{
switch(*str)
{
case 'm':
state = START;
break;
case ' ':
if(state == START) /* we are just after the m */
{
state = POINT;
point = 0;
break;
}
else if(state == POINT)
{
if(sscanf(str, "%f,%f", &x, &y) != 2)
/* handle error; */
/* save point somewhere */
point++;
}
break;
}
str++;
}
请注意,我刚刚在编辑框中写了这个,只是以它为例。
另一种方法是使用NSScanner
,但我觉得上述方法更符合您的要求。
答案 1 :(得分:2)
这是一个用于将SVG路径转换为Objective-C的小型原型。这绝不是任何接近完成的事情,但它可能对某人有帮助:
答案 2 :(得分:1)
“m”命令只需要两个参数:x和y坐标。但是“M”(大写)采用绝对坐标,“m”(小写)采用相对坐标。因此,如果您当前的坐标(在“m”命令之前)是(100,100),则示例中的相对移动将使它们(100,766.6479)。
事实上,在这两个坐标之后没有新的命令字母意味着下一个命令也是一个相对移动,所以这会带你到(354.28571,766.6479)。
来自SVG 1.1 spec:
可以删除命令信 在后续命令上如果相同 命令在a中多次使用 行(例如,您可以删除第二个“L” 在“M 100 200 L 200 100 L -100 -200”中 并使用“M 100 200 L 200 100 -100 -200“而不是。”
您可以使用NSScanner来解析十进制数字:
NSScanner *scanner = [NSScanner scannerWithString:aString];
float num = 0;
BOOL success = [scanner scanFloat:&num];
if (succes) {
// Do something
}
else {
// Throw exception
}
正确解析SVG文件有点棘手,因为规范对数据的格式化非常放松。如果你想编写一个足够强大的解析器来接受任何来源的输入(Illustrator,InkScape ......),我建议你仔细看看Batik project's microsyntax parsers。 (虽然你可以得到一些体面的工作,可以满足你的需求,而不会有任何接近Batik的复杂性。)