Skip to content

Commit

Permalink
Support simple DOM manipulation
Browse files Browse the repository at this point in the history
  • Loading branch information
sammycage committed Jan 7, 2024
1 parent f3dc82b commit 760e7e8
Show file tree
Hide file tree
Showing 12 changed files with 378 additions and 272 deletions.
76 changes: 73 additions & 3 deletions include/lunasvg.h
Expand Up @@ -23,9 +23,10 @@
#ifndef LUNASVG_H
#define LUNASVG_H

#include <cstdint>
#include <memory>
#include <string>
#include <cstdint>
#include <map>

#if defined(_MSC_VER) && defined(LUNASVG_SHARED)
#ifdef LUNASVG_EXPORT
Expand Down Expand Up @@ -125,7 +126,66 @@ class LUNASVG_API Bitmap {
std::shared_ptr<Impl> m_impl;
};

class Element;

class LUNASVG_API DomElement {
public:
/**
* @brief DomElement
*/
DomElement() = default;

/**
* @brief DomElement
* @param element
*/
DomElement(Element* element);

/**
* @brief setAttribute
* @param name
* @param value
*/
void setAttribute(const std::string& name, const std::string& value);

/**
* @brief getAttribute
* @param name
* @return
*/
std::string getAttribute(const std::string& name) const;

/**
* @brief removeAttribute
* @param name
*/
void removeAttribute(const std::string& name);

/**
* @brief hasAttribute
* @param name
* @return
*/
bool hasAttribute(const std::string& name) const;

/**
* @brief isNull
* @return
*/
bool isNull() const { return m_element == nullptr; }

/**
* @brief get
* @return
*/
Element* get() { return m_element; }

private:
Element* m_element = nullptr;
};

class LayoutSymbol;
class SVGElement;

class LUNASVG_API Document {
public:
Expand Down Expand Up @@ -204,13 +264,23 @@ class LUNASVG_API Document {
*/
Bitmap renderToBitmap(std::uint32_t width = 0, std::uint32_t height = 0, std::uint32_t backgroundColor = 0x00000000) const;

/**
* @brief updateLayout
*/
void updateLayout();

Document(Document&&);
~Document();

DomElement getElementById(const std::string& id) const;
DomElement rootElement() const;

private:
Document();

std::unique_ptr<LayoutSymbol> root;
bool parse(const char* data, size_t size);
std::unique_ptr<SVGElement> m_rootElement;
std::map<std::string, Element*> m_idCache;
std::unique_ptr<LayoutSymbol> m_rootBox;
};

} //namespace lunasvg
Expand Down
71 changes: 66 additions & 5 deletions source/element.cpp
@@ -1,5 +1,16 @@
#include "element.h"
#include "clippathelement.h"
#include "defselement.h"
#include "gelement.h"
#include "geometryelement.h"
#include "markerelement.h"
#include "maskelement.h"
#include "paintelement.h"
#include "stopelement.h"
#include "svgelement.h"
#include "symbolelement.h"
#include "useelement.h"
#include "styleelement.h"
#include "parser.h"

namespace lunasvg {
Expand All @@ -20,6 +31,58 @@ Element::Element(ElementID id)
{
}

std::unique_ptr<Element> Element::create(ElementID id)
{
switch(id) {
case ElementID::Svg:
return makeUnique<SVGElement>();
case ElementID::Path:
return makeUnique<PathElement>();
case ElementID::G:
return makeUnique<GElement>();
case ElementID::Rect:
return makeUnique<RectElement>();
case ElementID::Circle:
return makeUnique<CircleElement>();
case ElementID::Ellipse:
return makeUnique<EllipseElement>();
case ElementID::Line:
return makeUnique<LineElement>();
case ElementID::Defs:
return makeUnique<DefsElement>();
case ElementID::Polygon:
return makeUnique<PolygonElement>();
case ElementID::Polyline:
return makeUnique<PolylineElement>();
case ElementID::Stop:
return makeUnique<StopElement>();
case ElementID::LinearGradient:
return makeUnique<LinearGradientElement>();
case ElementID::RadialGradient:
return makeUnique<RadialGradientElement>();
case ElementID::Symbol:
return makeUnique<SymbolElement>();
case ElementID::Use:
return makeUnique<UseElement>();
case ElementID::Pattern:
return makeUnique<PatternElement>();
case ElementID::Mask:
return makeUnique<MaskElement>();
case ElementID::ClipPath:
return makeUnique<ClipPathElement>();
case ElementID::SolidColor:
return makeUnique<SolidColorElement>();
case ElementID::Marker:
return makeUnique<MarkerElement>();
case ElementID::Style:
return makeUnique<StyleElement>();
default:
break;
}

return nullptr;
}

void Element::set(PropertyID id, const std::string& value, int specificity)
{
for(auto& property : properties) {
Expand Down Expand Up @@ -79,7 +142,6 @@ Element* Element::previousElement() const
{
if(parent == nullptr)
return nullptr;

Element* element = nullptr;
auto it = parent->children.begin();
auto end = parent->children.end();
Expand All @@ -99,7 +161,6 @@ Element* Element::nextElement() const
{
if(parent == nullptr)
return nullptr;

Element* element = nullptr;
auto it = parent->children.rbegin();
auto end = parent->children.rend();
Expand Down Expand Up @@ -154,19 +215,19 @@ Rect Element::currentViewport() const
return parent->currentViewport();
}

void Element::build(const TreeBuilder* builder)
void Element::build(const Document* document)
{
for(auto& child : children) {
if(child->isText())
continue;
auto element = static_cast<Element*>(child.get());
element->build(builder);
element->build(document);
}
}

std::unique_ptr<Node> Element::clone() const
{
auto element = TreeBuilder::createElement(id);
auto element = Element::create(id);
element->properties = properties;
for(auto& child : children)
element->addChild(child->clone());
Expand Down
12 changes: 8 additions & 4 deletions source/element.h
Expand Up @@ -5,6 +5,7 @@
#include <list>

#include "property.h"
#include "lunasvg.h"

namespace lunasvg {

Expand Down Expand Up @@ -107,6 +108,10 @@ enum class PropertyID {
Y2
};

ElementID elementid(const std::string& name);
PropertyID csspropertyid(const std::string& name);
PropertyID propertyid(const std::string& name);

struct Property {
int specificity;
PropertyID id;
Expand Down Expand Up @@ -153,11 +158,9 @@ class TextNode : public Node {

using NodeList = std::list<std::unique_ptr<Node>>;

class TreeBuilder;

class Element : public Node {
public:
Element(ElementID id);
static std::unique_ptr<Element> create(ElementID id);

void set(PropertyID id, const std::string& value, int specificity);
const std::string& get(PropertyID id) const;
Expand All @@ -170,7 +173,7 @@ class Element : public Node {
void layoutChildren(LayoutContext* context, LayoutContainer* current) const;
Rect currentViewport() const;

virtual void build(const TreeBuilder* builder);
virtual void build(const Document* document);

template<typename T>
void transverse(T callback) {
Expand All @@ -191,6 +194,7 @@ class Element : public Node {
std::unique_ptr<Node> clone() const final;

public:
Element(ElementID id);
ElementID id;
NodeList children;
PropertyList properties;
Expand Down
9 changes: 6 additions & 3 deletions source/layoutcontext.cpp
Expand Up @@ -467,14 +467,17 @@ void RenderState::endGroup(RenderState& state, const BlendInfo& info)
state.canvas->blend(canvas.get(), BlendMode::Src_Over, m_mode == RenderMode::Display ? info.opacity : 1.0);
}

LayoutContext::LayoutContext(const TreeBuilder* builder, LayoutSymbol* root)
: m_builder(builder), m_root(root)
LayoutContext::LayoutContext(const Document* document, LayoutSymbol* root)
: m_document(document), m_root(root)
{
}

Element* LayoutContext::getElementById(const std::string& id) const
{
return m_builder->getElementById(id);
auto element = m_document->getElementById(id);
if(element.isNull())
return nullptr;
return element.get();
}

LayoutObject* LayoutContext::getResourcesById(const std::string& id) const
Expand Down
6 changes: 3 additions & 3 deletions source/layoutcontext.h
Expand Up @@ -325,13 +325,13 @@ class RenderState {
RenderMode m_mode;
};

class TreeBuilder;
class Document;
class StyledElement;
class GeometryElement;

class LayoutContext {
public:
LayoutContext(const TreeBuilder* builder, LayoutSymbol* root);
LayoutContext(const Document* document, LayoutSymbol* root);

Element* getElementById(const std::string& id) const;
LayoutObject* getResourcesById(const std::string& id) const;
Expand All @@ -351,7 +351,7 @@ class LayoutContext {
bool hasReference(const Element* element) const;

private:
const TreeBuilder* m_builder;
const Document* m_document;
LayoutSymbol* m_root;
std::map<std::string, LayoutObject*> m_resourcesCache;
std::set<const Element*> m_references;
Expand Down

0 comments on commit 760e7e8

Please sign in to comment.