23#include <glibmm/i18n.h>
41#define noOFFSET_VERBOSE
114 if (this->
getRepr()->attribute(
"inkscape:radius")) {
126 if (this->
getRepr()->attribute(
"inkscape:original")) {
136 if (this->
getRepr()->attribute(
"xlink:href")) {
142 size_t lA = strlen(oldA);
143 char *nA=(
char*)malloc((1+lA+1)*
sizeof(char));
145 memcpy(nA+1,oldA,lA*
sizeof(
char));
162 if ((flags & SP_OBJECT_WRITE_BUILD) && !
repr) {
166 if (flags & SP_OBJECT_WRITE_EXT) {
225 if (value ==
nullptr) {
253 if (fabs (this->
rad) < 0.01) {
254 this->
rad = (this->
rad < 0) ? -0.01 : 0.01;
267 if ( value ==
nullptr ) {
287 g_warning(
"%s", e.what());
308 (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG |
309 SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
321 return _(
"Linked Offset");
323 return _(
"Dynamic Offset");
333 return g_strdup_printf(_(
"%s by %f pt"), (this->
rad >= 0) ?
334 _(
"outset") : _(
"inset"), fabs (this->
rad));
343 g_print (
"rad=%g\n",
offset->rad);
347 if ( fabs(this->
rad) < 0.01 ) {
364 if (fabs (this->
rad) < 0.01) {
365 this->
rad = (this->
rad < 0) ? -0.01 : 0.01;
388 o_width = -this->
rad;
402 res->
Fill (theShape, 0);
411 gdouble
size = L2(
bbox->dimensions());
454 o_width = -this->
rad;
460 orig->ConvertWithBackData (0.5);
464 orig->ConvertWithBackData (0.5*o_width);
467 orig->Fill (theShape, 0);
478 char *holes=(
char*)malloc(nbPart*
sizeof(
char));
488 for (
int i=0;i<nbPart;i++) {
489 double partSurf=parts[i]->
Surface();
496 double measure=((bR-bL)+(bB-bT))*0.5;
497 if ( measure < 10.0 ) {
498 parts[i]->
Convert(0.02*measure);
502 if ( partSurf < 0 ) {
505 parts[i]->
Fill(oneCleanPart,0);
513 if ( typicalSize < 0.05 ) {
519 if ( typicalSize > 1.0 ) {
527 double nPartSurf=parts[i]->
Surface();
529 if ( nPartSurf >= 0 ) {
542 parts[i]->
Fill(oneCleanPart,0,
false,
true,
true);
551 if ( typicalSize < 0.05 ) {
557 if ( typicalSize > 1.0 ) {
564 double nPartSurf=parts[i]->
Surface();
566 if ( nPartSurf >= 0 ) {
587 for (
int i=0;i<nbPart;i++) {
592 parts[i]->
Fill(theShape,i,
true,
true,
true);
594 parts[i]->
Fill(theShape,i,
true,
true,
false);
602 for (
int i=0;i<nbPart;i++) {
607 }
else if ( nbPart == 1 ) {
608 orig->Copy(parts[0]);
610 for (
int i=0;i<nbPart;i++) {
644 if (
orig->descr_cmd.size() <= 1) {
648 res_pv =
orig->MakePathVector();
686 double ab_s =
dot(A, rot90(B));
687 double ab_c =
dot(A, B);
688 double ca_s =
dot(C, rot90(A));
689 double ca_c =
dot(C, A);
691 double ab_a = acos (ab_c);
702 ab_a = 2 * M_PI - ab_a;
705 double ca_a = acos (ca_c);
716 ca_a = 2 * M_PI - ca_a;
719 double lim = 2 * M_PI - ca_a;
739 if (
offset ==
nullptr ||
offset->originalPath ==
nullptr || ((
Path *)
offset->originalPath)->descr_cmd.size() <= 1) {
757 ((
Path *)
offset->originalPath)->Convert (1.0);
758 ((
Path *)
offset->originalPath)->Fill (theShape, 0);
767 double ptDist = -1.0;
769 double arDist = -1.0;
779 double ndist = sqrt (
dot(nxpx,nxpx));
781 if (ptSet ==
false || fabs (ndist) < fabs (ptDist))
786 double nlen = sqrt (
dot(nx , nx));
798 nlen = sqrt (
dot(prx, prx));
801 nlen = sqrt (
dot(nex , nex));
831 cb = theRes->
NextAt (i, cb);
834 while (cb >= 0 && pb >= 0 && pb != fb);
845 double len = sqrt (
dot(nx,nx));
850 double ab =
dot(nx,pxsx);
852 if (ab > 0 && ab <
len *
len)
855 double ndist = (cross(nx, pxsx)) /
len;
857 if (arSet ==
false || fabs (ndist) < fabs (arDist))
868 if (arSet ==
false) {
872 if (ptSet ==
false) {
876 if (fabs (ptDist) < fabs (arDist)) {
913 if (
curve ==
nullptr)
919 if (
curve ==
nullptr)
923 if (
curve->is_empty())
934 finalPath->
Fill (theShape, 0);
949 if ( to ==
nullptr ) {
953 offset->sourceObject = to;
963 if (
offset->sourceObject ==
nullptr ) {
967 offset->_modified_connection.disconnect();
968 offset->_delete_connection.disconnect();
969 offset->_transformed_connection.disconnect();
971 offset->sourceRepr =
nullptr;
972 offset->sourceObject =
nullptr;
988 offset->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1013 offset_move = offset_move.
inverse() * m;
1014 advertized_move = m;
1016 offset_move = offset_move.
inverse();
1019 g_assert_not_reached();
1040 if (
offset->sourceHref ) {
1041 g_free(
offset->sourceHref);
1044 offset->sourceHref =
nullptr;
1045 offset->sourceRef->detach();
1055 offset->sourceDirty=
true;
1057 if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG)) {
1058 offset->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1065 if (
offset ==
nullptr ) {
1069 offset->sourceDirty=
false;
1075 if (
item ==
nullptr) {
1081 if (
auto shape = cast<SPShape>(
item)) {
1082 if (!shape->curve()) {
1085 curve = *shape->curve();
1086 }
else if (
auto text = cast<SPText>(
item)) {
1087 curve = text->getNormalizedBpath();
1093 orig->LoadPathVector(
curve.get_pathvector());
1114 orig->ConvertWithBackData (1.0);
1115 orig->Fill (theShape, 0);
1120 if (val && strcmp (val,
"nonzero") == 0)
1124 else if (val && strcmp (val,
"evenodd") == 0)
1134 originaux[0] =
orig;
1153 return offset->sourceRef->getObject();
TODO: insert short description here.
TODO: insert short description here.
Lookup dictionary for attributes/properties.
TODO: insert short description here.
3x3 matrix representing an affine transformation.
Coord descrim() const
Calculate the descriminant.
bool isIdentity(Coord eps=EPSILON) const
Check whether this matrix is an identity matrix.
void setIdentity()
Sets this matrix to be the Identity Affine.
bool isTranslation(Coord eps=EPSILON) const
Check whether this matrix represents a pure translation.
Affine inverse() const
Compute the inverse matrix.
Axis-aligned rectangle that can be empty.
Two-dimensional point that doubles as a vector.
Preference storage class.
static Preferences * get()
Access the singleton Preferences object.
int getInt(Glib::ustring const &pref_path, int def=0)
Retrieve an integer.
Storing of snapping preferences.
void detach()
Detaches from the currently attached URI target, if any; the current referrent is signaled as NULL.
sigc::signal< void(SPObject *, SPObject *)> changedSignal()
Accessor for the referrent change notification signal; this signal is emitted whenever the URIReferen...
void attach(URI const &uri)
Attaches to a URI, relative to the specified document.
Represents an URI as per RFC 2396.
Interface for refcounted XML nodes.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
bool setAttributeSvgDouble(Util::const_char_ptr key, double val)
For attributes where an exponent is allowed.
Path and its polyline approximation.
void ConvertWithBackData(double threshhold, bool relative=false)
Creates a polyline approximation of the path.
void SetBackData(bool nVal)
Sets the back variable to the value passed in and clears the polyline approximation.
void OutsideOutline(Path *dest, double width, JoinType join, ButtType butt, double miter)
void Fill(Shape *dest, int pathID=-1, bool justAdd=false, bool closeIfNeeded=true, bool invert=false)
Fills the shape with the polyline approximation stored in this object.
std::string svg_dump_path() const
void ConvertEvenLines(double treshhold)
Creates a polyline approximation of the path.
void LoadPathVector(Geom::PathVector const &pv, Geom::Affine const &tr, bool doTransformation)
Load a lib2geom Geom::PathVector in this path object.
Path ** SubPaths(int &outNb, bool killNoSurf)
void Simplify(double treshhold)
Simplify the path.
void Convert(double treshhold)
Creates a polyline approximation of the path.
void PolylineBoundingBox(double &l, double &t, double &r, double &b)
Wrapper around a Geom::PathVector object.
Typed SVG document implementation.
Base class for visual SVG elements.
Geom::OptRect documentVisualBounds() const
Get item's visual bbox in document coordinate system.
sigc::connection connectTransformed(sigc::slot< void(Geom::Affine const *, SPItem *)> slot)
void doWriteTransform(Geom::Affine const &transform, Geom::Affine const *adv=nullptr, bool compensate=true)
Set a new transform on an object.
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Inkscape::XML::Node * repr
void setAttribute(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
void removeAttribute(char const *key)
sigc::connection connectDelete(sigc::slot< void(SPObject *)> slot)
Connects a slot to be called when an object is deleted.
void readAttr(char const *key)
Read value of key attribute from XML node into object.
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
sigc::connection connectModified(sigc::slot< void(SPObject *, unsigned int)> slot)
Connects to the modification notification signal.
void requestDisplayUpdate(unsigned int flags)
Queues an deferred update of this object's display.
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned flags) override
char * description() const override
bool knotSet
for interactive setting of the radius
void build(SPDocument *document, Inkscape::XML::Node *repr) override
SPUseReference * sourceRef
const char * typeName() const override
The item's type name, not node tag name.
void set_shape() override
sigc::connection _modified_connection
void snappoints(std::vector< Inkscape::SnapCandidatePoint > &p, Inkscape::SnapPreferences const *snapprefs) const override
Inkscape::XML::Node * sourceRepr
the repr associated with that id
sigc::connection _transformed_connection
void update(SPCtx *ctx, unsigned int flags) override
sigc::connection _changed_connection
const char * displayName() const override
The item's type name as a translated human string.
char * original
SVG description of the source path.
void * originalPath
will be a livarot Path, just don't declare it here to please the gcc linker FIXME what?
sigc::connection _delete_connection
void set(SPAttr key, char const *value) override
Base class for shapes, including <path> element.
SPCurve const * curve() const
Return a borrowed pointer to the curve (if any exists) or NULL if there is no curve.
void update(SPCtx *ctx, unsigned int flags) override
void setCurveInsync(SPCurve const *)
void snappoints(std::vector< Inkscape::SnapCandidatePoint > &p, Inkscape::SnapPreferences const *snapprefs) const override
Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) const override
void release() override
Removes, releases and unrefs all children of object.
void set(SPAttr key, char const *value) override
void setCurveBeforeLPE(SPCurve const *)
void build(SPDocument *document, Inkscape::XML::Node *repr) override
std::shared_ptr< SPCurve const > _curve
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
A class to store/manipulate directed graphs.
void ConvertToForme(Path *dest)
Extract contours from a directed graph.
bool hasPoints() const
Do we have points?
void SortPoints()
Sort the points (all points) only if needed.
void CalcBBox(bool strict_degree=false)
int numberOfEdges() const
Returns number of edges.
int NextAt(int p, int b) const
int numberOfPoints() const
Returns number of points.
dg_arete const & getEdge(int n) const
Get an edge.
void Reset(int n=0, int m=0)
Clear all data.
int MakeOffset(Shape *of, double dec, JoinType join, double miter, bool do_profile=false, double cx=0, double cy=0, double radius=0, Geom::Affine *i2doc=nullptr)
int ConvertToShape(Shape *a, FillRule directed=fill_nonZero, bool invert=false)
Using a given fill rule, find all intersections in the shape given, create a new intersection free sh...
dg_point const & getPoint(int n) const
Get a point.
std::shared_ptr< Css const > css
@ SP_CLONE_ORPHANS_UNLINK
@ SP_CLONE_ORPHANS_DELETE
@ SP_CLONE_COMPENSATION_UNMOVED
@ SP_CLONE_COMPENSATION_PARALLEL
@ SP_CLONE_COMPENSATION_NONE
D2< T > rot90(D2< T > const &a)
static cairo_user_data_key_t key
Singleton class to access the preferences file in a convenient way.
SPCSSAttr * sp_repr_css_attr(Node const *repr, gchar const *attr)
Creates a new SPCSSAttr with one attribute (i.e.
char const * sp_repr_css_property(SPCSSAttr *css, gchar const *name, gchar const *defval)
Returns a character string of the value of a given style property or a default value if the attribute...
static void refresh_offset_source(SPOffset *offset)
static void sp_offset_source_modified(SPObject *iSource, guint flags, SPItem *item)
double sp_offset_distance_to_original(SPOffset *offset, Geom::Point px)
Distance to the original path; that function is called from shape-editor-knotholders to set the radiu...
SPItem * sp_offset_get_source(SPOffset *offset)
static void sp_offset_delete_self(SPObject *deleted, SPOffset *self)
static void sp_offset_quit_listening(SPOffset *offset)
static void sp_offset_start_listening(SPOffset *offset, SPItem *to)
static bool vectors_are_clockwise(Geom::Point A, Geom::Point B, Geom::Point C)
static bool use_slow_but_correct_offset_method
static void sp_offset_move_compensate(Geom::Affine const *mp, SPItem *original, SPOffset *self)
static void sp_offset_href_changed(SPObject *old_ref, SPObject *ref, SPOffset *offset)
void sp_offset_top_point(SPOffset const *offset, Geom::Point *px)
Computes a point on the offset; used to set a "seed" position for the control knot.
Interface for XML documents.
virtual Node * createElement(char const *name)=0
bool sp_svg_transform_read(gchar const *str, Geom::Affine *transform)
unsigned int sp_svg_length_read_computed_absolute(gchar const *str, float *length)
Geom::PathVector sp_svg_read_pathv(char const *str)
static void sp_svg_write_path(Inkscape::SVG::PathString &str, Geom::Path const &p, bool normalize=false)
void dot(Cairo::RefPtr< Cairo::Context > &cr, double x, double y)