2022-10-03 16:25:42 +00:00
|
|
|
#include "useelement.h"
|
|
|
|
#include "parser.h"
|
|
|
|
#include "layoutcontext.h"
|
|
|
|
|
|
|
|
#include "gelement.h"
|
|
|
|
#include "svgelement.h"
|
|
|
|
|
|
|
|
namespace lunasvg {
|
|
|
|
|
|
|
|
UseElement::UseElement()
|
2022-10-16 10:31:43 +00:00
|
|
|
: GraphicsElement(ElementID::Use)
|
2022-10-03 16:25:42 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Length UseElement::x() const
|
|
|
|
{
|
2022-10-16 10:31:43 +00:00
|
|
|
auto& value = get(PropertyID::X);
|
2022-10-03 16:25:42 +00:00
|
|
|
return Parser::parseLength(value, AllowNegativeLengths, Length::Zero);
|
|
|
|
}
|
|
|
|
|
|
|
|
Length UseElement::y() const
|
|
|
|
{
|
2022-10-16 10:31:43 +00:00
|
|
|
auto& value = get(PropertyID::Y);
|
2022-10-03 16:25:42 +00:00
|
|
|
return Parser::parseLength(value, AllowNegativeLengths, Length::Zero);
|
|
|
|
}
|
|
|
|
|
|
|
|
Length UseElement::width() const
|
|
|
|
{
|
2022-10-16 10:31:43 +00:00
|
|
|
auto& value = get(PropertyID::Width);
|
2022-10-03 16:25:42 +00:00
|
|
|
return Parser::parseLength(value, ForbidNegativeLengths, Length::HundredPercent);
|
|
|
|
}
|
|
|
|
|
|
|
|
Length UseElement::height() const
|
|
|
|
{
|
2022-10-16 10:31:43 +00:00
|
|
|
auto& value = get(PropertyID::Height);
|
2022-10-03 16:25:42 +00:00
|
|
|
return Parser::parseLength(value, ForbidNegativeLengths, Length::HundredPercent);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string UseElement::href() const
|
|
|
|
{
|
2022-10-16 10:31:43 +00:00
|
|
|
auto& value = get(PropertyID::Href);
|
2022-10-03 16:25:42 +00:00
|
|
|
return Parser::parseHref(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void UseElement::transferWidthAndHeight(Element* element) const
|
|
|
|
{
|
2022-10-16 10:31:43 +00:00
|
|
|
auto& width = get(PropertyID::Width);
|
|
|
|
auto& height = get(PropertyID::Height);
|
2022-10-03 16:25:42 +00:00
|
|
|
|
2022-10-16 10:31:43 +00:00
|
|
|
element->set(PropertyID::Width, width, 0x0);
|
|
|
|
element->set(PropertyID::Height, height, 0x0);
|
2022-10-03 16:25:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void UseElement::layout(LayoutContext* context, LayoutContainer* current) const
|
|
|
|
{
|
|
|
|
if(isDisplayNone())
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto ref = context->getElementById(href());
|
|
|
|
if(ref == nullptr || context->hasReference(ref) || (current->id == LayoutId::ClipPath && !ref->isGeometry()))
|
|
|
|
return;
|
|
|
|
|
|
|
|
LayoutBreaker layoutBreaker(context, ref);
|
|
|
|
auto group = std::make_unique<GElement>();
|
|
|
|
group->parent = parent;
|
|
|
|
group->properties = properties;
|
|
|
|
|
|
|
|
LengthContext lengthContext(this);
|
|
|
|
auto _x = lengthContext.valueForLength(x(), LengthMode::Width);
|
|
|
|
auto _y = lengthContext.valueForLength(y(), LengthMode::Height);
|
|
|
|
|
2022-10-16 10:31:43 +00:00
|
|
|
auto transform = get(PropertyID::Transform);
|
2022-10-03 16:25:42 +00:00
|
|
|
transform += "translate(";
|
|
|
|
transform += std::to_string(_x);
|
|
|
|
transform += ' ';
|
|
|
|
transform += std::to_string(_y);
|
|
|
|
transform += ')';
|
2022-10-16 10:31:43 +00:00
|
|
|
group->set(PropertyID::Transform, transform, 0x10);
|
2022-10-03 16:25:42 +00:00
|
|
|
|
2023-07-29 10:37:05 +00:00
|
|
|
if(ref->id == ElementID::Svg || ref->id == ElementID::Symbol) {
|
2022-10-03 16:25:42 +00:00
|
|
|
auto element = ref->cloneElement<SVGElement>();
|
|
|
|
transferWidthAndHeight(element.get());
|
|
|
|
group->addChild(std::move(element));
|
2023-07-29 10:37:05 +00:00
|
|
|
} else {
|
2022-10-03 16:25:42 +00:00
|
|
|
group->addChild(ref->clone());
|
|
|
|
}
|
|
|
|
|
|
|
|
group->layout(context, current);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<Node> UseElement::clone() const
|
|
|
|
{
|
|
|
|
return cloneElement<UseElement>();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace lunasvg
|