diff --git a/source/graphics.cpp b/source/graphics.cpp index 27a7514..8c3b1c8 100644 --- a/source/graphics.cpp +++ b/source/graphics.cpp @@ -277,8 +277,14 @@ void Path::addRect(const Rect& rect) void Path::reset() { - plutovg_path_destroy(m_data); - m_data = nullptr; + if(m_data == nullptr) + return; + if(isUnique()) { + plutovg_path_reset(m_data); + } else { + plutovg_path_destroy(m_data); + m_data = nullptr; + } } Rect Path::boundingRect() const @@ -301,7 +307,7 @@ bool Path::isUnique() const { if(m_data) return plutovg_path_get_reference_count(m_data) == 1; - return true; + return false; } bool Path::parse(const char* data, size_t length) diff --git a/source/graphics.h b/source/graphics.h index d981379..737631f 100644 --- a/source/graphics.h +++ b/source/graphics.h @@ -303,6 +303,7 @@ class Transform { float yScale() const; const plutovg_matrix_t& matrix() const { return m_matrix; } + plutovg_matrix_t& matrix() { return m_matrix; } bool parse(const char* data, size_t length); @@ -357,11 +358,10 @@ class Path { bool isEmpty() const; bool isUnique() const; bool isNull() const { return m_data == nullptr; } + plutovg_path_t* data() const { return m_data; } bool parse(const char* data, size_t length); - plutovg_path_t* data() const { return m_data; } - private: plutovg_path_t* release(); plutovg_path_t* ensure(); diff --git a/source/svgelement.cpp b/source/svgelement.cpp index 20a08e0..96a208b 100644 --- a/source/svgelement.cpp +++ b/source/svgelement.cpp @@ -793,7 +793,6 @@ std::unique_ptr SVGUseElement::cloneTargetElement(SVGElement* target SVGImageElement::SVGImageElement(Document* document) : SVGGraphicsElement(document, ElementID::Image) - , SVGURIReference(this) , m_x(PropertyID::X, LengthDirection::Horizontal, LengthNegativeMode::Allow, 0.f, LengthUnits::None) , m_y(PropertyID::Y, LengthDirection::Vertical, LengthNegativeMode::Allow, 0.f, LengthUnits::None) , m_width(PropertyID::Width, LengthDirection::Horizontal, LengthNegativeMode::Forbid, 100.f, LengthUnits::Percent) @@ -858,9 +857,11 @@ static Bitmap loadImageResource(const std::string& href) void SVGImageElement::parseAttribute(PropertyID id, const std::string& value) { - if(id == PropertyID::Href) + if(id == PropertyID::Href) { m_image = loadImageResource(value); - SVGGraphicsElement::parseAttribute(id, value); + } else { + SVGGraphicsElement::parseAttribute(id, value); + } } SVGSymbolElement::SVGSymbolElement(Document* document) diff --git a/source/svgelement.h b/source/svgelement.h index 394db6a..5707596 100644 --- a/source/svgelement.h +++ b/source/svgelement.h @@ -373,7 +373,7 @@ class SVGUseElement final : public SVGGraphicsElement, public SVGURIReference { SVGLength m_height; }; -class SVGImageElement final : public SVGGraphicsElement, public SVGURIReference { +class SVGImageElement final : public SVGGraphicsElement { public: SVGImageElement(Document* document); @@ -453,6 +453,7 @@ class SVGClipPathElement final : public SVGGraphicsElement { void applyClipMask(SVGRenderState& state) const; void applyClipPath(SVGRenderState& state) const; + bool requiresMasking() const; private: @@ -473,6 +474,7 @@ class SVGMaskElement final : public SVGElement { Rect maskRect(const SVGElement* element) const; Rect maskBoundingBox(const SVGElement* element) const; void applyMask(SVGRenderState& state) const; + void layoutElement(const SVGLayoutState& state) final; private: diff --git a/source/svggeometryelement.cpp b/source/svggeometryelement.cpp index caa592e..bc59e61 100644 --- a/source/svggeometryelement.cpp +++ b/source/svggeometryelement.cpp @@ -272,7 +272,7 @@ Rect SVGCircleElement::updateShape(Path& path) { LengthContext lengthContext(this); auto r = lengthContext.valueForLength(m_r); - if(r <= 0.f || r <= 0.f) { + if(r <= 0.f) { return Rect::Empty; } diff --git a/source/svggeometryelement.h b/source/svggeometryelement.h index 101cfd0..b02d8b3 100644 --- a/source/svggeometryelement.h +++ b/source/svggeometryelement.h @@ -42,6 +42,7 @@ class SVGGeometryElement : public SVGGraphicsElement { FillRule clip_rule() const { return m_clip_rule; } virtual Rect updateShape(Path& path) = 0; + void updateMarkerPositions(SVGMarkerPositionList& positions, const SVGLayoutState& state); void render(SVGRenderState& state) const override; diff --git a/source/svgtextelement.cpp b/source/svgtextelement.cpp index b6da9ba..315bba8 100644 --- a/source/svgtextelement.cpp +++ b/source/svgtextelement.cpp @@ -152,7 +152,7 @@ void SVGTextFragmentsBuilder::build(const SVGTextElement* textElement) auto recordTextFragment = [&](auto startOffset, auto endOffset) { auto text = wholeText.substr(startOffset, endOffset - startOffset); fragment.offset = startOffset; - fragment.length = endOffset - startOffset; + fragment.length = text.length(); fragment.width = element->font().measureText(text); m_fragments.push_back(fragment); m_x += fragment.width; @@ -265,7 +265,7 @@ void SVGTextFragmentsBuilder::handleText(const SVGTextNode* node) void SVGTextFragmentsBuilder::handleElement(const SVGTextPositioningElement* element) { - auto itemIndex = m_textPositions.size(); + const auto itemIndex = m_textPositions.size(); m_textPositions.emplace_back(element, m_text.length(), m_text.length()); for(const auto& child : element->children()) { if(child->isTextNode()) { @@ -394,13 +394,12 @@ SVGTextElement::SVGTextElement(Document* document) void SVGTextElement::layout(SVGLayoutState& state) { SVGTextPositioningElement::layout(state); - SVGTextFragmentsBuilder fragmentsBuilder(m_text, m_fragments); - fragmentsBuilder.build(this); + SVGTextFragmentsBuilder(m_text, m_fragments).build(this); } void SVGTextElement::render(SVGRenderState& state) const { - if(m_text.empty() || isVisibilityHidden() || isDisplayNone()) + if(m_fragments.empty() || isVisibilityHidden() || isDisplayNone()) return; SVGBlendInfo blendInfo(this); SVGRenderState newState(this, state, localTransform());