summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTomasz Boczkowski <penginsbacon@gmail.com>2015-04-25 12:59:51 +0000
committerTomasz Boczkowski <penginsbacon@gmail.com>2015-04-25 12:59:51 +0000
commit3eb2b94eded9236bea634cd28eae13a3645a8cfb (patch)
treef89f5fc023b87e5127ed57a1fc22c6d21e88fbd0 /src
parentmerged SPColorSlider c++-sification from svgpaints branch (diff)
parentSPPattern c++-sification: class fields are private (diff)
downloadinkscape-3eb2b94eded9236bea634cd28eae13a3645a8cfb.tar.gz
inkscape-3eb2b94eded9236bea634cd28eae13a3645a8cfb.zip
merged SPPattern c++-sification from svgpaints branch
(bzr r14059.1.2)
Diffstat (limited to 'src')
-rw-r--r--src/desktop-style.cpp4
-rw-r--r--src/extension/internal/cairo-render-context.cpp16
-rw-r--r--src/extension/internal/emf-print.cpp8
-rw-r--r--src/extension/internal/wmf-print.cpp4
-rw-r--r--src/knot-holder-entity.cpp18
-rw-r--r--src/selection-chemistry.cpp24
-rw-r--r--src/sp-item.cpp8
-rw-r--r--src/sp-pattern.cpp242
-rw-r--r--src/sp-pattern.h131
-rw-r--r--src/widgets/fill-style.cpp4
-rw-r--r--src/widgets/paint-selector.cpp4
11 files changed, 230 insertions, 233 deletions
diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp
index c713e0d61..eabdae0d2 100644
--- a/src/desktop-style.cpp
+++ b/src/desktop-style.cpp
@@ -577,8 +577,8 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill
return QUERY_STYLE_MULTIPLE_DIFFERENT; // different kind of server
}
- SPPattern *pat = pattern_getroot (pattern);
- SPPattern *pat_res = pattern_getroot (pattern_res);
+ SPPattern *pat = SP_PATTERN (server)->get_root();
+ SPPattern *pat_res = SP_PATTERN (server_res)->get_root();
if (pat_res != pat) {
return QUERY_STYLE_MULTIPLE_DIFFERENT; // different pattern roots
}
diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp
index 2d6619e1e..7162ca658 100644
--- a/src/extension/internal/cairo-render-context.cpp
+++ b/src/extension/internal/cairo-render-context.cpp
@@ -1008,16 +1008,16 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
ps2user = Geom::identity();
pcs2dev = Geom::identity();
- double x = pattern_x(pat);
- double y = pattern_y(pat);
- double width = pattern_width(pat);
- double height = pattern_height(pat);
+ double x = pat->get_x();
+ double y = pat->get_y();
+ double width = pat->get_width();
+ double height = pat->get_height();
double bbox_width_scaler;
double bbox_height_scaler;
TRACE(("%f x %f pattern\n", width, height));
- if (pbox && pattern_patternUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
+ if (pbox && pat->get_pattern_units() == SPPattern::UNITS_OBJECTBOUNDINGBOX) {
//Geom::Affine bbox2user (pbox->x1 - pbox->x0, 0.0, 0.0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0);
bbox_width_scaler = pbox->width();
bbox_height_scaler = pbox->height();
@@ -1031,13 +1031,13 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
}
// apply pattern transformation
- Geom::Affine pattern_transform(pattern_patternTransform(pat));
+ Geom::Affine pattern_transform(pat->get_transform());
ps2user *= pattern_transform;
Geom::Point ori (ps2user[4], ps2user[5]);
// create pattern contents coordinate system
if (pat->viewBox_set) {
- Geom::Rect view_box = *pattern_viewBox(pat);
+ Geom::Rect view_box = *pat->get_viewbox();
double x, y, w, h;
x = 0;
@@ -1050,7 +1050,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
pcs2dev[3] = h / view_box.height();
pcs2dev[4] = x - view_box.left() * pcs2dev[0];
pcs2dev[5] = y - view_box.top() * pcs2dev[3];
- } else if (pbox && pattern_patternContentUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
+ } else if (pbox && pat->get_pattern_content_units() == SPPattern::UNITS_OBJECTBOUNDINGBOX) {
pcs2dev[0] = pbox->width();
pcs2dev[3] = pbox->height();
}
diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp
index 67a9242bc..a391548e9 100644
--- a/src/extension/internal/emf-print.cpp
+++ b/src/extension/internal/emf-print.cpp
@@ -388,8 +388,8 @@ int PrintEmf::create_brush(SPStyle const *style, PU_COLORREF fcolor)
} else if (SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style))) { // must be paint-server
SPPaintServer *paintserver = style->fill.value.href->getObject();
SPPattern *pat = SP_PATTERN(paintserver);
- double dwidth = pattern_width(pat);
- double dheight = pattern_height(pat);
+ double dwidth = pat->get_width();
+ double dheight = pat->get_height();
width = dwidth;
height = dheight;
brush_classify(pat, 0, &pixbuf, &hatchType, &hatchColor, &bkColor);
@@ -574,8 +574,8 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform)
if (SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style))) { // must be paint-server
SPPaintServer *paintserver = style->stroke.value.href->getObject();
SPPattern *pat = SP_PATTERN(paintserver);
- double dwidth = pattern_width(pat);
- double dheight = pattern_height(pat);
+ double dwidth = pat->get_width();
+ double dheight = pat->get_height();
width = dwidth;
height = dheight;
brush_classify(pat, 0, &pixbuf, &hatchType, &hatchColor, &bkColor);
diff --git a/src/extension/internal/wmf-print.cpp b/src/extension/internal/wmf-print.cpp
index 567f9f366..2d0e51e30 100644
--- a/src/extension/internal/wmf-print.cpp
+++ b/src/extension/internal/wmf-print.cpp
@@ -379,8 +379,8 @@ int PrintWmf::create_brush(SPStyle const *style, U_COLORREF *fcolor)
} else if (SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style))) { // must be paint-server
SPPaintServer *paintserver = style->fill.value.href->getObject();
SPPattern *pat = SP_PATTERN(paintserver);
- double dwidth = pattern_width(pat);
- double dheight = pattern_height(pat);
+ double dwidth = pat->get_width();
+ double dheight = pat->get_height();
width = dwidth;
height = dheight;
brush_classify(pat, 0, &pixbuf, &hatchType, &hatchColor, &bkColor);
diff --git a/src/knot-holder-entity.cpp b/src/knot-holder-entity.cpp
index b66156b09..69ee4017e 100644
--- a/src/knot-holder-entity.cpp
+++ b/src/knot-holder-entity.cpp
@@ -140,19 +140,19 @@ KnotHolderEntity::snap_knot_position_constrained(Geom::Point const &p, Inkscape:
static gdouble sp_pattern_extract_theta(SPPattern const *pat)
{
- Geom::Affine transf = pat->patternTransform;
+ Geom::Affine transf = pat->get_transform();
return Geom::atan2(transf.xAxis());
}
static Geom::Point sp_pattern_extract_scale(SPPattern const *pat)
{
- Geom::Affine transf = pat->patternTransform;
+ Geom::Affine transf = pat->get_transform();
return Geom::Point( transf.expansionX(), transf.expansionY() );
}
static Geom::Point sp_pattern_extract_trans(SPPattern const *pat)
{
- return Geom::Point(pat->patternTransform[4], pat->patternTransform[5]);
+ return Geom::Point(pat->get_transform()[4], pat->get_transform()[5]);
}
void
@@ -191,7 +191,7 @@ PatternKnotHolderEntityAngle::knot_get() const
{
SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer());
- gdouble x = pattern_width(pat);
+ gdouble x = pat->get_width();
gdouble y = 0;
Geom::Point delta = Geom::Point(x,y);
Geom::Point scale = sp_pattern_extract_scale(pat);
@@ -240,8 +240,8 @@ PatternKnotHolderEntityScale::knot_set(Geom::Point const &p, Geom::Point const &
// Get the new scale from the position of the knotholder
Geom::Point d = p_snapped - sp_pattern_extract_trans(pat);
- gdouble pat_x = pattern_width(pat);
- gdouble pat_y = pattern_height(pat);
+ gdouble pat_x = pat->get_width();
+ gdouble pat_y = pat->get_height();
Geom::Scale scl(1);
if ( state & GDK_CONTROL_MASK ) {
// if ctrl is pressed: use 1:1 scaling
@@ -267,10 +267,10 @@ PatternKnotHolderEntityScale::knot_get() const
{
SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer());
- gdouble x = pattern_width(pat);
- gdouble y = pattern_height(pat);
+ gdouble x = pat->get_width();
+ gdouble y = pat->get_height();
Geom::Point delta = Geom::Point(x,y);
- Geom::Affine a = pat->patternTransform;
+ Geom::Affine a = pat->get_transform();
a[4] = 0;
a[5] = 0;
delta = delta * a;
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 5e8fd5e07..6f7eddd43 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -1990,8 +1990,8 @@ GSList *sp_get_same_fill_or_stroke_color(SPItem *sel, GSList *src, SPSelectStrok
}
} else if (dynamic_cast<SPPattern *>(sel_server) && dynamic_cast<SPPattern *>(iter_server)) {
- SPPattern *sel_pat = pattern_getroot(dynamic_cast<SPPattern *>(sel_server));
- SPPattern *iter_pat = pattern_getroot(dynamic_cast<SPPattern *>(iter_server));
+ SPPattern *sel_pat = SP_PATTERN(sel_server)->get_root();
+ SPPattern *iter_pat = SP_PATTERN(iter_server)->get_root();
if (sel_pat == iter_pat) {
match = true;
}
@@ -3340,13 +3340,11 @@ sp_selection_tile(SPDesktop *desktop, bool apply)
gint pos = SP_OBJECT(items->data)->getRepr()->position();
// create a list of duplicates
- GSList *repr_copies = NULL;
+ std::list<Inkscape::XML::Node*> repr_copies;
for (GSList *i = items; i != NULL; i = i->next) {
Inkscape::XML::Node *dup = SP_OBJECT(i->data)->getRepr()->duplicate(xml_doc);
- repr_copies = g_slist_prepend(repr_copies, dup);
+ repr_copies.push_back(dup);
}
- // restore the z-order after prepends
- repr_copies = g_slist_reverse(repr_copies);
Geom::Rect bbox(desktop->dt2doc(r->min()), desktop->dt2doc(r->max()));
@@ -3365,11 +3363,11 @@ sp_selection_tile(SPDesktop *desktop, bool apply)
int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
- gchar const *pat_id = pattern_tile(repr_copies, bbox, doc,
- ( Geom::Affine(Geom::Translate(desktop->dt2doc(Geom::Point(r->min()[Geom::X],
- r->max()[Geom::Y]))))
- * parent_transform.inverse() ),
- parent_transform * move);
+ gchar const *pat_id = SPPattern::produce(repr_copies, bbox, doc,
+ ( Geom::Affine(Geom::Translate(desktop->dt2doc(Geom::Point(r->min()[Geom::X],
+ r->max()[Geom::Y]))))
+ * parent_transform.inverse() ),
+ parent_transform * move);
// restore compensation setting
prefs->setInt("/options/clonecompensation/value", saved_compensation);
@@ -3446,9 +3444,9 @@ void sp_selection_untile(SPDesktop *desktop)
did = true;
- SPPattern *pattern = pattern_getroot(basePat);
+ SPPattern *pattern = basePat->get_root();
- Geom::Affine pat_transform = pattern_patternTransform(basePat);
+ Geom::Affine pat_transform = pattern->get_transform();
pat_transform *= item->transform;
for (SPObject *child = pattern->firstChild() ; child != NULL; child = child->next ) {
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index 8c99e9bcf..506f9e52a 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -1234,8 +1234,8 @@ void SPItem::adjust_pattern(Geom::Affine const &postmul, bool set, PatternTransf
SPObject *server = style->getFillPaintServer();
SPPattern *serverPatt = dynamic_cast<SPPattern *>(server);
if ( serverPatt ) {
- SPPattern *pattern = sp_pattern_clone_if_necessary(this, serverPatt, "fill");
- sp_pattern_transform_multiply(pattern, postmul, set);
+ SPPattern *pattern = serverPatt->clone_if_necessary(this, "fill");
+ pattern->transform_multiply(postmul, set);
}
}
@@ -1244,8 +1244,8 @@ void SPItem::adjust_pattern(Geom::Affine const &postmul, bool set, PatternTransf
SPObject *server = style->getStrokePaintServer();
SPPattern *serverPatt = dynamic_cast<SPPattern *>(server);
if ( serverPatt ) {
- SPPattern *pattern = sp_pattern_clone_if_necessary(this, serverPatt, "stroke");
- sp_pattern_transform_multiply(pattern, postmul, set);
+ SPPattern *pattern = serverPatt->clone_if_necessary(this, "stroke");
+ pattern->transform_multiply(postmul, set);
}
}
}
diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp
index 987a86fe4..df8086ae7 100644
--- a/src/sp-pattern.cpp
+++ b/src/sp-pattern.cpp
@@ -20,8 +20,8 @@
#include <string>
#include <glibmm.h>
#include <2geom/transforms.h>
+#include <sigc++/functors/mem_fun.h>
-#include "macros.h"
#include "svg/svg.h"
#include "display/cairo-utils.h"
#include "display/drawing-context.h"
@@ -34,31 +34,21 @@
#include "style.h"
#include "sp-pattern.h"
#include "xml/repr.h"
-#include "display/grayscale.h"
-#include <sigc++/functors/ptr_fun.h>
-#include <sigc++/adaptors/bind.h>
-
-/*
- * Pattern
- */
-static void pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat);
-static void pattern_ref_modified (SPObject *ref, guint flags, SPPattern *pattern);
+#include "sp-factory.h"
SPPattern::SPPattern() : SPPaintServer(), SPViewBox() {
- this->href = NULL;
-
this->ref = new SPPatternReference(this);
- this->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(pattern_ref_changed), this));
+ this->ref->changedSignal().connect(sigc::mem_fun(this, &SPPattern::_on_ref_changed));
- this->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX;
- this->patternUnits_set = FALSE;
+ this->patternUnits = UNITS_OBJECTBOUNDINGBOX;
+ this->patternUnits_set = false;
- this->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE;
- this->patternContentUnits_set = FALSE;
+ this->patternContentUnits = UNITS_USERSPACEONUSE;
+ this->patternContentUnits_set = false;
this->patternTransform = Geom::identity();
- this->patternTransform_set = FALSE;
+ this->patternTransform_set = false;
this->x.unset();
this->y.unset();
@@ -108,14 +98,14 @@ void SPPattern::set(unsigned int key, const gchar* value) {
case SP_ATTR_PATTERNUNITS:
if (value) {
if (!strcmp (value, "userSpaceOnUse")) {
- this->patternUnits = SP_PATTERN_UNITS_USERSPACEONUSE;
+ this->patternUnits = UNITS_USERSPACEONUSE;
} else {
- this->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX;
+ this->patternUnits = UNITS_OBJECTBOUNDINGBOX;
}
- this->patternUnits_set = TRUE;
+ this->patternUnits_set = true;
} else {
- this->patternUnits_set = FALSE;
+ this->patternUnits_set = false;
}
this->requestModified(SP_OBJECT_MODIFIED_FLAG);
@@ -124,14 +114,14 @@ void SPPattern::set(unsigned int key, const gchar* value) {
case SP_ATTR_PATTERNCONTENTUNITS:
if (value) {
if (!strcmp (value, "userSpaceOnUse")) {
- this->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE;
+ this->patternContentUnits = UNITS_USERSPACEONUSE;
} else {
- this->patternContentUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX;
+ this->patternContentUnits = UNITS_OBJECTBOUNDINGBOX;
}
- this->patternContentUnits_set = TRUE;
+ this->patternContentUnits_set = true;
} else {
- this->patternContentUnits_set = FALSE;
+ this->patternContentUnits_set = false;
}
this->requestModified(SP_OBJECT_MODIFIED_FLAG);
@@ -142,10 +132,10 @@ void SPPattern::set(unsigned int key, const gchar* value) {
if (value && sp_svg_transform_read (value, &t)) {
this->patternTransform = t;
- this->patternTransform_set = TRUE;
+ this->patternTransform_set = true;
} else {
this->patternTransform = Geom::identity();
- this->patternTransform_set = FALSE;
+ this->patternTransform_set = false;
}
this->requestModified(SP_OBJECT_MODIFIED_FLAG);
@@ -182,15 +172,14 @@ void SPPattern::set(unsigned int key, const gchar* value) {
break;
case SP_ATTR_XLINK_HREF:
- if ( value && this->href && ( strcmp(value, this->href) == 0 ) ) {
+ if ( value && this->href == value ) {
/* Href unchanged, do nothing. */
} else {
- g_free(this->href);
- this->href = NULL;
+ this->href.clear();
if (value) {
// First, set the href field; it's only used in the "unchanged" check above.
- this->href = g_strdup(value);
+ this->href = value;
// Now do the attaching, which emits the changed signal.
if (value) {
try {
@@ -217,37 +206,34 @@ void SPPattern::set(unsigned int key, const gchar* value) {
/* fixme: We need ::order_changed handler too (Lauris) */
-static GSList *pattern_getchildren(SPPattern *pat)
-{
- GSList *l = NULL;
-
+void SPPattern::_get_children(std::list<SPObject*>& l) {
+ SPPattern *pat = this;
for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (pat_i->firstChild()) { // find the first one with children
for (SPObject *child = pat->firstChild() ; child ; child = child->getNext() ) {
- l = g_slist_prepend (l, child);
+ l.push_back(child);
}
break; // do not go further up the chain if children are found
}
}
-
- return l;
}
void SPPattern::update(SPCtx* ctx, unsigned int flags) {
- if (flags & SP_OBJECT_MODIFIED_FLAG) {
+ typedef std::list<SPObject*>::iterator SPObjectIterator;
+
+ if (flags & SP_OBJECT_MODIFIED_FLAG) {
flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
}
flags &= SP_OBJECT_MODIFIED_CASCADE;
- GSList *l = pattern_getchildren (this);
- l = g_slist_reverse (l);
+ std::list<SPObject*> l;
+ _get_children(l);
- while (l) {
- SPObject *child = SP_OBJECT (l->data);
+ for (SPObjectIterator it = l.begin(); it != l.end(); it++) {
+ SPObject *child = *it;
sp_object_ref (child, NULL);
- l = g_slist_remove (l, child);
if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
child->updateDisplay(ctx, flags);
@@ -258,20 +244,21 @@ void SPPattern::update(SPCtx* ctx, unsigned int flags) {
}
void SPPattern::modified(unsigned int flags) {
+ typedef std::list<SPObject*>::iterator SPObjectIterator;
+
if (flags & SP_OBJECT_MODIFIED_FLAG) {
flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
}
flags &= SP_OBJECT_MODIFIED_CASCADE;
- GSList *l = pattern_getchildren (this);
- l = g_slist_reverse (l);
+ std::list<SPObject*> l;
+ _get_children(l);
- while (l) {
- SPObject *child = SP_OBJECT (l->data);
+ for (SPObjectIterator it = l.begin(); it != l.end(); it++) {
+ SPObject *child = *it;
sp_object_ref (child, NULL);
- l = g_slist_remove (l, child);
if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
child->emitModified(flags);
@@ -281,40 +268,25 @@ void SPPattern::modified(unsigned int flags) {
}
}
-/**
-Gets called when the pattern is reattached to another <pattern>
-*/
-static void
-pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat)
-{
+void SPPattern::_on_ref_changed(SPObject *old_ref, SPObject *ref) {
if (old_ref) {
- pat->modified_connection.disconnect();
+ modified_connection.disconnect();
}
if (SP_IS_PATTERN (ref)) {
- pat->modified_connection = ref->connectModified(sigc::bind<2>(sigc::ptr_fun(&pattern_ref_modified), pat));
+ modified_connection = ref->connectModified(sigc::mem_fun(this, &SPPattern::_on_ref_modified));
}
- pattern_ref_modified (ref, 0, pat);
+ _on_ref_modified(ref, 0);
}
-/**
-Gets called when the referenced <pattern> is changed
-*/
-static void pattern_ref_modified (SPObject */*ref*/, guint /*flags*/, SPPattern *pattern)
+void SPPattern::_on_ref_modified(SPObject */*ref*/, guint /*flags*/)
{
- if ( SP_IS_OBJECT(pattern) ) {
- pattern->requestModified(SP_OBJECT_MODIFIED_FLAG);
- }
+ requestModified(SP_OBJECT_MODIFIED_FLAG);
// Conditional to avoid causing infinite loop if there's a cycle in the href chain.
}
-
-/**
-Count how many times pat is used by the styles of o and its descendants
-*/
-static guint
-count_pattern_hrefs(SPObject *o, SPPattern *pat)
+guint SPPattern::_count_hrefs(SPObject *o) const
{
if (!o)
return 1;
@@ -325,36 +297,33 @@ count_pattern_hrefs(SPObject *o, SPPattern *pat)
if (style
&& style->fill.isPaintserver()
&& SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style))
- && SP_PATTERN(SP_STYLE_FILL_SERVER(style)) == pat)
+ && SP_PATTERN(SP_STYLE_FILL_SERVER(style)) == this)
{
i ++;
}
if (style
&& style->stroke.isPaintserver()
&& SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style))
- && SP_PATTERN(SP_STYLE_STROKE_SERVER(style)) == pat)
+ && SP_PATTERN(SP_STYLE_STROKE_SERVER(style)) == this)
{
i ++;
}
for ( SPObject *child = o->firstChild(); child != NULL; child = child->next ) {
- i += count_pattern_hrefs(child, pat);
+ i += _count_hrefs(child);
}
return i;
}
-SPPattern *pattern_chain(SPPattern *pattern)
-{
- SPDocument *document = pattern->document;
- Inkscape::XML::Document *xml_doc = document->getReprDoc();
+SPPattern *SPPattern::_chain() const {
+ Inkscape::XML::Document *xml_doc = document->getReprDoc();
Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr();
Inkscape::XML::Node *repr = xml_doc->createElement("svg:pattern");
repr->setAttribute("inkscape:collect", "always");
- gchar *parent_ref = g_strconcat("#", pattern->getRepr()->attribute("id"), NULL);
+ Glib::ustring parent_ref = Glib::ustring::compose("#%1", getRepr()->attribute("id"));
repr->setAttribute("xlink:href", parent_ref);
- g_free (parent_ref);
defsrepr->addChild(repr, NULL);
const gchar *child_id = repr->attribute("id");
@@ -364,42 +333,42 @@ SPPattern *pattern_chain(SPPattern *pattern)
return SP_PATTERN (child);
}
-SPPattern *
-sp_pattern_clone_if_necessary (SPItem *item, SPPattern *pattern, const gchar *property)
-{
- if (!pattern->href || pattern->hrefcount > count_pattern_hrefs(item, pattern)) {
- pattern = pattern_chain (pattern);
- gchar *href = g_strconcat("url(#", pattern->getRepr()->attribute("id"), ")", NULL);
+SPPattern *SPPattern::clone_if_necessary(SPItem *item, const gchar *property) {
+ SPPattern *pattern = this;
+ if (pattern->href.empty() || pattern->hrefcount > _count_hrefs(item)) {
+ pattern = _chain();
+ Glib::ustring href = Glib::ustring::compose("url(#%1)", pattern->getRepr()->attribute("id"));
SPCSSAttr *css = sp_repr_css_attr_new ();
- sp_repr_css_set_property (css, property, href);
+ sp_repr_css_set_property (css, property, href.c_str());
sp_repr_css_change_recursive(item->getRepr(), css, "style");
+
}
return pattern;
}
-void
-sp_pattern_transform_multiply (SPPattern *pattern, Geom::Affine postmul, bool set)
-{
+void SPPattern::transform_multiply(Geom::Affine postmul, bool set) {
// this formula is for a different interpretation of pattern transforms as described in (*) in sp-pattern.cpp
// for it to work, we also need sp_object_read_attr( item, "transform");
//pattern->patternTransform = premul * item->transform * pattern->patternTransform * item->transform.inverse() * postmul;
// otherwise the formula is much simpler
if (set) {
- pattern->patternTransform = postmul;
+ patternTransform = postmul;
} else {
- pattern->patternTransform = pattern_patternTransform(pattern) * postmul;
+ patternTransform = get_transform() * postmul;
}
- pattern->patternTransform_set = TRUE;
+ patternTransform_set = true;
- gchar *c=sp_svg_transform_write(pattern->patternTransform);
- pattern->getRepr()->setAttribute("patternTransform", c);
- g_free(c);
+ Glib::ustring c=sp_svg_transform_write(patternTransform);
+ getRepr()->setAttribute("patternTransform", c);
}
-const gchar *pattern_tile(GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Affine transform, Geom::Affine move)
+const gchar *SPPattern::produce(const std::list<Inkscape::XML::Node*> &reprs, Geom::Rect bounds,
+ SPDocument *document, Geom::Affine transform, Geom::Affine move)
{
+ typedef std::list<Inkscape::XML::Node*>::const_iterator NodePtrIterator;
+
Inkscape::XML::Document *xml_doc = document->getReprDoc();
Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr();
@@ -408,16 +377,15 @@ const gchar *pattern_tile(GSList *reprs, Geom::Rect bounds, SPDocument *document
sp_repr_set_svg_double(repr, "width", bounds.dimensions()[Geom::X]);
sp_repr_set_svg_double(repr, "height", bounds.dimensions()[Geom::Y]);
- gchar *t=sp_svg_transform_write(transform);
+ Glib::ustring t=sp_svg_transform_write(transform);
repr->setAttribute("patternTransform", t);
- g_free(t);
defsrepr->appendChild(repr);
const gchar *pat_id = repr->attribute("id");
SPObject *pat_object = document->getObjectById(pat_id);
- for (GSList *i = reprs; i != NULL; i = i->next) {
- Inkscape::XML::Node *node = (Inkscape::XML::Node *)(i->data);
+ for (NodePtrIterator i = reprs.begin(); i != reprs.end(); i++) {
+ Inkscape::XML::Node *node = *i;
SPItem *copy = SP_ITEM(pat_object->appendChildRepr(node));
Geom::Affine dup_transform;
@@ -432,14 +400,14 @@ const gchar *pattern_tile(GSList *reprs, Geom::Rect bounds, SPDocument *document
return pat_id;
}
-SPPattern *pattern_getroot(SPPattern *pat)
+SPPattern *SPPattern::get_root()
{
- for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ for (SPPattern *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if ( pat_i->firstChild() ) { // find the first one with children
return pat_i;
}
}
- return pat; // document is broken, we can't get to root; but at least we can return pat which is supposedly a valid pattern
+ return this; // document is broken, we can't get to root; but at least we can return pat which is supposedly a valid pattern
}
@@ -447,73 +415,73 @@ SPPattern *pattern_getroot(SPPattern *pat)
// Access functions that look up fields up the chain of referenced patterns and return the first one which is set
// FIXME: all of them must use chase_hrefs the same as in SPGradient, to avoid lockup on circular refs
-guint pattern_patternUnits (SPPattern const *pat)
+SPPattern::PatternUnits SPPattern::get_pattern_units() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (pat_i->patternUnits_set)
return pat_i->patternUnits;
}
- return pat->patternUnits;
+ return patternUnits;
}
-guint pattern_patternContentUnits (SPPattern const *pat)
+SPPattern::PatternUnits SPPattern::get_pattern_content_units() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (pat_i->patternContentUnits_set)
return pat_i->patternContentUnits;
}
- return pat->patternContentUnits;
+ return patternContentUnits;
}
-Geom::Affine const &pattern_patternTransform(SPPattern const *pat)
+Geom::Affine const &SPPattern::get_transform() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (pat_i->patternTransform_set)
return pat_i->patternTransform;
}
- return pat->patternTransform;
+ return patternTransform;
}
-gdouble pattern_x (SPPattern const *pat)
+gdouble SPPattern::get_x() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (pat_i->x._set)
return pat_i->x.computed;
}
return 0;
}
-gdouble pattern_y (SPPattern const *pat)
+gdouble SPPattern::get_y() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (pat_i->y._set)
return pat_i->y.computed;
}
return 0;
}
-gdouble pattern_width (SPPattern const* pat)
+gdouble SPPattern::get_width() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (pat_i->width._set)
return pat_i->width.computed;
}
return 0;
}
-gdouble pattern_height (SPPattern const *pat)
+gdouble SPPattern::get_height() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (pat_i->height._set)
return pat_i->height.computed;
}
return 0;
}
-Geom::OptRect pattern_viewBox (SPPattern const *pat)
+Geom::OptRect SPPattern::get_viewbox() const
{
Geom::OptRect viewbox;
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (pat_i->viewBox_set) {
viewbox = pat_i->viewBox;
break;
@@ -522,10 +490,10 @@ Geom::OptRect pattern_viewBox (SPPattern const *pat)
return viewbox;
}
-static bool pattern_hasItemChildren (SPPattern const *pat)
+bool SPPattern::_has_item_children() const
{
bool hasChildren = false;
- for (SPObject const *child = pat->firstChild() ; child && !hasChildren ; child = child->getNext() ) {
+ for (SPObject const *child = firstChild() ; child && !hasChildren ; child = child->getNext() ) {
if (SP_IS_ITEM(child)) {
hasChildren = true;
}
@@ -535,8 +503,8 @@ static bool pattern_hasItemChildren (SPPattern const *pat)
bool SPPattern::isValid() const
{
- double tile_width = pattern_width(this);
- double tile_height = pattern_height(this);
+ double tile_width = get_width();
+ double tile_height = get_height();
if (tile_width <= 0 || tile_height <= 0)
return false;
@@ -557,7 +525,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
for (SPPattern *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
// find the first one with item children
- if (pat_i && SP_IS_OBJECT(pat_i) && pattern_hasItemChildren(pat_i)) {
+ if (pat_i && SP_IS_OBJECT(pat_i) && pat_i->_has_item_children()) {
shown = pat_i;
break; // do not go further up the chain if children are found
}
@@ -591,11 +559,11 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
// * "x", "y", and "patternTransform" transform tile to user space after tile is generated.
// These functions recursively search up the tree to find the values.
- double tile_x = pattern_x(this);
- double tile_y = pattern_y(this);
- double tile_width = pattern_width(this);
- double tile_height = pattern_height(this);
- if ( bbox && (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) ) {
+ double tile_x = get_x();
+ double tile_y = get_y();
+ double tile_width = get_width();
+ double tile_height = get_height();
+ if ( bbox && (get_pattern_units() == UNITS_OBJECTBOUNDINGBOX) ) {
tile_x *= bbox->width();
tile_y *= bbox->height();
tile_width *= bbox->width();
@@ -607,7 +575,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
// Content to tile (pattern space)
Geom::Affine content2ps;
- Geom::OptRect effective_view_box = pattern_viewBox(this);
+ Geom::OptRect effective_view_box = get_viewbox();
if (effective_view_box) {
// viewBox to pattern server (using SPViewBox)
viewBox = *effective_view_box;
@@ -617,14 +585,14 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
} else {
// Content to bbox
- if (bbox && (pattern_patternContentUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) ) {
+ if (bbox && (get_pattern_content_units() == UNITS_OBJECTBOUNDINGBOX) ) {
content2ps = Geom::Affine(bbox->width(), 0.0, 0.0, bbox->height(), 0,0);
}
}
// Tile (pattern space) to user.
- Geom::Affine ps2user = Geom::Translate(tile_x,tile_y) * pattern_patternTransform(this);
+ Geom::Affine ps2user = Geom::Translate(tile_x,tile_y) * get_transform();
// Transform of object with pattern (includes screen scaling)
diff --git a/src/sp-pattern.h b/src/sp-pattern.h
index f021101e2..83336f991 100644
--- a/src/sp-pattern.h
+++ b/src/sp-pattern.h
@@ -1,9 +1,6 @@
-#ifndef SEEN_SP_PATTERN_H
-#define SEEN_SP_PATTERN_H
-
-/*
+/** @file
* SVG <pattern> implementation
- *
+ *//*
* Author:
* Lauris Kaplinski <lauris@kaplinski.com>
* Abhishek Sharma
@@ -13,45 +10,66 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#define SP_PATTERN(obj) (dynamic_cast<SPPattern*>((SPObject*)obj))
-#define SP_IS_PATTERN(obj) (dynamic_cast<const SPPattern*>((SPObject*)obj) != NULL)
+#ifndef SEEN_SP_PATTERN_H
+#define SEEN_SP_PATTERN_H
-class SPPatternReference;
-class SPItem;
-typedef struct _GSList GSList;
+#include <list>
+#include <stddef.h>
+#include <glibmm/ustring.h>
+#include <sigc++/connection.h>
#include "svg/svg-length.h"
#include "sp-paint-server.h"
#include "uri-references.h"
#include "viewbox.h"
-#include <sigc++/connection.h>
+class SPPatternReference;
+class SPItem;
+
+namespace Inkscape {
+namespace XML {
+
+class Node;
+}
+}
+
+#define SP_PATTERN(obj) (dynamic_cast<SPPattern*>((SPObject*)obj))
+#define SP_IS_PATTERN(obj) (dynamic_cast<const SPPattern*>((SPObject*)obj) != NULL)
class SPPattern : public SPPaintServer, public SPViewBox {
public:
+ enum PatternUnits {
+ UNITS_USERSPACEONUSE,
+ UNITS_OBJECTBOUNDINGBOX
+ };
+
SPPattern();
virtual ~SPPattern();
/* Reference (href) */
- char *href;
+ Glib::ustring href;
SPPatternReference *ref;
- /* patternUnits and patternContentUnits attribute */
- unsigned int patternUnits : 1;
- unsigned int patternUnits_set : 1;
- unsigned int patternContentUnits : 1;
- unsigned int patternContentUnits_set : 1;
- /* patternTransform attribute */
- Geom::Affine patternTransform;
- unsigned int patternTransform_set : 1;
- /* Tile rectangle */
- SVGLength x;
- SVGLength y;
- SVGLength width;
- SVGLength height;
-
- sigc::connection modified_connection;
+ gdouble get_x() const;
+ gdouble get_y() const;
+ gdouble get_width() const;
+ gdouble get_height() const;
+ Geom::OptRect get_viewbox() const;
+ SPPattern::PatternUnits get_pattern_units() const;
+ SPPattern::PatternUnits get_pattern_content_units() const;
+ Geom::Affine const &get_transform() const;
+ SPPattern *get_root(); //TODO: const
+
+ SPPattern *clone_if_necessary(SPItem *item, const gchar *property);
+ void transform_multiply(Geom::Affine postmul, bool set);
+
+ /**
+ * @brief create a new pattern in XML tree
+ * @return created pattern id
+ */
+ static const gchar *produce(const std::list<Inkscape::XML::Node*> &reprs,
+ Geom::Rect bounds, SPDocument *document, Geom::Affine transform, Geom::Affine move);
bool isValid() const;
@@ -63,6 +81,42 @@ protected:
virtual void set(unsigned int key, const gchar* value);
virtual void update(SPCtx* ctx, unsigned int flags);
virtual void modified(unsigned int flags);
+
+private:
+ bool _has_item_children() const;
+ void _get_children(std::list<SPObject*>& l);
+ SPPattern *_chain() const;
+
+ /**
+ Count how many times pattern is used by the styles of o and its descendants
+ */
+ guint _count_hrefs(SPObject* o) const;
+
+ /**
+ Gets called when the pattern is reattached to another <pattern>
+ */
+ void _on_ref_changed(SPObject *old_ref, SPObject *ref);
+
+ /**
+ Gets called when the referenced <pattern> is changed
+ */
+ void _on_ref_modified(SPObject *ref, guint flags);
+
+ /* patternUnits and patternContentUnits attribute */
+ PatternUnits patternUnits : 1;
+ bool patternUnits_set : 1;
+ PatternUnits patternContentUnits : 1;
+ bool patternContentUnits_set : 1;
+ /* patternTransform attribute */
+ Geom::Affine patternTransform;
+ bool patternTransform_set : 1;
+ /* Tile rectangle */
+ SVGLength x;
+ SVGLength y;
+ SVGLength width;
+ SVGLength height;
+
+ sigc::connection modified_connection;
};
@@ -79,29 +133,6 @@ protected:
}
};
-enum {
- SP_PATTERN_UNITS_USERSPACEONUSE,
- SP_PATTERN_UNITS_OBJECTBOUNDINGBOX
-};
-
-unsigned int pattern_users (SPPattern *pattern);
-SPPattern *pattern_chain (SPPattern *pattern);
-SPPattern *sp_pattern_clone_if_necessary (SPItem *item, SPPattern *pattern, const char *property);
-void sp_pattern_transform_multiply (SPPattern *pattern, Geom::Affine postmul, bool set);
-
-const char *pattern_tile (GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Affine transform, Geom::Affine move);
-
-SPPattern *pattern_getroot (SPPattern *pat);
-
-unsigned int pattern_patternUnits (SPPattern const *pat);
-unsigned int pattern_patternContentUnits (SPPattern const *pat);
-Geom::Affine const &pattern_patternTransform(SPPattern const *pat);
-double pattern_x (SPPattern const *pat);
-double pattern_y (SPPattern const *pat);
-double pattern_width (SPPattern const *pat);
-double pattern_height (SPPattern const *pat);
-Geom::OptRect pattern_viewBox (SPPattern const *pat);
-
#endif // SEEN_SP_PATTERN_H
/*
diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp
index d60a92b8b..28e1683bd 100644
--- a/src/widgets/fill-style.cpp
+++ b/src/widgets/fill-style.cpp
@@ -304,7 +304,7 @@ void FillNStroke::performUpdate()
psel->setGradientProperties( rg->getUnits(),
rg->getSpread() );
} else if (SP_IS_PATTERN(server)) {
- SPPattern *pat = pattern_getroot(SP_PATTERN(server));
+ SPPattern *pat = SP_PATTERN(server)->get_root();
psel->updatePatternList( pat );
}
}
@@ -660,7 +660,7 @@ void FillNStroke::updateFromPaint()
SPPaintServer *server = (kind == FILL) ?
selobj->style->getFillPaintServer() :
selobj->style->getStrokePaintServer();
- if (SP_IS_PATTERN(server) && pattern_getroot(SP_PATTERN(server)) == pattern)
+ if (SP_IS_PATTERN(server) && SP_PATTERN(server)->get_root() == pattern)
// only if this object's pattern is not rooted in our selected pattern, apply
continue;
}
diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp
index 948c80db3..00ad00941 100644
--- a/src/widgets/paint-selector.cpp
+++ b/src/widgets/paint-selector.cpp
@@ -828,7 +828,7 @@ ink_pattern_list_get (SPDocument *source)
GSList *pl = NULL;
GSList const *patterns = source->getResourceList("pattern");
for (GSList *l = const_cast<GSList *>(patterns); l != NULL; l = l->next) {
- if (SP_PATTERN(l->data) == pattern_getroot(SP_PATTERN(l->data))) { // only if this is a root pattern
+ if (SP_PATTERN(l->data) == SP_PATTERN(l->data)->get_root()) { // only if this is a root pattern
pl = g_slist_prepend(pl, l->data);
}
}
@@ -1148,7 +1148,7 @@ SPPattern *SPPaintSelector::getPattern()
}
g_free(paturn);
} else {
- pat = pattern_getroot(SP_PATTERN(patid));
+ pat = SP_PATTERN(patid)->get_root();
}
if (pat && !SP_IS_PATTERN(pat)) {