2012-07-03 78 views
0

所以我目前正在研究UIView的一個子類,它使用TBXML解析一個SVG XML文件,並去掉'g'路徑指令。然後它將這些指令集傳遞給SvgToBezier - 一個簡單的解析器,它將路徑指令作爲輸入並返回一個UIBezierPath對象。然後將它們繪製在drawRect方法中。從SVG文件中取出Bezier曲線

的路徑渲染罰款,但問題是他們不互相排隊他們應該

我知道(他們的方式,他們在谷歌Chrome,Adobe Illustrator中,等顯示出來)的方式SVGKit庫允許解析複雜的svg文件,但是我想自己寫這個,這樣我就可以擴展對有關概念的理解。

首先,我會告訴你我的drawRect方法,後面是一個SVG文件示例,它是預期的輸出,它是在300x300矩形的iPhone上繪製的實際輸出。

- (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); 


} 

這裏的Raw SVG

這裏的Expected Drawing Result

而這裏的Actual iPhone Output (screenshot from iOS Simulator)

我一直在嘗試用各種計算和CGAffineTransforms的..離開了這一切,代碼因爲它只會讓事情混淆。

感謝您的幫助!

乾杯

編輯: 包括另一種情況下,只是爲了說明的不一致(一致性?)問題的。

Raw

Expected

Actual

回答

0

嘿只想讓誰看了這個才知道,我還沒有解決這個問題,我不就可以了計劃。我正在使用UIWebView。 Safari似乎渲染SVG就好了。我使用了一個HTML包裝器來使SVG縮放以適應其視口。

無論如何,我更喜歡UIWebView,因爲它認爲繪製速度比我的方法快。

乾杯