0

そのため、現在、 TBXMLを使用して SVG XML ファイルを解析し、「g」パス命令を取り除くUIView のサブクラスに取り組んでいます。次に、これらの一連の命令をSvgToBezier (入力としてパス命令を受け取り、UIBezierPath オブジェクトを返す単純なパーサー) に渡します。次に、drawRect メソッドでそれらを描画します。

パスは正常にレンダリングされますが、問題は、パスが想定どおりに整列していないことです (Google chrome、adobe illustrator などで表示される方法)。

SVGKit ライブラリを使用すると複雑な svg ファイルを解析できることは知っていますが、関連する概念の理解を深めるために、これを自分で作成したいと考えています。

まず、drawRect メソッドを示し、次に SVG ファイルの例を示します。これは予想される出力であり、iPhone で 300x300 の長方形に描画された実際の出力です。

- (void)drawRect:(CGRect)rect
{


//getting the XML from set property
TBXMLElement *root = self.svgRoot.rootXMLElement;

//getting the rect tag, which is the background
TBXMLElement *rectColor = [TBXML childElementNamed:@"rect" parentElement:root];

//getting the first g tag
TBXMLElement *g1 = [TBXML childElementNamed:@"g" parentElement:root];

//and it's child path tag
TBXMLElement *path1 = [TBXML childElementNamed:@"path" parentElement:g1];

//getting the sibbling g tag
TBXMLElement *g2 = g1->nextSibling;

//and it's child path tag
TBXMLElement *path2 = [TBXML childElementNamed:@"path" parentElement:g2];

//create a context reference
CGContextRef ctx = UIGraphicsGetCurrentContext();

//flip the context so the origin points jive
CGContextTranslateCTM(ctx, 0, rect.size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);

//get fill color for first path
const char *str1 = [[TBXML valueOfAttributeNamed:@"fill" forElement:g1] cStringUsingEncoding:NSASCIIStringEncoding];
long x1 = strtol(str1+1, NULL, 16);

UIColor *rgb1 = UIColorFromRGB(x1);

//get fill color for second path
const char *str2 = [[TBXML valueOfAttributeNamed:@"fill" forElement:g2] cStringUsingEncoding:NSASCIIStringEncoding];
long x2 = strtol(str2+1, NULL, 16);

UIColor *rgb2 = UIColorFromRGB(x2);

//get fill color for rect background
const char *str3 = [[TBXML valueOfAttributeNamed:@"fill" forElement:rectColor] cStringUsingEncoding:NSASCIIStringEncoding];
long x3 = strtol(str3+1, NULL, 16);

UIColor *rgb3 = UIColorFromRGB(x3);

//turn them into CGColors
CGColorRef color1 = rgb1.CGColor;
CGColorRef color2 = rgb2.CGColor;
CGColorRef color3 = rgb3.CGColor;

//draw the rect background and fill it
CGContextSetFillColorWithColor(ctx, color3);
CGContextFillRect(ctx, CGRectMake(0, 0, rect.size.width, rect.size.height));


//make a bezier path from the first path tag using SvgToBezier
SvgToBezier *bezier1 = [[SvgToBezier alloc] initFromSVGPathNodeDAttr:[TBXML valueOfAttributeNamed:@"d" forElement:path1] rect:rect];

//make second bezier path
SvgToBezier *bezier2 = [[SvgToBezier alloc] initFromSVGPathNodeDAttr:[TBXML valueOfAttributeNamed:@"d" forElement:path2] rect:rect];


//set fill color for first bezier
CGContextSetFillColorWithColor(ctx, color1);

//draw it
UIBezierPath *bezierPath1 = bezier1.bezier;

CGContextAddPath(ctx, bezierPath1.CGPath);
CGContextDrawPath(ctx, kCGPathEOFill);


//second bezier
CGContextSetFillColorWithColor(ctx, color2);

UIBezierPath *bezierPath2 = bezier2.bezier;

CGContextAddPath(ctx, bezierPath2.CGPath);
CGContextDrawPath(ctx, kCGPathEOFill);


}

これが生のSVGです

予想される描画結果は次のとおりです

そして、これが実際のiPhone出力です(iOSシミュレーターのスクリーンショット)

私はあらゆる種類の計算と CGAffineTransforms を試してきました.. 物事を混乱させるだけなので、コードからすべてを残しました。

助けてくれてありがとう!

乾杯

EDIT:問題の矛盾(一貫性?)を説明するために、別のケースを含めます。

期待される

実際

4

1 に答える 1

0

ねえ、これを読んだ人に知らせたかっただけです。私は問題を解決しておらず、計画もしていません。代わりに UIWebView を使用しています。Safari は SVG を問題なくレンダリングしているようです。HTML ラッパーを使用して、ビューポートに合わせて SVG をスケーリングしました。

とにかくUIWebViewの方が好きです。なぜなら、私の方法よりも速く描画すると思われるからです。

乾杯

于 2012-07-04T02:23:06.747 に答える