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 |