svg_loader: reduce binary size
authorHermet Park <chuneon.park@samsung.com>
Fri, 5 Nov 2021 05:00:04 +0000 (14:00 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Mon, 8 Nov 2021 09:01:54 +0000 (18:01 +0900)
removed the std::string usages.

saved 17kb.

src/loaders/svg/tvgSvgLoader.cpp
src/loaders/svg/tvgSvgLoaderCommon.h
src/loaders/svg/tvgSvgSceneBuilder.cpp
src/loaders/svg/tvgXmlParser.cpp

index 3a9e4e9..59197bf 100644 (file)
@@ -88,11 +88,11 @@ static char* _skipSpace(const char* str, const char* end)
 }
 
 
-static string* _copyId(const char* str)
+static char* _copyId(const char* str)
 {
     if (!str) return nullptr;
 
-    return new string(str);
+    return strdup(str);
 }
 
 
@@ -271,8 +271,7 @@ _PARSE_TAG(FillRule, fillRule, FillRule, fillRuleTags, FillRule::Winding)
  * Initial:    none
  * https://www.w3.org/TR/SVG/painting.html
  */
-static inline void
-_parseDashArray(SvgLoaderData* loader, const char *str, SvgDash* dash)
+static void _parseDashArray(SvgLoaderData* loader, const char *str, SvgDash* dash)
 {
     if (!strncmp(str, "none", 4)) return;
 
@@ -296,7 +295,8 @@ _parseDashArray(SvgLoaderData* loader, const char *str, SvgDash* dash)
     if ((*dash).array.count == 1) (*dash).array.push((*dash).array.data[0]);
 }
 
-static string* _idFromUrl(const char* url)
+
+static char* _idFromUrl(const char* url)
 {
     url = _skipSpace(url, nullptr);
     if ((*url) == '(') {
@@ -310,7 +310,14 @@ static string* _idFromUrl(const char* url)
     int i = 0;
     while (url[i] > ' ' && url[i] != ')' && url[i] != '\'') ++i;
 
-    return new string(url, i);
+    //custom strndup() for portability
+    int len = strlen(url);
+    if (i < len) len = i;
+
+    auto ret = (char*) malloc(len + 1);
+    if (!ret) return 0;
+    ret[len] = '\0';
+    return (char*) memcpy(ret, url, len);
 }
 
 
@@ -487,7 +494,7 @@ static constexpr struct
 };
 
 
-static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, string** ref)
+static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char** ref)
 {
     unsigned int len = strlen(str);
     char *red, *green, *blue;
@@ -1561,11 +1568,11 @@ static SvgNode* _createLineNode(SvgLoaderData* loader, SvgNode* parent, const ch
 }
 
 
-static string* _idFromHref(const char* href)
+static char* _idFromHref(const char* href)
 {
     href = _skipSpace(href, nullptr);
     if ((*href) == '#') href++;
-    return new string(href);
+    return strdup(href);
 }
 
 
@@ -1651,15 +1658,15 @@ static SvgNode* _findChildById(const SvgNode* node, const char* id)
 
     auto child = node->child.data;
     for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
-        if (((*child)->id != nullptr) && !strcmp((*child)->id->c_str(), id)) return (*child);
+        if (((*child)->id) && !strcmp((*child)->id, id)) return (*child);
     }
     return nullptr;
 }
 
-static SvgNode* _findNodeById(SvgNode *node, string* id)
+static SvgNode* _findNodeById(SvgNode *node, const char* id)
 {
     SvgNode* result = nullptr;
-    if (node->id && !node->id->compare(*id)) return node;
+    if (node->id && !strcmp(node->id, id)) return node;
 
     if (node->child.count > 0) {
         auto child = node->child.data;
@@ -1685,8 +1692,8 @@ static SvgStyleGradient* _cloneGradient(SvgStyleGradient* from)
 
     auto grad = new SvgStyleGradient;
     grad->type = from->type;
-    grad->id = from->id ? _copyId(from->id->c_str()) : nullptr;
-    grad->ref = from->ref ? _copyId(from->ref->c_str()) : nullptr;
+    grad->id = from->id ? _copyId(from->id) : nullptr;
+    grad->ref = from->ref ? _copyId(from->ref) : nullptr;
     grad->spread = from->spread;
     grad->userSpace = from->userSpace;
 
@@ -1724,10 +1731,10 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
     }
     //Copy style attribute
     *to->style = *from->style;
-    if (from->style->fill.paint.url) to->style->fill.paint.url = new string(from->style->fill.paint.url->c_str());
-    if (from->style->stroke.paint.url) to->style->stroke.paint.url = new string(from->style->stroke.paint.url->c_str());
-    if (from->style->clipPath.url) to->style->clipPath.url = new string(from->style->clipPath.url->c_str());
-    if (from->style->mask.url) to->style->mask.url = new string(from->style->mask.url->c_str());
+    if (from->style->fill.paint.url) to->style->fill.paint.url = strdup(from->style->fill.paint.url);
+    if (from->style->stroke.paint.url) to->style->stroke.paint.url = strdup(from->style->stroke.paint.url);
+    if (from->style->clipPath.url) to->style->clipPath.url = strdup(from->style->clipPath.url);
+    if (from->style->mask.url) to->style->mask.url = strdup(from->style->mask.url);
 
     //Copy node attribute
     switch (from->type) {
@@ -1763,7 +1770,7 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
             break;
         }
         case SvgNodeType::Path: {
-            if (from->node.path.path) to->node.path.path = new string(from->node.path.path->c_str());
+            if (from->node.path.path) to->node.path.path = strdup(from->node.path.path);
             break;
         }
         case SvgNodeType::Polygon: {
@@ -1783,7 +1790,7 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
             to->node.image.y = from->node.image.y;
             to->node.image.w = from->node.image.w;
             to->node.image.h = from->node.image.h;
-            if (from->node.image.href) to->node.image.href = new string(from->node.image.href->c_str());
+            if (from->node.image.href) to->node.image.href = strdup(from->node.image.href);
             break;
         }
         default: {
@@ -1811,21 +1818,18 @@ static void _cloneNode(SvgNode* from, SvgNode* parent)
 }
 
 
-static void _postponeCloneNode(SvgLoaderData* loader, SvgNode *node, string* id) {
-    SvgNodeIdPair nodeIdPair;
-    nodeIdPair.node = node;
-    nodeIdPair.id = id;
-    loader->cloneNodes.push(nodeIdPair);
+static void _postponeCloneNode(SvgLoaderData* loader, SvgNode *node, char* id) {
+    loader->cloneNodes.push({node, id});
 }
 
 
 static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes) {
     for (uint32_t i = 0; i < cloneNodes->count; ++i) {
-        SvgNodeIdPair nodeIdPair = cloneNodes->data[i];
-        SvgNode *defs = _getDefsNode(nodeIdPair.node);
-        SvgNode *nodeFrom = _findChildById(defs, nodeIdPair.id->c_str());
+        auto nodeIdPair = cloneNodes->data[i];
+        auto defs = _getDefsNode(nodeIdPair.node);
+        auto nodeFrom = _findChildById(defs, nodeIdPair.id);
         _cloneNode(nodeFrom, nodeIdPair.node);
-        delete nodeIdPair.id;
+        free(nodeIdPair.id);
     }
 }
 
@@ -1848,7 +1852,7 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value)
 {
     SvgLoaderData* loader = (SvgLoaderData*)data;
     SvgNode *defs, *nodeFrom, *node = loader->svgParse->node;
-    string* id;
+    char* id;
 
     SvgUseNode* use = &(node->node.use);
     int sz = strlen(key);
@@ -1863,7 +1867,7 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value)
     if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
         id = _idFromHref(value);
         defs = _getDefsNode(node);
-        nodeFrom = _findChildById(defs, id->c_str());
+        nodeFrom = _findChildById(defs, id);
         if (nodeFrom) {
             _cloneNode(nodeFrom, node);
             delete id;
@@ -2490,7 +2494,7 @@ static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* paren
         child->fill.paint.color = parent->fill.paint.color;
         child->fill.paint.none = parent->fill.paint.none;
         child->fill.paint.curColor = parent->fill.paint.curColor;
-        if (parent->fill.paint.url) child->fill.paint.url = _copyId(parent->fill.paint.url->c_str());
+        if (parent->fill.paint.url) child->fill.paint.url = _copyId(parent->fill.paint.url);
     } else if (child->fill.paint.curColor && !child->curColorSet) {
         child->color = parent->color;
     }
@@ -2505,7 +2509,7 @@ static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* paren
         child->stroke.paint.color = parent->stroke.paint.color;
         child->stroke.paint.none = parent->stroke.paint.none;
         child->stroke.paint.curColor = parent->stroke.paint.curColor;
-        child->stroke.paint.url = parent->stroke.paint.url ? _copyId(parent->stroke.paint.url->c_str()) : nullptr;
+        child->stroke.paint.url = parent->stroke.paint.url ? _copyId(parent->stroke.paint.url) : nullptr;
     } else if (child->stroke.paint.curColor && !child->curColorSet) {
         child->color = parent->color;
     }
@@ -2543,7 +2547,7 @@ static void _inefficientNodeCheck(TVG_UNUSED SvgNode* node){
 
     switch (node->type) {
         case SvgNodeType::Path: {
-            if (!node->node.path.path || node->node.path.path->empty()) TVGLOG("SVG", "Inefficient elements used [Empty path][Node Type : %s]", type);
+            if (!node->node.path.path) TVGLOG("SVG", "Inefficient elements used [Empty path][Node Type : %s]", type);
             break;
         }
         case SvgNodeType::Ellipse: {
@@ -2585,14 +2589,14 @@ static void _updateStyle(SvgNode* node, SvgStyleProperty* parentStyle)
 }
 
 
-static SvgStyleGradient* _gradientDup(Array<SvgStyleGradient*>* gradients, const string* id)
+static SvgStyleGradient* _gradientDup(Array<SvgStyleGradient*>* gradients, const char* id)
 {
     SvgStyleGradient* result = nullptr;
 
     auto gradList = gradients->data;
 
     for (uint32_t i = 0; i < gradients->count; ++i) {
-        if (!((*gradList)->id->compare(*id))) {
+        if (!strcmp((*gradList)->id, id)) {
             result = _cloneGradient(*gradList);
             break;
         }
@@ -2602,10 +2606,8 @@ static SvgStyleGradient* _gradientDup(Array<SvgStyleGradient*>* gradients, const
     if (result && result->ref) {
         gradList = gradients->data;
         for (uint32_t i = 0; i < gradients->count; ++i) {
-            if (!((*gradList)->id->compare(*result->ref))) {
-                if (result->stops.count == 0) {
-                    _cloneGradStops(result->stops, (*gradList)->stops);
-                }
+            if (!strcmp((*gradList)->id, result->ref)) {
+                if (result->stops.count == 0) _cloneGradStops(result->stops, (*gradList)->stops);
                 //TODO: Properly inherit other property
                 break;
             }
@@ -2661,13 +2663,13 @@ static void _freeNodeStyle(SvgStyleProperty* style)
     if (!style) return;
 
     //style->clipPath.node and style->mask.node has only the addresses of node. Therefore, node is released from _freeNode.
-    delete(style->clipPath.url);
-    delete(style->mask.url);
+    free(style->clipPath.url);
+    free(style->mask.url);
 
     if (style->fill.paint.gradient) delete(style->fill.paint.gradient);
     if (style->stroke.paint.gradient) delete(style->stroke.paint.gradient);
-    delete(style->fill.paint.url);
-    delete(style->stroke.paint.url);
+    free(style->fill.paint.url);
+    free(style->stroke.paint.url);
     style->stroke.dash.array.reset();
     free(style);
 }
@@ -2683,12 +2685,12 @@ static void _freeNode(SvgNode* node)
     }
     node->child.reset();
 
-    delete node->id;
+    free(node->id);
     free(node->transform);
     _freeNodeStyle(node->style);
     switch (node->type) {
          case SvgNodeType::Path: {
-             delete node->node.path.path;
+             free(node->node.path.path);
              break;
          }
          case SvgNodeType::Polygon: {
@@ -2713,7 +2715,7 @@ static void _freeNode(SvgNode* node)
              break;
          }
          case SvgNodeType::Image: {
-             delete node->node.image.href;
+             free(node->node.image.href);
              break;
          }
          default: {
index 472a813..b627538 100644 (file)
@@ -201,12 +201,12 @@ struct SvgLineNode
 struct SvgImageNode
 {
     float x, y, w, h;
-    string *href;
+    char* href;
 };
 
 struct SvgPathNode
 {
-    string* path;
+    char* path;
 };
 
 struct SvgPolygonNode
@@ -248,7 +248,7 @@ struct SvgRadialGradient
 
 struct SvgComposite
 {
-    string *url;
+    char *url;
     SvgNode* node;
     bool applying;              //flag for checking circular dependency.
 };
@@ -263,7 +263,7 @@ struct SvgColor
 struct SvgPaint
 {
     SvgStyleGradient* gradient;
-    string *url;
+    char *url;
     SvgColor color;
     bool none;
     bool curColor;
@@ -277,8 +277,8 @@ struct SvgDash
 struct SvgStyleGradient
 {
     SvgGradientType type = SvgGradientType::Linear;
-    string *id = nullptr;
-    string *ref = nullptr;
+    char *id = nullptr;
+    char *ref = nullptr;
     FillSpread spread = FillSpread::Pad;
     SvgRadialGradient* radial = nullptr;
     SvgLinearGradient* linear = nullptr;
@@ -292,8 +292,8 @@ struct SvgStyleGradient
         free(transform);
         free(radial);
         free(linear);
-        delete(ref);
-        delete(id);
+        free(ref);
+        free(id);
     }
 };
 
@@ -336,7 +336,7 @@ struct SvgNode
     SvgNodeType type;
     SvgNode* parent;
     Array<SvgNode*> child;
-    string *id;
+    char *id;
     SvgStyleProperty *style;
     Matrix* transform;
     union {
@@ -379,7 +379,7 @@ struct SvgParser
 struct SvgNodeIdPair
 {
     SvgNode* node;
-    string *id;
+    char *id;
 };
 
 struct SvgLoaderData
index fed40c6..7363a71 100644 (file)
@@ -376,7 +376,7 @@ static bool _appendShape(SvgNode* node, Shape* shape, float vx, float vy, float
     switch (node->type) {
         case SvgNodeType::Path: {
             if (node->node.path.path) {
-                if (svgPathToTvgPath(node->node.path.path->c_str(), cmds, pts)) {
+                if (svgPathToTvgPath(node->node.path.path, cmds, pts)) {
                     shape->appendPath(cmds.data, cmds.count, pts.data, pts.count);
                 }
             }
@@ -501,7 +501,7 @@ static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, float vx, float vy,
     if (!node->node.image.href) return nullptr;
     auto picture = Picture::gen();
 
-    const char* href = (*node->node.image.href).c_str();
+    const char* href = node->node.image.href;
     if (!strncmp(href, "data:", sizeof("data:") - 1)) {
         href += sizeof("data:") - 1;
         const char* mimetype;
index f3bcc7d..2e3d592 100644 (file)
@@ -348,7 +348,7 @@ bool simpleXmlParseAttributes(const char* buf, unsigned bufLength, simpleXMLAttr
 
         if (!func((void*)data, tmpBuf, tval)) {
             if (!_isIgnoreUnsupportedLogAttributes(tmpBuf, tval)) {
-                TVGLOG("SVG", "Unsupported attributes used [Elements type: %s][Id : %s][Attribute: %s][Value: %s]", simpleXmlNodeTypeToString(((SvgLoaderData*)data)->svgParse->node->type), ((SvgLoaderData*)data)->svgParse->node->id ? ((SvgLoaderData*)data)->svgParse->node->id->c_str() : "NO_ID", tmpBuf, tval ? tval : "NONE");
+                TVGLOG("SVG", "Unsupported attributes used [Elements type: %s][Id : %s][Attribute: %s][Value: %s]", simpleXmlNodeTypeToString(((SvgLoaderData*)data)->svgParse->node->type), ((SvgLoaderData*)data)->svgParse->node->id ? ((SvgLoaderData*)data)->svgParse->node->id : "NO_ID", tmpBuf, tval ? tval : "NONE");
             }
         }
     }
@@ -496,7 +496,7 @@ bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, cons
 
             if (!func((void*)data, key, val)) {
                 if (!_isIgnoreUnsupportedLogAttributes(key, val)) {
-                    TVGLOG("SVG", "Unsupported attributes used [Elements type: %s][Id : %s][Attribute: %s][Value: %s]", simpleXmlNodeTypeToString(((SvgLoaderData*)data)->svgParse->node->type), ((SvgLoaderData*)data)->svgParse->node->id ? ((SvgLoaderData*)data)->svgParse->node->id->c_str() : "NO_ID", key, val ? val : "NONE");
+                    TVGLOG("SVG", "Unsupported attributes used [Elements type: %s][Id : %s][Attribute: %s][Value: %s]", simpleXmlNodeTypeToString(((SvgLoaderData*)data)->svgParse->node->type), ((SvgLoaderData*)data)->svgParse->node->id ? ((SvgLoaderData*)data)->svgParse->node->id : "NO_ID", key, val ? val : "NONE");
                 }
             }
         }