/*
10 * Copyright (C) 2022 Authors
11 * Released under GNU GPL v2+, read the file
'COPYING' for more information.
18#include <boost/range/adaptor/reversed.hpp>
35 for (
auto &path : pathv) {
60 return is<SPImage>(
item) || is<SPUse>(
item);
66struct PathvectorItem {
68 : pathv(
std::move(path))
80 if (is<SPGroup>(
item)) {
82 if (
auto child_item = cast<SPItem>(&
child)) {
86 }
else if (
auto img = cast<SPImage>(
item)) {
87 if (
auto clip = img->getClipPathVector(
root)) {
93 }
else if (
auto shape = cast<SPShape>(
item)) {
94 if (
auto curve = shape->curve()) {
97 }
else if (
auto text = cast<SPText>(
item)) {
98 result.emplace_back(text->getNormalizedBpath() * transform,
root,
item);
99 }
else if (
auto use = cast<SPUse>(
item)) {
100 auto clip = use->getClipPathVector(
root);
101 if (
clip && is<SPImage>(use->get_original())) {
104 }
else if (use->child) {
117 std::sort(
items.begin(),
items.end(), [] (
auto a,
auto b) {
118 return sp_object_compare_position_bool(b, a);
132 std::stable_partition(augmented.begin(), augmented.end(), [] (
auto &pvi) {
133 return is<SPImage>(pvi.item) || is<SPUse>(pvi.item);
140 for (
auto &pvi : augmented) {
141 bounds |= pvi.pathv.boundsExact();
142 for (
auto &path : pvi.pathv) {
151 constexpr double expansion = 10.0;
160 auto gen = std::default_random_engine(std::random_device()());
161 auto ranf = [&] {
return std::uniform_real_distribution()(gen); };
162 auto randpt = [&] {
return Geom::Point(ranf(), ranf()); };
164 for (
auto &piece : pieces) {
166 if (
auto rect = piece.boundsExact()) {
177 for (
auto it = piece.begin(); it != piece.end(); ) {
179 it = piece.erase(it);
192 std::unordered_map<PathvectorItem*, int> hits;
194 auto rect = piece.boundsExact();
198 for (
auto &pvi : augmented) {
199 auto fill_rule = pvi.item->style->fill_rule.computed;
200 auto winding = pvi.pathv.winding(pt);
211 for (
int total_hits = 0, patience = 1000; total_hits < 20 && patience > 0; patience--) {
213 auto pt = rect->min() + randpt() * rect->dimensions();
214 if (piece.winding(pt)) {
221 PathvectorItem *found =
nullptr;
224 for (
auto &[a, h] : hits) {
232 auto root = found ? found->root :
nullptr;
233 auto item = found ? found->item :
nullptr;
235 result.emplace_back(std::make_shared<SubItem>(std::move(piece),
root,
item, style));
247 std::sort(
items.begin(),
items.end(), [] (
auto a,
auto b) {
248 return sp_object_compare_position_bool(b, a);
259 for (
auto &[pathv,
root, subitem] : extracted) {
261 for (
auto &it : pathv) {
273 auto fillrule = subitem->style->fill_rule.computed;
279 if (unioned.empty()) {
281 unioned = std::move(pathv);
288 result.emplace_back(std::make_shared<SubItem>(std::move(uniq),
root, subitem, subitem->style));
FillRule to_livarot(SPWindRule fill_rule)
3x3 matrix representing an affine transformation.
C right() const
Return rightmost coordinate of the rectangle (+X is to the right).
C top() const
Return top coordinate of the rectangle (+Y is downwards).
void expandBy(C amount)
Expand the rectangle in both directions by the specified amount.
C left() const
Return leftmost coordinate of the rectangle (+X is to the right).
C bottom() const
Return bottom coordinate of the rectangle (+Y is downwards).
Axis-aligned rectangle that can be empty.
void push_back(Path const &path)
Append a path at the end.
int winding(Point const &p) const
Determine the winding number at the specified point.
Sequence of contiguous curves, aka spline.
Two-dimensional point that doubles as a vector.
When an item is broken, each broken part is represented by the SubItem class.
SubItem & operator+=(SubItem const &other)
Union operator, merges two subitems when requested by the user The left hand side will retain priorit...
static WorkItems build_flatten(std::vector< SPItem * > &&items)
Take a list of items and flatten into a list of SubItems.
static WorkItems build_mosaic(std::vector< SPItem * > &&items)
Take a list of items and fracture into a list of SubItems ready for use inside the booleans interacti...
static bool _get_is_image(SPItem const *item)
Test if this sub item is a special image type.
bool contains(Geom::Point const &pt) const
Return true if this subitem contains the give point.
Base class for visual SVG elements.
Geom::Affine i2dt_affine() const
Returns the transformation from item to desktop coords.
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
Helper class to stream background task notifications as a series of messages.
static Geom::PathVector clean_pathvector(Geom::PathVector &&pathv)
std::vector< PathvectorItem > PathvectorItems
static void extract_pathvectors_recursive(SPItem *root, SPItem *item, PathvectorItems &result, Geom::Affine const &transform)
std::vector< WorkItem > WorkItems
bool is_path_empty(Geom::Path const &path)
Check for an empty path.
static T clip(T const &v, T const &a, T const &b)
void flatten(Geom::PathVector &pathv, FillRule fill_rule)
Geom::PathVector sp_pathvector_boolop(Geom::PathVector const &pathva, Geom::PathVector const &pathvb, BooleanOp bop, FillRule fra, FillRule frb)
Perform a boolean operation on two pathvectors.
Geom::PathVector flattened(Geom::PathVector const &pathv, FillRule fill_rule)
Flatten a pathvector according to the given fill rule.
std::vector< Geom::PathVector > pathvector_cut(Geom::PathVector const &pathv, Geom::PathVector const &lines)
Cut a pathvector along a collection of lines into several smaller pathvectors.
SVG <image> implementation.
SPStyle - a style object for SPItem objects.
int winding(PathVector ps, Point p)