Выравнивание кривых Безье, взятых из файлов SVG

Поэтому в настоящее время я работаю над подклассом UIView, который использует TBXML для анализа файлов SVG XML и удаления 'g' инструкции пути. Затем он передает эти наборы инструкций в 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.. оставил все это вне кода, потому что это просто запутает вещи imo.

Спасибо за любую помощь!

Ваше здоровье

РЕДАКТИРОВАТЬ: Включая еще один случай, просто чтобы проиллюстрировать непоследовательность (непротиворечивость?) проблемы.

Необработанный

Ожидается

Фактическое


person Doug    schedule 03.07.2012    source источник


Ответы (1)


Эй, просто хотел, чтобы все, кто читает это, знали, что я не решил проблему и не планирую этого. Вместо этого я использую UIWebView. Safari, похоже, отлично отображает SVG. Я использовал HTML-оболочку, чтобы масштабировать SVG в соответствии с его областью просмотра.

В любом случае мне больше нравится UIWebView, потому что он считает, что рисует быстрее, чем мой метод.

Ваше здоровье

person Doug    schedule 04.07.2012