1 /* 2 * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. 3 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 11 * The above copyright notice and this permission notice shall be included in all 12 * copies or substantial portions of the Software. 13 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 */ 22 23 #include "../../lv_conf_internal.h" 24 #if LV_USE_THORVG_INTERNAL 25 26 #ifndef _TVG_SVG_LOADER_COMMON_H_ 27 #define _TVG_SVG_LOADER_COMMON_H_ 28 29 #include "tvgCommon.h" 30 #include "tvgArray.h" 31 32 struct SvgNode; 33 struct SvgStyleGradient; 34 35 //NOTE: Please update simpleXmlNodeTypeToString() as well. 36 enum class SvgNodeType 37 { 38 Doc, 39 G, 40 Defs, 41 Animation, 42 Arc, 43 Circle, 44 Ellipse, 45 Image, 46 Line, 47 Path, 48 Polygon, 49 Polyline, 50 Rect, 51 Text, 52 TextArea, 53 Tspan, 54 Use, 55 Video, 56 ClipPath, 57 Mask, 58 CssStyle, 59 Symbol, 60 Unknown 61 }; 62 63 /* 64 // TODO - remove? 65 enum class SvgLengthType 66 { 67 Percent, 68 Px, 69 Pc, 70 Pt, 71 Mm, 72 Cm, 73 In, 74 }; 75 */ 76 77 enum class SvgFillFlags 78 { 79 Paint = 0x01, 80 Opacity = 0x02, 81 Gradient = 0x04, 82 FillRule = 0x08, 83 ClipPath = 0x16 84 }; 85 86 constexpr bool operator &(SvgFillFlags a, SvgFillFlags b) 87 { 88 return int(a) & int(b); 89 } 90 91 constexpr SvgFillFlags operator |(SvgFillFlags a, SvgFillFlags b) 92 { 93 return SvgFillFlags(int(a) | int(b)); 94 } 95 96 enum class SvgStrokeFlags 97 { 98 Paint = 0x1, 99 Opacity = 0x2, 100 Gradient = 0x4, 101 Scale = 0x8, 102 Width = 0x10, 103 Cap = 0x20, 104 Join = 0x40, 105 Dash = 0x80, 106 Miterlimit = 0x100, 107 DashOffset = 0x200 108 }; 109 110 constexpr bool operator &(SvgStrokeFlags a, SvgStrokeFlags b) 111 { 112 return int(a) & int(b); 113 } 114 115 constexpr SvgStrokeFlags operator |(SvgStrokeFlags a, SvgStrokeFlags b) 116 { 117 return SvgStrokeFlags(int(a) | int(b)); 118 } 119 120 121 enum class SvgGradientType 122 { 123 Linear, 124 Radial 125 }; 126 127 enum class SvgStyleFlags 128 { 129 Color = 0x01, 130 Fill = 0x02, 131 FillRule = 0x04, 132 FillOpacity = 0x08, 133 Opacity = 0x010, 134 Stroke = 0x20, 135 StrokeWidth = 0x40, 136 StrokeLineJoin = 0x80, 137 StrokeLineCap = 0x100, 138 StrokeOpacity = 0x200, 139 StrokeDashArray = 0x400, 140 Transform = 0x800, 141 ClipPath = 0x1000, 142 Mask = 0x2000, 143 MaskType = 0x4000, 144 Display = 0x8000, 145 PaintOrder = 0x10000, 146 StrokeMiterlimit = 0x20000, 147 StrokeDashOffset = 0x40000, 148 }; 149 150 constexpr bool operator &(SvgStyleFlags a, SvgStyleFlags b) 151 { 152 return int(a) & int(b); 153 } 154 155 constexpr SvgStyleFlags operator |(SvgStyleFlags a, SvgStyleFlags b) 156 { 157 return SvgStyleFlags(int(a) | int(b)); 158 } 159 160 enum class SvgStopStyleFlags 161 { 162 StopDefault = 0x0, 163 StopOpacity = 0x01, 164 StopColor = 0x02 165 }; 166 167 constexpr bool operator &(SvgStopStyleFlags a, SvgStopStyleFlags b) 168 { 169 return int(a) & int(b); 170 } 171 172 constexpr SvgStopStyleFlags operator |(SvgStopStyleFlags a, SvgStopStyleFlags b) 173 { 174 return SvgStopStyleFlags(int(a) | int(b)); 175 } 176 177 enum class SvgGradientFlags 178 { 179 None = 0x0, 180 GradientUnits = 0x1, 181 SpreadMethod = 0x2, 182 X1 = 0x4, 183 X2 = 0x8, 184 Y1 = 0x10, 185 Y2 = 0x20, 186 Cx = 0x40, 187 Cy = 0x80, 188 R = 0x100, 189 Fx = 0x200, 190 Fy = 0x400, 191 Fr = 0x800 192 }; 193 194 constexpr bool operator &(SvgGradientFlags a, SvgGradientFlags b) 195 { 196 return int(a) & int(b); 197 } 198 199 constexpr SvgGradientFlags operator |(SvgGradientFlags a, SvgGradientFlags b) 200 { 201 return SvgGradientFlags(int(a) | int(b)); 202 } 203 204 enum class SvgFillRule 205 { 206 Winding = 0, 207 OddEven = 1 208 }; 209 210 enum class SvgMaskType 211 { 212 Luminance = 0, 213 Alpha 214 }; 215 216 //Length type to recalculate %, pt, pc, mm, cm etc 217 enum class SvgParserLengthType 218 { 219 Vertical, 220 Horizontal, 221 Diagonal, 222 //In case of, for example, radius of radial gradient 223 Other 224 }; 225 226 enum class SvgViewFlag 227 { 228 None = 0x0, 229 Width = 0x01, //viewPort width 230 Height = 0x02, //viewPort height 231 Viewbox = 0x04, //viewBox x,y,w,h - used only if all 4 are correctly set 232 WidthInPercent = 0x08, 233 HeightInPercent = 0x10 234 }; 235 236 constexpr bool operator &(SvgViewFlag a, SvgViewFlag b) 237 { 238 return static_cast<int>(a) & static_cast<int>(b); 239 } 240 241 constexpr SvgViewFlag operator |(SvgViewFlag a, SvgViewFlag b) 242 { 243 return SvgViewFlag(int(a) | int(b)); 244 } 245 246 constexpr SvgViewFlag operator ^(SvgViewFlag a, SvgViewFlag b) 247 { 248 return SvgViewFlag(int(a) ^ int(b)); 249 } 250 251 enum class AspectRatioAlign 252 { 253 None, 254 XMinYMin, 255 XMidYMin, 256 XMaxYMin, 257 XMinYMid, 258 XMidYMid, 259 XMaxYMid, 260 XMinYMax, 261 XMidYMax, 262 XMaxYMax 263 }; 264 265 enum class AspectRatioMeetOrSlice 266 { 267 Meet, 268 Slice 269 }; 270 271 struct SvgDocNode 272 { 273 float w; //unit: point or in percentage see: SvgViewFlag 274 float h; //unit: point or in percentage see: SvgViewFlag 275 float vx; 276 float vy; 277 float vw; 278 float vh; 279 SvgViewFlag viewFlag; 280 SvgNode* defs; 281 SvgNode* style; 282 AspectRatioAlign align; 283 AspectRatioMeetOrSlice meetOrSlice; 284 }; 285 286 struct SvgGNode 287 { 288 }; 289 290 struct SvgDefsNode 291 { 292 Array<SvgStyleGradient*> gradients; 293 }; 294 295 struct SvgSymbolNode 296 { 297 float w, h; 298 float vx, vy, vw, vh; 299 AspectRatioAlign align; 300 AspectRatioMeetOrSlice meetOrSlice; 301 bool overflowVisible; 302 bool hasViewBox; 303 bool hasWidth; 304 bool hasHeight; 305 }; 306 307 struct SvgUseNode 308 { 309 float x, y, w, h; 310 bool isWidthSet; 311 bool isHeightSet; 312 SvgNode* symbol; 313 }; 314 315 struct SvgEllipseNode 316 { 317 float cx; 318 float cy; 319 float rx; 320 float ry; 321 }; 322 323 struct SvgCircleNode 324 { 325 float cx; 326 float cy; 327 float r; 328 }; 329 330 struct SvgRectNode 331 { 332 float x; 333 float y; 334 float w; 335 float h; 336 float rx; 337 float ry; 338 bool hasRx; 339 bool hasRy; 340 }; 341 342 struct SvgLineNode 343 { 344 float x1; 345 float y1; 346 float x2; 347 float y2; 348 }; 349 350 struct SvgImageNode 351 { 352 float x, y, w, h; 353 char* href; 354 }; 355 356 struct SvgPathNode 357 { 358 char* path; 359 }; 360 361 struct SvgPolygonNode 362 { 363 Array<float> pts; 364 }; 365 366 struct SvgClipNode 367 { 368 bool userSpace; 369 }; 370 371 struct SvgMaskNode 372 { 373 SvgMaskType type; 374 bool userSpace; 375 }; 376 377 struct SvgCssStyleNode 378 { 379 }; 380 381 struct SvgTextNode 382 { 383 char* text; 384 char* fontFamily; 385 float x, y; 386 float fontSize; 387 }; 388 389 struct SvgLinearGradient 390 { 391 float x1; 392 float y1; 393 float x2; 394 float y2; 395 bool isX1Percentage; 396 bool isY1Percentage; 397 bool isX2Percentage; 398 bool isY2Percentage; 399 }; 400 401 struct SvgRadialGradient 402 { 403 float cx; 404 float cy; 405 float fx; 406 float fy; 407 float r; 408 float fr; 409 bool isCxPercentage; 410 bool isCyPercentage; 411 bool isFxPercentage; 412 bool isFyPercentage; 413 bool isRPercentage; 414 bool isFrPercentage; 415 }; 416 417 struct SvgComposite 418 { 419 char *url; 420 SvgNode* node; 421 bool applying; //flag for checking circular dependency. 422 }; 423 424 struct SvgColor 425 { 426 uint8_t r; 427 uint8_t g; 428 uint8_t b; 429 }; 430 431 struct SvgPaint 432 { 433 SvgStyleGradient* gradient; 434 char *url; 435 SvgColor color; 436 bool none; 437 bool curColor; 438 }; 439 440 struct SvgDash 441 { 442 Array<float> array; 443 float offset; 444 }; 445 446 struct SvgStyleGradient 447 { 448 SvgGradientType type; 449 char* id; 450 char* ref; 451 FillSpread spread; 452 SvgRadialGradient* radial; 453 SvgLinearGradient* linear; 454 Matrix* transform; 455 Array<Fill::ColorStop> stops; 456 SvgGradientFlags flags; 457 bool userSpace; 458 clearSvgStyleGradient459 void clear() 460 { 461 stops.reset(); 462 free(transform); 463 free(radial); 464 free(linear); 465 free(ref); 466 free(id); 467 } 468 }; 469 470 struct SvgStyleFill 471 { 472 SvgFillFlags flags; 473 SvgPaint paint; 474 int opacity; 475 FillRule fillRule; 476 }; 477 478 struct SvgStyleStroke 479 { 480 SvgStrokeFlags flags; 481 SvgPaint paint; 482 int opacity; 483 float scale; 484 float width; 485 float centered; 486 StrokeCap cap; 487 StrokeJoin join; 488 float miterlimit; 489 SvgDash dash; 490 }; 491 492 struct SvgStyleProperty 493 { 494 SvgStyleFill fill; 495 SvgStyleStroke stroke; 496 SvgComposite clipPath; 497 SvgComposite mask; 498 int opacity; 499 SvgColor color; 500 char* cssClass; 501 SvgStyleFlags flags; 502 SvgStyleFlags flagsImportance; //indicates the importance of the flag - if set, higher priority is applied (https://drafts.csswg.org/css-cascade-4/#importance) 503 bool curColorSet; 504 bool paintOrder; //true if default (fill, stroke), false otherwise 505 bool display; 506 }; 507 508 struct SvgNode 509 { 510 SvgNodeType type; 511 SvgNode* parent; 512 Array<SvgNode*> child; 513 char *id; 514 SvgStyleProperty *style; 515 Matrix* transform; 516 union { 517 SvgGNode g; 518 SvgDocNode doc; 519 SvgDefsNode defs; 520 SvgUseNode use; 521 SvgCircleNode circle; 522 SvgEllipseNode ellipse; 523 SvgPolygonNode polygon; 524 SvgPolygonNode polyline; 525 SvgRectNode rect; 526 SvgPathNode path; 527 SvgLineNode line; 528 SvgImageNode image; 529 SvgMaskNode mask; 530 SvgClipNode clip; 531 SvgCssStyleNode cssStyle; 532 SvgSymbolNode symbol; 533 SvgTextNode text; 534 } node; 535 ~SvgNode(); 536 }; 537 538 struct SvgParser 539 { 540 SvgNode* node; 541 SvgStyleGradient* styleGrad; 542 Fill::ColorStop gradStop; 543 SvgStopStyleFlags flags; 544 struct 545 { 546 float x, y, w, h; 547 } global; 548 struct 549 { 550 bool parsedFx; 551 bool parsedFy; 552 } gradient; 553 }; 554 555 struct SvgNodeIdPair 556 { 557 SvgNode* node; 558 char *id; 559 }; 560 561 enum class OpenedTagType : uint8_t 562 { 563 Other = 0, 564 Style, 565 Text 566 }; 567 568 struct SvgLoaderData 569 { 570 Array<SvgNode*> stack; 571 SvgNode* doc = nullptr; 572 SvgNode* def = nullptr; //also used to store nested graphic nodes 573 SvgNode* cssStyle = nullptr; 574 Array<SvgStyleGradient*> gradients; 575 SvgStyleGradient* latestGradient = nullptr; //For stops 576 SvgParser* svgParse = nullptr; 577 Array<SvgNodeIdPair> cloneNodes; 578 Array<SvgNodeIdPair> nodesToStyle; 579 Array<char*> images; //embedded images 580 int level = 0; 581 bool result = false; 582 OpenedTagType openedTag = OpenedTagType::Other; 583 SvgNode* currentGraphicsNode = nullptr; 584 }; 585 586 struct Box 587 { 588 float x, y, w, h; 589 }; 590 591 #endif 592 593 #endif /* LV_USE_THORVG_INTERNAL */ 594 595