decode method

Implementation

Future<RenderBoxModel> decode() async {
  final resp = await imageLoader;

  final code = convert.utf8.decode(resp.bytes);

  final gumbo = parseSVGResult(code);
  final ptr = gumbo.ptr;

  Pointer<NativeGumboNode> root = nullptr;
  visitSVGTree(ptr.ref.root, (node, _) {
    final type = node.ref.type;
    if (type == GumboNodeType.GUMBO_NODE_ELEMENT) {
      final element = node.ref.v.element;
      if (element.tag_namespace == GumboNamespaceEnum.GUMBO_NAMESPACE_SVG &&
          element.tag == GumboTag.SVG) {
        // svg tag
        root = node;
        return false;
      }
    }
  });

  if (root == nullptr) {
    // IMPROVE: throw a more specific error
    throw Error();
  }

  final rootRenderObject = visitSVGTree(root, (node, parent) {
    final type = node.ref.type;
    if (type == GumboNodeType.GUMBO_NODE_ELEMENT) {
      final element = node.ref.v.element;
      final tagName = element.original_tag.data
          .toDartString(length: element.original_tag.length)
          .toUpperCase();
      final renderBox = getSVGRenderBox(tagName);

      final attributes = element.attributes;
      for (int i = 0; i < attributes.length; i++) {
        final attr = attributes.data[i] as Pointer<NativeGumboAttribute>;
        final name = attr.ref.name.toDartString();
        final value = attr.ref.value.toDartString();
        setAttribute(tagName, renderBox, name, value);
      }

      if (parent != null) {
        assert(parent is RenderSVGContainer);
        parent.insert(renderBox);
        // We need to build renderStyle tree manually.
        renderBox.renderStyle.parent = parent.renderStyle;
      }

      return renderBox;
    }
    return false;
  });

  freeSVGResult(gumbo);

  return rootRenderObject as RenderBoxModel;
}