| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkSVGParser.h" | 10 #include "SkSVGParser.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #include "SkSVGText.h" | 31 #include "SkSVGText.h" |
| 32 #include "SkSVGUse.h" | 32 #include "SkSVGUse.h" |
| 33 #include "SkTSearch.h" | 33 #include "SkTSearch.h" |
| 34 #include <stdio.h> | 34 #include <stdio.h> |
| 35 | 35 |
| 36 static int gGeneratedMatrixID = 0; | 36 static int gGeneratedMatrixID = 0; |
| 37 | 37 |
| 38 SkSVGParser::SkSVGParser(SkXMLParserError* errHandler) : | 38 SkSVGParser::SkSVGParser(SkXMLParserError* errHandler) : |
| 39 SkXMLParser(errHandler), | 39 SkXMLParser(errHandler), |
| 40 fHead(&fEmptyPaint), fIDs(256), | 40 fHead(&fEmptyPaint), fIDs(256), |
| 41 fXMLWriter(&fStream), fCurrElement(NULL), fInSVG(false), fSuppressPaint(
false) { | 41 fXMLWriter(&fStream), fCurrElement(nullptr), fInSVG(false), fSuppressPai
nt(false) { |
| 42 fLastTransform.reset(); | 42 fLastTransform.reset(); |
| 43 fEmptyPaint.f_fill.set("black"); | 43 fEmptyPaint.f_fill.set("black"); |
| 44 fEmptyPaint.f_stroke.set("none"); | 44 fEmptyPaint.f_stroke.set("none"); |
| 45 fEmptyPaint.f_strokeMiterlimit.set("4"); | 45 fEmptyPaint.f_strokeMiterlimit.set("4"); |
| 46 fEmptyPaint.f_fillRule.set("winding"); | 46 fEmptyPaint.f_fillRule.set("winding"); |
| 47 fEmptyPaint.f_opacity.set("1"); | 47 fEmptyPaint.f_opacity.set("1"); |
| 48 fEmptyPaint.fNext = NULL; | 48 fEmptyPaint.fNext = nullptr; |
| 49 for (int index = SkSVGPaint::kInitial + 1; index < SkSVGPaint::kTerminal; in
dex++) { | 49 for (int index = SkSVGPaint::kInitial + 1; index < SkSVGPaint::kTerminal; in
dex++) { |
| 50 SkString* initial = fEmptyPaint[index]; | 50 SkString* initial = fEmptyPaint[index]; |
| 51 if (initial->size() == 0) | 51 if (initial->size() == 0) |
| 52 continue; | 52 continue; |
| 53 fLastFlush[index]->set(*initial); | 53 fLastFlush[index]->set(*initial); |
| 54 } | 54 } |
| 55 } | 55 } |
| 56 | 56 |
| 57 SkSVGParser::~SkSVGParser() { | 57 SkSVGParser::~SkSVGParser() { |
| 58 } | 58 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 SkASSERT(fEmptyPaint[field]); | 122 SkASSERT(fEmptyPaint[field]); |
| 123 return *fEmptyPaint[field]; | 123 return *fEmptyPaint[field]; |
| 124 } | 124 } |
| 125 | 125 |
| 126 bool SkSVGParser::isStrokeAndFill( SkSVGPaint** strokeState, SkSVGPaint** fillS
tate) { | 126 bool SkSVGParser::isStrokeAndFill( SkSVGPaint** strokeState, SkSVGPaint** fillS
tate) { |
| 127 SkSVGPaint* walking = fHead; | 127 SkSVGPaint* walking = fHead; |
| 128 bool stroke = false; | 128 bool stroke = false; |
| 129 bool fill = false; | 129 bool fill = false; |
| 130 bool strokeSet = false; | 130 bool strokeSet = false; |
| 131 bool fillSet = false; | 131 bool fillSet = false; |
| 132 while (walking != NULL) { | 132 while (walking != nullptr) { |
| 133 if (strokeSet == false && walking->f_stroke.size() > 0) { | 133 if (strokeSet == false && walking->f_stroke.size() > 0) { |
| 134 stroke = walking->f_stroke.equals("none") == false; | 134 stroke = walking->f_stroke.equals("none") == false; |
| 135 *strokeState = walking; | 135 *strokeState = walking; |
| 136 strokeSet = true; | 136 strokeSet = true; |
| 137 } | 137 } |
| 138 if (fillSet == false && walking->f_fill.size() > 0) { | 138 if (fillSet == false && walking->f_fill.size() > 0) { |
| 139 fill = walking->f_fill.equals("none") == false; | 139 fill = walking->f_fill.equals("none") == false; |
| 140 *fillState = walking; | 140 *fillState = walking; |
| 141 fillSet = true; | 141 fillSet = true; |
| 142 } | 142 } |
| 143 walking = walking->fNext; | 143 walking = walking->fNext; |
| 144 } | 144 } |
| 145 return stroke && fill; | 145 return stroke && fill; |
| 146 } | 146 } |
| 147 | 147 |
| 148 bool SkSVGParser::onAddAttribute(const char name[], const char value[]) { | 148 bool SkSVGParser::onAddAttribute(const char name[], const char value[]) { |
| 149 return onAddAttributeLen(name, value, strlen(value)); | 149 return onAddAttributeLen(name, value, strlen(value)); |
| 150 } | 150 } |
| 151 | 151 |
| 152 bool SkSVGParser::onAddAttributeLen(const char name[], const char value[], size_
t len) { | 152 bool SkSVGParser::onAddAttributeLen(const char name[], const char value[], size_
t len) { |
| 153 if (fCurrElement == NULL) // this signals we should ignore attributes for
this element | 153 if (fCurrElement == nullptr) // this signals we should ignore attributes
for this element |
| 154 return true; | 154 return true; |
| 155 if (fCurrElement->fIsDef == false && fCurrElement->fIsNotDef == false) | 155 if (fCurrElement->fIsDef == false && fCurrElement->fIsNotDef == false) |
| 156 return false; // also an ignored element | 156 return false; // also an ignored element |
| 157 size_t nameLen = strlen(name); | 157 size_t nameLen = strlen(name); |
| 158 int attrIndex = findAttribute(fCurrElement, name, nameLen, false); | 158 int attrIndex = findAttribute(fCurrElement, name, nameLen, false); |
| 159 if (attrIndex == -1) { | 159 if (attrIndex == -1) { |
| 160 attrIndex = findAttribute(&fCurrElement->fPaintState, name, nameLen, tru
e); | 160 attrIndex = findAttribute(&fCurrElement->fPaintState, name, nameLen, tru
e); |
| 161 if (attrIndex >= 0) { | 161 if (attrIndex >= 0) { |
| 162 fCurrElement->fPaintState.addAttribute(*this, attrIndex, value, len)
; | 162 fCurrElement->fPaintState.addAttribute(*this, attrIndex, value, len)
; |
| 163 return false; | 163 return false; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 return false; | 195 return false; |
| 196 const char* nextColon = strchr(name, ':'); | 196 const char* nextColon = strchr(name, ':'); |
| 197 if (nextColon && (size_t)(nextColon - name) < len) | 197 if (nextColon && (size_t)(nextColon - name) < len) |
| 198 return false; | 198 return false; |
| 199 SkSVGTypes type = GetType(name, len); | 199 SkSVGTypes type = GetType(name, len); |
| 200 // SkASSERT(type >= 0); | 200 // SkASSERT(type >= 0); |
| 201 if (type < 0) { | 201 if (type < 0) { |
| 202 type = SkSVGType_G; | 202 type = SkSVGType_G; |
| 203 // return true; | 203 // return true; |
| 204 } | 204 } |
| 205 SkSVGElement* parent = fParents.count() > 0 ? fParents.top() : NULL; | 205 SkSVGElement* parent = fParents.count() > 0 ? fParents.top() : nullptr; |
| 206 SkSVGElement* element = CreateElement(type, parent); | 206 SkSVGElement* element = CreateElement(type, parent); |
| 207 bool result = false; | 207 bool result = false; |
| 208 if (parent) { | 208 if (parent) { |
| 209 element->fParent = parent; | 209 element->fParent = parent; |
| 210 result = fParents.top()->onStartElement(element); | 210 result = fParents.top()->onStartElement(element); |
| 211 } else | 211 } else |
| 212 *fChildren.append() = element; | 212 *fChildren.append() = element; |
| 213 if (strncmp(name, "svg", len) != 0) | 213 if (strncmp(name, "svg", len) != 0) |
| 214 *fParents.append() = element; | 214 *fParents.append() = element; |
| 215 fCurrElement = element; | 215 fCurrElement = element; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 230 static int32_t strokeFillID = 0; | 230 static int32_t strokeFillID = 0; |
| 231 | 231 |
| 232 void SkSVGParser::translate(SkSVGElement* element, bool isDef) { | 232 void SkSVGParser::translate(SkSVGElement* element, bool isDef) { |
| 233 SkSVGPaint::Push(&fHead, &element->fPaintState); | 233 SkSVGPaint::Push(&fHead, &element->fPaintState); |
| 234 bool isFlushable = element->isFlushable(); | 234 bool isFlushable = element->isFlushable(); |
| 235 if ((element->fIsDef == false && element->fIsNotDef == false) || | 235 if ((element->fIsDef == false && element->fIsNotDef == false) || |
| 236 (element->fIsDef && isDef == false && element->fIsNotDef == false) || | 236 (element->fIsDef && isDef == false && element->fIsNotDef == false) || |
| 237 (element->fIsDef == false && isDef && element->fIsNotDef)) { | 237 (element->fIsDef == false && isDef && element->fIsNotDef)) { |
| 238 isFlushable = false; | 238 isFlushable = false; |
| 239 } | 239 } |
| 240 SkSVGPaint* strokeState = NULL, * fillState = NULL; | 240 SkSVGPaint* strokeState = nullptr, * fillState = nullptr; |
| 241 if (isFlushable) | 241 if (isFlushable) |
| 242 element->fPaintState.setSave(*this); | 242 element->fPaintState.setSave(*this); |
| 243 if (isFlushable && isStrokeAndFill(&strokeState, &fillState)) { | 243 if (isFlushable && isStrokeAndFill(&strokeState, &fillState)) { |
| 244 SkString& elementID = element->f_id; | 244 SkString& elementID = element->f_id; |
| 245 if (elementID.size() == 0) { | 245 if (elementID.size() == 0) { |
| 246 elementID.set("sf"); | 246 elementID.set("sf"); |
| 247 elementID.appendS32(++strokeFillID); | 247 elementID.appendS32(++strokeFillID); |
| 248 } | 248 } |
| 249 SkString saveStroke(strokeState->f_stroke); | 249 SkString saveStroke(strokeState->f_stroke); |
| 250 SkString saveFill(fillState->f_fill); | 250 SkString saveFill(fillState->f_fill); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 281 _startElement("matrix"); | 281 _startElement("matrix"); |
| 282 char idStr[24]; | 282 char idStr[24]; |
| 283 strcpy(idStr, "sk_matrix"); | 283 strcpy(idStr, "sk_matrix"); |
| 284 sprintf(idStr + strlen(idStr), "%d", gGeneratedMatrixID); | 284 sprintf(idStr + strlen(idStr), "%d", gGeneratedMatrixID); |
| 285 _addAttribute("id", idStr); | 285 _addAttribute("id", idStr); |
| 286 stringID->set(idStr); | 286 stringID->set(idStr); |
| 287 const char* str = string.c_str(); | 287 const char* str = string.c_str(); |
| 288 SkASSERT(strncmp(str, "matrix(", 7) == 0); | 288 SkASSERT(strncmp(str, "matrix(", 7) == 0); |
| 289 str += 6; | 289 str += 6; |
| 290 const char* strEnd = strrchr(str, ')'); | 290 const char* strEnd = strrchr(str, ')'); |
| 291 SkASSERT(strEnd != NULL); | 291 SkASSERT(strEnd != nullptr); |
| 292 SkString mat(str, strEnd - str); | 292 SkString mat(str, strEnd - str); |
| 293 ConvertToArray(mat); | 293 ConvertToArray(mat); |
| 294 const char* elems[6]; | 294 const char* elems[6]; |
| 295 static const int order[] = {0, 3, 1, 4, 2, 5}; | 295 static const int order[] = {0, 3, 1, 4, 2, 5}; |
| 296 const int* orderPtr = order; | 296 const int* orderPtr = order; |
| 297 str = mat.c_str(); | 297 str = mat.c_str(); |
| 298 strEnd = str + mat.size(); | 298 strEnd = str + mat.size(); |
| 299 while (str < strEnd) { | 299 while (str < strEnd) { |
| 300 elems[*orderPtr++] = str; | 300 elems[*orderPtr++] = str; |
| 301 while (str < strEnd && *str != ',' ) | 301 while (str < strEnd && *str != ',' ) |
| 302 str++; | 302 str++; |
| 303 str++; | 303 str++; |
| 304 } | 304 } |
| 305 string.reset(); | 305 string.reset(); |
| 306 for (int index = 0; index < 6; index++) { | 306 for (int index = 0; index < 6; index++) { |
| 307 const char* end = strchr(elems[index], ','); | 307 const char* end = strchr(elems[index], ','); |
| 308 if (end == NULL) | 308 if (end == nullptr) |
| 309 end= strchr(elems[index], ']'); | 309 end= strchr(elems[index], ']'); |
| 310 string.append(elems[index], end - elems[index] + 1); | 310 string.append(elems[index], end - elems[index] + 1); |
| 311 } | 311 } |
| 312 string.remove(string.size() - 1, 1); | 312 string.remove(string.size() - 1, 1); |
| 313 string.append(",0,0,1]"); | 313 string.append(",0,0,1]"); |
| 314 _addAttribute("matrix", string); | 314 _addAttribute("matrix", string); |
| 315 _endElement(); // matrix | 315 _endElement(); // matrix |
| 316 } | 316 } |
| 317 | 317 |
| 318 static bool is_whitespace(char ch) { | 318 static bool is_whitespace(char ch) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 349 undoLastComma: | 349 undoLastComma: |
| 350 while (is_whitespace(valCh[--index])) | 350 while (is_whitespace(valCh[--index])) |
| 351 ; | 351 ; |
| 352 if (valCh[index] == ',') | 352 if (valCh[index] == ',') |
| 353 valCh[index] = ' '; | 353 valCh[index] = ' '; |
| 354 } | 354 } |
| 355 | 355 |
| 356 #define CASE_NEW(type) case SkSVGType_##type : created = new SkSVG##type(); brea
k | 356 #define CASE_NEW(type) case SkSVGType_##type : created = new SkSVG##type(); brea
k |
| 357 | 357 |
| 358 SkSVGElement* SkSVGParser::CreateElement(SkSVGTypes type, SkSVGElement* parent)
{ | 358 SkSVGElement* SkSVGParser::CreateElement(SkSVGTypes type, SkSVGElement* parent)
{ |
| 359 SkSVGElement* created = NULL; | 359 SkSVGElement* created = nullptr; |
| 360 switch (type) { | 360 switch (type) { |
| 361 CASE_NEW(Circle); | 361 CASE_NEW(Circle); |
| 362 CASE_NEW(ClipPath); | 362 CASE_NEW(ClipPath); |
| 363 CASE_NEW(Defs); | 363 CASE_NEW(Defs); |
| 364 CASE_NEW(Ellipse); | 364 CASE_NEW(Ellipse); |
| 365 CASE_NEW(FeColorMatrix); | 365 CASE_NEW(FeColorMatrix); |
| 366 CASE_NEW(Filter); | 366 CASE_NEW(Filter); |
| 367 CASE_NEW(G); | 367 CASE_NEW(G); |
| 368 CASE_NEW(Image); | 368 CASE_NEW(Image); |
| 369 CASE_NEW(Line); | 369 CASE_NEW(Line); |
| 370 CASE_NEW(LinearGradient); | 370 CASE_NEW(LinearGradient); |
| 371 CASE_NEW(Mask); | 371 CASE_NEW(Mask); |
| 372 CASE_NEW(Metadata); | 372 CASE_NEW(Metadata); |
| 373 CASE_NEW(Path); | 373 CASE_NEW(Path); |
| 374 CASE_NEW(Polygon); | 374 CASE_NEW(Polygon); |
| 375 CASE_NEW(Polyline); | 375 CASE_NEW(Polyline); |
| 376 CASE_NEW(RadialGradient); | 376 CASE_NEW(RadialGradient); |
| 377 CASE_NEW(Rect); | 377 CASE_NEW(Rect); |
| 378 CASE_NEW(Stop); | 378 CASE_NEW(Stop); |
| 379 CASE_NEW(SVG); | 379 CASE_NEW(SVG); |
| 380 CASE_NEW(Symbol); | 380 CASE_NEW(Symbol); |
| 381 CASE_NEW(Text); | 381 CASE_NEW(Text); |
| 382 CASE_NEW(Tspan); | 382 CASE_NEW(Tspan); |
| 383 CASE_NEW(Use); | 383 CASE_NEW(Use); |
| 384 default: | 384 default: |
| 385 SkASSERT(0); | 385 SkASSERT(0); |
| 386 return NULL; | 386 return nullptr; |
| 387 } | 387 } |
| 388 created->fParent = parent; | 388 created->fParent = parent; |
| 389 bool isDef = created->fIsDef = created->isDef(); | 389 bool isDef = created->fIsDef = created->isDef(); |
| 390 bool isNotDef = created->fIsNotDef = created->isNotDef(); | 390 bool isNotDef = created->fIsNotDef = created->isNotDef(); |
| 391 if (isDef) { | 391 if (isDef) { |
| 392 SkSVGElement* up = parent; | 392 SkSVGElement* up = parent; |
| 393 while (up && up->fIsDef == false) { | 393 while (up && up->fIsDef == false) { |
| 394 up->fIsDef = true; | 394 up->fIsDef = true; |
| 395 up = up->fParent; | 395 up = up->fParent; |
| 396 } | 396 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 }; | 432 }; |
| 433 | 433 |
| 434 const int kSVGTypeNamesSize = SK_ARRAY_COUNT(gSVGTypeNames); | 434 const int kSVGTypeNamesSize = SK_ARRAY_COUNT(gSVGTypeNames); |
| 435 | 435 |
| 436 SkSVGTypes SkSVGParser::GetType(const char match[], size_t len ) { | 436 SkSVGTypes SkSVGParser::GetType(const char match[], size_t len ) { |
| 437 int index = SkStrSearch(&gSVGTypeNames[0].fName, kSVGTypeNamesSize, match, | 437 int index = SkStrSearch(&gSVGTypeNames[0].fName, kSVGTypeNamesSize, match, |
| 438 len, sizeof(gSVGTypeNames[0])); | 438 len, sizeof(gSVGTypeNames[0])); |
| 439 return index >= 0 && index < kSVGTypeNamesSize ? gSVGTypeNames[index].fType
: | 439 return index >= 0 && index < kSVGTypeNamesSize ? gSVGTypeNames[index].fType
: |
| 440 (SkSVGTypes) -1; | 440 (SkSVGTypes) -1; |
| 441 } | 441 } |
| OLD | NEW |