180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGParser.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGCircle.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGClipPath.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGDefs.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGEllipse.h" 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGFeColorMatrix.h" 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGFilter.h" 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGG.h" 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGImage.h" 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGLine.h" 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGLinearGradient.h" 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGMask.h" 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGMetadata.h" 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGPath.h" 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGPolygon.h" 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGPolyline.h" 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGRadialGradient.h" 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGRect.h" 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGSVG.h" 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGStop.h" 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGSymbol.h" 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGText.h" 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSVGUse.h" 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTSearch.h" 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <stdio.h> 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic int gGeneratedMatrixID = 0; 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkSVGParser::SkSVGParser(SkXMLParserError* errHandler) : 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXMLParser(errHandler), 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fHead(&fEmptyPaint), fIDs(256), 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fXMLWriter(&fStream), fCurrElement(NULL), fInSVG(false), fSuppressPaint(false) { 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fLastTransform.reset(); 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEmptyPaint.f_fill.set("black"); 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEmptyPaint.f_stroke.set("none"); 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEmptyPaint.f_strokeMiterlimit.set("4"); 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEmptyPaint.f_fillRule.set("winding"); 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEmptyPaint.f_opacity.set("1"); 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEmptyPaint.fNext = NULL; 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int index = SkSVGPaint::kInitial + 1; index < SkSVGPaint::kTerminal; index++) { 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString* initial = fEmptyPaint[index]; 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (initial->size() == 0) 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru continue; 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fLastFlush[index]->set(*initial); 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkSVGParser::~SkSVGParser() { 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkSVGParser::Delete(SkTDArray<SkSVGElement*>& fChildren) { 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGElement** ptr; 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Delete((*ptr)->fChildren); 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete *ptr; 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkSVGParser::findAttribute(SkSVGBase* element, const char* attrValue, 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t len, bool isPaint) { 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkSVGAttribute* attributes; 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t count = element->getAttributes(&attributes); 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t result = 0; 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (result < count) { 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (strncmp(attributes->fName, attrValue, len) == 0 && strlen(attributes->fName) == len) { 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(result == (attributes->fOffset - 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (isPaint ? sizeof(SkString) : sizeof(SkSVGElement))) / sizeof(SkString)); 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return result; 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru attributes++; 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru result++; 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return -1; 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* SkSVGParser::getFinal() { 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _startElement("screenplay"); 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // generate defs 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGElement** ptr; 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGElement* element = *ptr; 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru translate(element, true); 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // generate onLoad 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _startElement("event"); 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _addAttribute("kind", "onLoad"); 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _startElement("paint"); 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _addAttribute("antiAlias", "true"); 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _endElement(); 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGElement* element = *ptr; 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru translate(element, false); 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _endElement(); // event 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _endElement(); // screenplay 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Delete(fChildren); 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fStream.write("", 1); 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fStream.getStream(); 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkString& SkSVGParser::getPaintLast(SkSVGPaint::Field field) { 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGPaint* state = fHead; 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString* attr = (*state)[field]; 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(attr); 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (attr->size() > 0) 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return *attr; 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru state = state->fNext; 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (state); 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(0); 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fEmptyPaint[field]); 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return *fEmptyPaint[field]; 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkSVGParser::isStrokeAndFill( SkSVGPaint** strokeState, SkSVGPaint** fillState) { 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGPaint* walking = fHead; 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool stroke = false; 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool fill = false; 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool strokeSet = false; 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool fillSet = false; 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (walking != NULL) { 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (strokeSet == false && walking->f_stroke.size() > 0) { 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru stroke = walking->f_stroke.equals("none") == false; 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *strokeState = walking; 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru strokeSet = true; 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fillSet == false && walking->f_fill.size() > 0) { 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fill = walking->f_fill.equals("none") == false; 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *fillState = walking; 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fillSet = true; 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru walking = walking->fNext; 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return stroke && fill; 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkSVGParser::onAddAttribute(const char name[], const char value[]) { 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return onAddAttributeLen(name, value, strlen(value)); 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkSVGParser::onAddAttributeLen(const char name[], const char value[], size_t len) { 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fCurrElement == NULL) // this signals we should ignore attributes for this element 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fCurrElement->fIsDef == false && fCurrElement->fIsNotDef == false) 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; // also an ignored element 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t nameLen = strlen(name); 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int attrIndex = findAttribute(fCurrElement, name, nameLen, false); 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (attrIndex == -1) { 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru attrIndex = findAttribute(&fCurrElement->fPaintState, name, nameLen, true); 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (attrIndex >= 0) { 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCurrElement->fPaintState.addAttribute(*this, attrIndex, value, len); 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (nameLen == 2 && strncmp("id", name, nameLen) == 0) { 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCurrElement->f_id.set(value, len); 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (strchr(name, ':') != 0) // part of a different namespace 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(attrIndex >= 0); 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCurrElement->addAttribute(*this, attrIndex, value, len); 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkSVGParser::onEndElement(const char elem[]) { 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int parentIndex = fParents.count() - 1; 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (parentIndex >= 0) { 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGElement* element = fParents[parentIndex]; 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru element->onEndElement(*this); 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fParents.remove(parentIndex); 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkSVGParser::onStartElement(const char name[]) { 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return onStartElementLen(name, strlen(name)); 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkSVGParser::onStartElementLen(const char name[], size_t len) { 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (strncmp(name, "svg", len) == 0) { 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fInSVG = true; 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (fInSVG == false) 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* nextColon = strchr(name, ':'); 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (nextColon && (size_t)(nextColon - name) < len) 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGTypes type = GetType(name, len); 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// SkASSERT(type >= 0); 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (type < 0) { 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru type = SkSVGType_G; 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// return true; 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGElement* parent = fParents.count() > 0 ? fParents.top() : NULL; 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGElement* element = CreateElement(type, parent); 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool result = false; 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (parent) { 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru element->fParent = parent; 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru result = fParents.top()->onStartElement(element); 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *fChildren.append() = element; 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (strncmp(name, "svg", len) != 0) 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *fParents.append() = element; 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCurrElement = element; 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return result; 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkSVGParser::onText(const char text[], int len) { 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fInSVG == false) 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGTypes type = fCurrElement->getType(); 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (type != SkSVGType_Text && type != SkSVGType_Tspan) 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGText* textElement = (SkSVGText*) fCurrElement; 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru textElement->f_text.set(text, len); 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic int32_t strokeFillID = 0; 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkSVGParser::translate(SkSVGElement* element, bool isDef) { 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGPaint::Push(&fHead, &element->fPaintState); 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isFlushable = element->isFlushable(); 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((element->fIsDef == false && element->fIsNotDef == false) || 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (element->fIsDef && isDef == false && element->fIsNotDef == false) || 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (element->fIsDef == false && isDef && element->fIsNotDef)) { 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru isFlushable = false; 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGPaint* strokeState = NULL, * fillState = NULL; 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (isFlushable) 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru element->fPaintState.setSave(*this); 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (isFlushable && isStrokeAndFill(&strokeState, &fillState)) { 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString& elementID = element->f_id; 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (elementID.size() == 0) { 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru elementID.set("sf"); 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru elementID.appendS32(++strokeFillID); 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString saveStroke(strokeState->f_stroke); 25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString saveFill(fillState->f_fill); 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru strokeState->f_stroke.set("none"); 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru element->fPaintState.flush(*this, isFlushable, isDef); 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru element->translate(*this, isDef); 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru strokeState->f_stroke.set(saveStroke); 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fillState->f_fill.set("none"); 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (element->fPaintState.flush(*this, isFlushable, isDef)) { 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _startElement("add"); 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _addAttributeLen("use", elementID.c_str(), elementID.size()); 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _endElement(); // add 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fillState->f_fill.set(saveFill); 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru element->fPaintState.flush(*this, isFlushable, isDef); 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (isFlushable || element->isGroup()) 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru element->translate(*this, isDef); 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGPaint::Pop(&fHead); 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkSVGParser::translateMatrix(SkString& string, SkString* stringID) { 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (string.size() == 0) 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (stringID->size() > 0) { 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _startElement("add"); 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _addAttribute("use", stringID->c_str()); 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _endElement(); // add 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(strncmp(string.c_str(), "matrix", 6) == 0); 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ++gGeneratedMatrixID; 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _startElement("matrix"); 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char idStr[24]; 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru strcpy(idStr, "sk_matrix"); 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sprintf(idStr + strlen(idStr), "%d", gGeneratedMatrixID); 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _addAttribute("id", idStr); 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru stringID->set(idStr); 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* str = string.c_str(); 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(strncmp(str, "matrix(", 7) == 0); 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str += 6; 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* strEnd = strrchr(str, ')'); 29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(strEnd != NULL); 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString mat(str, strEnd - str); 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ConvertToArray(mat); 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* elems[6]; 29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int order[] = {0, 3, 1, 4, 2, 5}; 29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const int* orderPtr = order; 29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str = mat.c_str(); 29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru strEnd = str + mat.size(); 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (str < strEnd) { 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru elems[*orderPtr++] = str; 30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (str < strEnd && *str != ',' ) 30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str++; 30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str++; 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru string.reset(); 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int index = 0; index < 6; index++) { 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* end = strchr(elems[index], ','); 30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (end == NULL) 30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru end= strchr(elems[index], ']'); 31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru string.append(elems[index], end - elems[index] + 1); 31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru string.remove(string.size() - 1, 1); 31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru string.append(",0,0,1]"); 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _addAttribute("matrix", string); 31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru _endElement(); // matrix 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool is_whitespace(char ch) { 31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return ch > 0 && ch <= ' '; 32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkSVGParser::ConvertToArray(SkString& vals) { 32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vals.appendUnichar(']'); 32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* valCh = (char*) vals.c_str(); 32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru valCh[0] = '['; 32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int index = 1; 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (valCh[index] != ']') { 32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (is_whitespace(valCh[index])) 32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru index++; 33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool foundComma = false; 33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char next; 33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru next = valCh[index++]; 33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (next == ',') { 33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru foundComma = true; 33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru continue; 33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (next == ']') { 33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru index--; 34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru goto undoLastComma; 34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (next == ' ') 34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru foundComma = false; 34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (is_whitespace(next) == false); 34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (foundComma == false) 34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru valCh[index - 1] = ','; 34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruundoLastComma: 35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (is_whitespace(valCh[--index])) 35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ; 35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (valCh[index] == ',') 35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru valCh[index] = ' '; 35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define CASE_NEW(type) case SkSVGType_##type : created = new SkSVG##type(); break 35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkSVGElement* SkSVGParser::CreateElement(SkSVGTypes type, SkSVGElement* parent) { 35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGElement* created = NULL; 36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (type) { 36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Circle); 36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(ClipPath); 36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Defs); 36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Ellipse); 36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(FeColorMatrix); 36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Filter); 36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(G); 36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Image); 36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Line); 37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(LinearGradient); 37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Mask); 37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Metadata); 37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Path); 37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Polygon); 37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Polyline); 37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(RadialGradient); 37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Rect); 37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Stop); 37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(SVG); 38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Symbol); 38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Text); 38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Tspan); 38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CASE_NEW(Use); 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(0); 38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru created->fParent = parent; 38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isDef = created->fIsDef = created->isDef(); 39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isNotDef = created->fIsNotDef = created->isNotDef(); 39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (isDef) { 39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGElement* up = parent; 39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (up && up->fIsDef == false) { 39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru up->fIsDef = true; 39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru up = up->fParent; 39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (isNotDef) { 39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSVGElement* up = parent; 40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (up && up->fIsNotDef == false) { 40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru up->fIsNotDef = true; 40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru up = up->fParent; 40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return created; 40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst SkSVGTypeName gSVGTypeNames[] = { 40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"circle", SkSVGType_Circle}, 41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"clipPath", SkSVGType_ClipPath}, 41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"defs", SkSVGType_Defs}, 41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"ellipse", SkSVGType_Ellipse}, 41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"feColorMatrix", SkSVGType_FeColorMatrix}, 41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"filter", SkSVGType_Filter}, 41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"g", SkSVGType_G}, 41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"image", SkSVGType_Image}, 41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"line", SkSVGType_Line}, 41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"linearGradient", SkSVGType_LinearGradient}, 41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"mask", SkSVGType_Mask}, 42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"metadata", SkSVGType_Metadata}, 42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"path", SkSVGType_Path}, 42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"polygon", SkSVGType_Polygon}, 42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"polyline", SkSVGType_Polyline}, 42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"radialGradient", SkSVGType_RadialGradient}, 42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"rect", SkSVGType_Rect}, 42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"stop", SkSVGType_Stop}, 42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"svg", SkSVGType_SVG}, 42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"symbol", SkSVGType_Symbol}, 42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"text", SkSVGType_Text}, 43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"tspan", SkSVGType_Tspan}, 43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru {"use", SkSVGType_Use} 43280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst int kSVGTypeNamesSize = SK_ARRAY_COUNT(gSVGTypeNames); 43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkSVGTypes SkSVGParser::GetType(const char match[], size_t len ) { 43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int index = SkStrSearch(&gSVGTypeNames[0].fName, kSVGTypeNamesSize, match, 43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru len, sizeof(gSVGTypeNames[0])); 43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return index >= 0 && index < kSVGTypeNamesSize ? gSVGTypeNames[index].fType : 44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (SkSVGTypes) -1; 44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 442