Index: src/svg/parser/SkSVGParser.cpp |
diff --git a/src/svg/parser/SkSVGParser.cpp b/src/svg/parser/SkSVGParser.cpp |
deleted file mode 100644 |
index 6243e37e94cdfa2f7296bc6f4b5ba7e950444e01..0000000000000000000000000000000000000000 |
--- a/src/svg/parser/SkSVGParser.cpp |
+++ /dev/null |
@@ -1,440 +0,0 @@ |
-/* |
- * Copyright 2006 The Android Open Source Project |
- * |
- * Use of this source code is governed by a BSD-style license that can be |
- * found in the LICENSE file. |
- */ |
- |
- |
-#include "SkSVGParser.h" |
-#include "SkSVGCircle.h" |
-#include "SkSVGClipPath.h" |
-#include "SkSVGDefs.h" |
-#include "SkSVGEllipse.h" |
-#include "SkSVGFeColorMatrix.h" |
-#include "SkSVGFilter.h" |
-#include "SkSVGG.h" |
-#include "SkSVGImage.h" |
-#include "SkSVGLine.h" |
-#include "SkSVGLinearGradient.h" |
-#include "SkSVGMask.h" |
-#include "SkSVGMetadata.h" |
-#include "SkSVGPath.h" |
-#include "SkSVGPolygon.h" |
-#include "SkSVGPolyline.h" |
-#include "SkSVGRadialGradient.h" |
-#include "SkSVGRect.h" |
-#include "SkSVGSVG.h" |
-#include "SkSVGStop.h" |
-#include "SkSVGSymbol.h" |
-#include "SkSVGText.h" |
-#include "SkSVGUse.h" |
-#include "SkTSearch.h" |
-#include <stdio.h> |
- |
-static int gGeneratedMatrixID = 0; |
- |
-SkSVGParser::SkSVGParser(SkXMLParserError* errHandler) : |
- SkXMLParser(errHandler), |
- fHead(&fEmptyPaint), fIDs(256), |
- fXMLWriter(&fStream), fCurrElement(nullptr), fInSVG(false), fSuppressPaint(false) { |
- fLastTransform.reset(); |
- fEmptyPaint.f_fill.set("black"); |
- fEmptyPaint.f_stroke.set("none"); |
- fEmptyPaint.f_strokeMiterlimit.set("4"); |
- fEmptyPaint.f_fillRule.set("winding"); |
- fEmptyPaint.f_opacity.set("1"); |
- fEmptyPaint.fNext = nullptr; |
- for (int index = SkSVGPaint::kInitial + 1; index < SkSVGPaint::kTerminal; index++) { |
- SkString* initial = fEmptyPaint[index]; |
- if (initial->size() == 0) |
- continue; |
- fLastFlush[index]->set(*initial); |
- } |
-} |
- |
-SkSVGParser::~SkSVGParser() { |
-} |
- |
-void SkSVGParser::Delete(SkTDArray<SkSVGElement*>& fChildren) { |
- SkSVGElement** ptr; |
- for (ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { |
- Delete((*ptr)->fChildren); |
- delete *ptr; |
- } |
-} |
- |
-int SkSVGParser::findAttribute(SkSVGBase* element, const char* attrValue, |
- size_t len, bool isPaint) { |
- const SkSVGAttribute* attributes; |
- size_t count = element->getAttributes(&attributes); |
- size_t result = 0; |
- while (result < count) { |
- if (strncmp(attributes->fName, attrValue, len) == 0 && strlen(attributes->fName) == len) { |
- SkASSERT(result == (attributes->fOffset - |
- (isPaint ? sizeof(SkString) : sizeof(SkSVGElement))) / sizeof(SkString)); |
- return result; |
- } |
- attributes++; |
- result++; |
- } |
- return -1; |
-} |
- |
-#if 0 |
-const char* SkSVGParser::getFinal() { |
- _startElement("screenplay"); |
- // generate defs |
- SkSVGElement** ptr; |
- for (ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { |
- SkSVGElement* element = *ptr; |
- translate(element, true); |
- } |
- // generate onLoad |
- _startElement("event"); |
- _addAttribute("kind", "onLoad"); |
- _startElement("paint"); |
- _addAttribute("antiAlias", "true"); |
- _endElement(); |
- for (ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { |
- SkSVGElement* element = *ptr; |
- translate(element, false); |
- } |
- _endElement(); // event |
- _endElement(); // screenplay |
- Delete(fChildren); |
- fStream.write("", 1); |
- return fStream.getStream(); |
-} |
-#endif |
- |
-SkString& SkSVGParser::getPaintLast(SkSVGPaint::Field field) { |
- SkSVGPaint* state = fHead; |
- do { |
- SkString* attr = (*state)[field]; |
- SkASSERT(attr); |
- if (attr->size() > 0) |
- return *attr; |
- state = state->fNext; |
- } while (state); |
- SkASSERT(0); |
- SkASSERT(fEmptyPaint[field]); |
- return *fEmptyPaint[field]; |
-} |
- |
-bool SkSVGParser::isStrokeAndFill( SkSVGPaint** strokeState, SkSVGPaint** fillState) { |
- SkSVGPaint* walking = fHead; |
- bool stroke = false; |
- bool fill = false; |
- bool strokeSet = false; |
- bool fillSet = false; |
- while (walking != nullptr) { |
- if (strokeSet == false && walking->f_stroke.size() > 0) { |
- stroke = walking->f_stroke.equals("none") == false; |
- *strokeState = walking; |
- strokeSet = true; |
- } |
- if (fillSet == false && walking->f_fill.size() > 0) { |
- fill = walking->f_fill.equals("none") == false; |
- *fillState = walking; |
- fillSet = true; |
- } |
- walking = walking->fNext; |
- } |
- return stroke && fill; |
-} |
- |
-bool SkSVGParser::onAddAttribute(const char name[], const char value[]) { |
- return onAddAttributeLen(name, value, strlen(value)); |
-} |
- |
-bool SkSVGParser::onAddAttributeLen(const char name[], const char value[], size_t len) { |
- if (fCurrElement == nullptr) // this signals we should ignore attributes for this element |
- return true; |
- if (fCurrElement->fIsDef == false && fCurrElement->fIsNotDef == false) |
- return false; // also an ignored element |
- size_t nameLen = strlen(name); |
- int attrIndex = findAttribute(fCurrElement, name, nameLen, false); |
- if (attrIndex == -1) { |
- attrIndex = findAttribute(&fCurrElement->fPaintState, name, nameLen, true); |
- if (attrIndex >= 0) { |
- fCurrElement->fPaintState.addAttribute(*this, attrIndex, value, len); |
- return false; |
- } |
- if (nameLen == 2 && strncmp("id", name, nameLen) == 0) { |
- fCurrElement->f_id.set(value, len); |
- return false; |
- } |
- if (strchr(name, ':') != 0) // part of a different namespace |
- return false; |
- } |
- SkASSERT(attrIndex >= 0); |
- fCurrElement->addAttribute(*this, attrIndex, value, len); |
- return false; |
-} |
- |
-bool SkSVGParser::onEndElement(const char elem[]) { |
- int parentIndex = fParents.count() - 1; |
- if (parentIndex >= 0) { |
- SkSVGElement* element = fParents[parentIndex]; |
- element->onEndElement(*this); |
- fParents.remove(parentIndex); |
- } |
- return false; |
-} |
- |
-bool SkSVGParser::onStartElement(const char name[]) { |
- return onStartElementLen(name, strlen(name)); |
-} |
- |
-bool SkSVGParser::onStartElementLen(const char name[], size_t len) { |
- if (strncmp(name, "svg", len) == 0) { |
- fInSVG = true; |
- } else if (fInSVG == false) |
- return false; |
- const char* nextColon = strchr(name, ':'); |
- if (nextColon && (size_t)(nextColon - name) < len) |
- return false; |
- SkSVGTypes type = GetType(name, len); |
-// SkASSERT(type >= 0); |
- if (type < 0) { |
- type = SkSVGType_G; |
-// return true; |
- } |
- SkSVGElement* parent = fParents.count() > 0 ? fParents.top() : nullptr; |
- SkSVGElement* element = CreateElement(type, parent); |
- bool result = false; |
- if (parent) { |
- element->fParent = parent; |
- result = fParents.top()->onStartElement(element); |
- } else |
- *fChildren.append() = element; |
- if (strncmp(name, "svg", len) != 0) |
- *fParents.append() = element; |
- fCurrElement = element; |
- return result; |
-} |
- |
-bool SkSVGParser::onText(const char text[], int len) { |
- if (fInSVG == false) |
- return false; |
- SkSVGTypes type = fCurrElement->getType(); |
- if (type != SkSVGType_Text && type != SkSVGType_Tspan) |
- return false; |
- SkSVGText* textElement = (SkSVGText*) fCurrElement; |
- textElement->f_text.set(text, len); |
- return false; |
-} |
- |
-static int32_t strokeFillID = 0; |
- |
-void SkSVGParser::translate(SkSVGElement* element, bool isDef) { |
- SkSVGPaint::Push(&fHead, &element->fPaintState); |
- bool isFlushable = element->isFlushable(); |
- if ((element->fIsDef == false && element->fIsNotDef == false) || |
- (element->fIsDef && isDef == false && element->fIsNotDef == false) || |
- (element->fIsDef == false && isDef && element->fIsNotDef)) { |
- isFlushable = false; |
- } |
- SkSVGPaint* strokeState = nullptr, * fillState = nullptr; |
- if (isFlushable) |
- element->fPaintState.setSave(*this); |
- if (isFlushable && isStrokeAndFill(&strokeState, &fillState)) { |
- SkString& elementID = element->f_id; |
- if (elementID.size() == 0) { |
- elementID.set("sf"); |
- elementID.appendS32(++strokeFillID); |
- } |
- SkString saveStroke(strokeState->f_stroke); |
- SkString saveFill(fillState->f_fill); |
- strokeState->f_stroke.set("none"); |
- element->fPaintState.flush(*this, isFlushable, isDef); |
- element->translate(*this, isDef); |
- strokeState->f_stroke.set(saveStroke); |
- fillState->f_fill.set("none"); |
- if (element->fPaintState.flush(*this, isFlushable, isDef)) { |
- _startElement("add"); |
- _addAttributeLen("use", elementID.c_str(), elementID.size()); |
- _endElement(); // add |
- } |
- fillState->f_fill.set(saveFill); |
- } else { |
- element->fPaintState.flush(*this, isFlushable, isDef); |
- if (isFlushable || element->isGroup()) |
- element->translate(*this, isDef); |
- } |
- SkSVGPaint::Pop(&fHead); |
-} |
- |
-void SkSVGParser::translateMatrix(SkString& string, SkString* stringID) { |
- if (string.size() == 0) |
- return; |
- if (stringID->size() > 0) { |
- _startElement("add"); |
- _addAttribute("use", stringID->c_str()); |
- _endElement(); // add |
- return; |
- } |
- SkASSERT(strncmp(string.c_str(), "matrix", 6) == 0); |
- ++gGeneratedMatrixID; |
- _startElement("matrix"); |
- char idStr[24]; |
- strcpy(idStr, "sk_matrix"); |
- sprintf(idStr + strlen(idStr), "%d", gGeneratedMatrixID); |
- _addAttribute("id", idStr); |
- stringID->set(idStr); |
- const char* str = string.c_str(); |
- SkASSERT(strncmp(str, "matrix(", 7) == 0); |
- str += 6; |
- const char* strEnd = strrchr(str, ')'); |
- SkASSERT(strEnd != nullptr); |
- SkString mat(str, strEnd - str); |
- ConvertToArray(mat); |
- const char* elems[6]; |
- static const int order[] = {0, 3, 1, 4, 2, 5}; |
- const int* orderPtr = order; |
- str = mat.c_str(); |
- strEnd = str + mat.size(); |
- while (str < strEnd) { |
- elems[*orderPtr++] = str; |
- while (str < strEnd && *str != ',' ) |
- str++; |
- str++; |
- } |
- string.reset(); |
- for (int index = 0; index < 6; index++) { |
- const char* end = strchr(elems[index], ','); |
- if (end == nullptr) |
- end= strchr(elems[index], ']'); |
- string.append(elems[index], end - elems[index] + 1); |
- } |
- string.remove(string.size() - 1, 1); |
- string.append(",0,0,1]"); |
- _addAttribute("matrix", string); |
- _endElement(); // matrix |
-} |
- |
-static bool is_whitespace(char ch) { |
- return ch > 0 && ch <= ' '; |
-} |
- |
-void SkSVGParser::ConvertToArray(SkString& vals) { |
- vals.appendUnichar(']'); |
- char* valCh = (char*) vals.c_str(); |
- valCh[0] = '['; |
- int index = 1; |
- while (valCh[index] != ']') { |
- while (is_whitespace(valCh[index])) |
- index++; |
- bool foundComma = false; |
- char next; |
- do { |
- next = valCh[index++]; |
- if (next == ',') { |
- foundComma = true; |
- continue; |
- } |
- if (next == ']') { |
- index--; |
- goto undoLastComma; |
- } |
- if (next == ' ') |
- break; |
- foundComma = false; |
- } while (is_whitespace(next) == false); |
- if (foundComma == false) |
- valCh[index - 1] = ','; |
- } |
-undoLastComma: |
- while (is_whitespace(valCh[--index])) |
- ; |
- if (valCh[index] == ',') |
- valCh[index] = ' '; |
-} |
- |
-#define CASE_NEW(type) case SkSVGType_##type : created = new SkSVG##type(); break |
- |
-SkSVGElement* SkSVGParser::CreateElement(SkSVGTypes type, SkSVGElement* parent) { |
- SkSVGElement* created = nullptr; |
- switch (type) { |
- CASE_NEW(Circle); |
- CASE_NEW(ClipPath); |
- CASE_NEW(Defs); |
- CASE_NEW(Ellipse); |
- CASE_NEW(FeColorMatrix); |
- CASE_NEW(Filter); |
- CASE_NEW(G); |
- CASE_NEW(Image); |
- CASE_NEW(Line); |
- CASE_NEW(LinearGradient); |
- CASE_NEW(Mask); |
- CASE_NEW(Metadata); |
- CASE_NEW(Path); |
- CASE_NEW(Polygon); |
- CASE_NEW(Polyline); |
- CASE_NEW(RadialGradient); |
- CASE_NEW(Rect); |
- CASE_NEW(Stop); |
- CASE_NEW(SVG); |
- CASE_NEW(Symbol); |
- CASE_NEW(Text); |
- CASE_NEW(Tspan); |
- CASE_NEW(Use); |
- default: |
- SkASSERT(0); |
- return nullptr; |
- } |
- created->fParent = parent; |
- bool isDef = created->fIsDef = created->isDef(); |
- bool isNotDef = created->fIsNotDef = created->isNotDef(); |
- if (isDef) { |
- SkSVGElement* up = parent; |
- while (up && up->fIsDef == false) { |
- up->fIsDef = true; |
- up = up->fParent; |
- } |
- } |
- if (isNotDef) { |
- SkSVGElement* up = parent; |
- while (up && up->fIsNotDef == false) { |
- up->fIsNotDef = true; |
- up = up->fParent; |
- } |
- } |
- return created; |
-} |
- |
-const SkSVGTypeName gSVGTypeNames[] = { |
- {"circle", SkSVGType_Circle}, |
- {"clipPath", SkSVGType_ClipPath}, |
- {"defs", SkSVGType_Defs}, |
- {"ellipse", SkSVGType_Ellipse}, |
- {"feColorMatrix", SkSVGType_FeColorMatrix}, |
- {"filter", SkSVGType_Filter}, |
- {"g", SkSVGType_G}, |
- {"image", SkSVGType_Image}, |
- {"line", SkSVGType_Line}, |
- {"linearGradient", SkSVGType_LinearGradient}, |
- {"mask", SkSVGType_Mask}, |
- {"metadata", SkSVGType_Metadata}, |
- {"path", SkSVGType_Path}, |
- {"polygon", SkSVGType_Polygon}, |
- {"polyline", SkSVGType_Polyline}, |
- {"radialGradient", SkSVGType_RadialGradient}, |
- {"rect", SkSVGType_Rect}, |
- {"stop", SkSVGType_Stop}, |
- {"svg", SkSVGType_SVG}, |
- {"symbol", SkSVGType_Symbol}, |
- {"text", SkSVGType_Text}, |
- {"tspan", SkSVGType_Tspan}, |
- {"use", SkSVGType_Use} |
-}; |
- |
-const int kSVGTypeNamesSize = SK_ARRAY_COUNT(gSVGTypeNames); |
- |
-SkSVGTypes SkSVGParser::GetType(const char match[], size_t len ) { |
- int index = SkStrSearch(&gSVGTypeNames[0].fName, kSVGTypeNamesSize, match, |
- len, sizeof(gSVGTypeNames[0])); |
- return index >= 0 && index < kSVGTypeNamesSize ? gSVGTypeNames[index].fType : |
- (SkSVGTypes) -1; |
-} |