diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2013-09-19 22:33:11 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2013-09-19 22:33:11 +0000 |
| commit | 4bda89e32e33c7bdff5d3ea3c1ceee1f806de9f7 (patch) | |
| tree | caeb924426bcc861badc6fa81318b67460b26d47 /src/sp-gradient.cpp | |
| parent | Update to trunk (diff) | |
| parent | updates for cmake (diff) | |
| download | inkscape-4bda89e32e33c7bdff5d3ea3c1ceee1f806de9f7.tar.gz inkscape-4bda89e32e33c7bdff5d3ea3c1ceee1f806de9f7.zip | |
Update to trunk
(bzr r11950.1.141)
Diffstat (limited to 'src/sp-gradient.cpp')
| -rw-r--r-- | src/sp-gradient.cpp | 1322 |
1 files changed, 146 insertions, 1176 deletions
diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index 1f2cfdd41..adfff3609 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -60,214 +60,6 @@ /// Has to be power of 2 Seems to be unused. //#define NCOLORS NR_GRADIENT_VECTOR_LENGTH -// SPStop -static void sp_stop_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); -static void sp_stop_set(SPObject *object, unsigned key, gchar const *value); -static Inkscape::XML::Node *sp_stop_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); -G_DEFINE_TYPE(SPStop, sp_stop, SP_TYPE_OBJECT); - - -// SPMeshRow -static void sp_meshrow_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); -static void sp_meshrow_set(SPObject *object, unsigned key, gchar const *value); -static Inkscape::XML::Node *sp_meshrow_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); -G_DEFINE_TYPE(SPMeshRow, sp_meshrow, SP_TYPE_OBJECT); - - -// SPMeshPatch -static void sp_meshpatch_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); -static void sp_meshpatch_set(SPObject *object, unsigned key, gchar const *value); -static Inkscape::XML::Node *sp_meshpatch_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); -G_DEFINE_TYPE(SPMeshPatch, sp_meshpatch, SP_TYPE_OBJECT); - - -class SPGradientImpl -{ - friend class SPGradient; - - static void classInit(SPGradientClass *klass); - - static void init(SPGradient *gr); - static void build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); - static void release(SPObject *object); - static void modified(SPObject *object, guint flags); - static Inkscape::XML::Node *write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); - - static void gradientRefModified(SPObject *href, guint flags, SPGradient *gradient); - static void gradientRefChanged(SPObject *old_ref, SPObject *ref, SPGradient *gr); - - static void childAdded(SPObject *object, - Inkscape::XML::Node *child, - Inkscape::XML::Node *ref); - static void removeChild(SPObject *object, Inkscape::XML::Node *child); - - static void setGradientAttr(SPObject *object, unsigned key, gchar const *value); -}; - -/** - * Callback to initialize SPStop vtable. - */ -static void sp_stop_class_init(SPStopClass *klass) -{ - SPObjectClass *sp_object_class = (SPObjectClass *) klass; - - sp_object_class->build = sp_stop_build; - sp_object_class->set = sp_stop_set; - sp_object_class->write = sp_stop_write; -} - -/** - * Callback to initialize SPStop object. - */ -static void -sp_stop_init(SPStop *stop) -{ - stop->offset = 0.0; - stop->currentColor = false; - stop->specified_color.set( 0x000000ff ); - stop->opacity = 1.0; -} - -/** - * Virtual build: set stop attributes from its associated XML node. - */ -static void sp_stop_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) -{ - if (((SPObjectClass *) sp_stop_parent_class)->build) - (* ((SPObjectClass *) sp_stop_parent_class)->build)(object, document, repr); - - object->readAttr( "offset" ); - object->readAttr( "stop-color" ); - object->readAttr( "stop-opacity" ); - object->readAttr( "style" ); - object->readAttr( "path" ); // For mesh -} - -/** - * Virtual set: set attribute to value. - */ -static void -sp_stop_set(SPObject *object, unsigned key, gchar const *value) -{ - SPStop *stop = SP_STOP(object); - - switch (key) { - case SP_ATTR_STYLE: { - /** \todo - * fixme: We are reading simple values 3 times during build (Lauris). - * \par - * We need presentation attributes etc. - * \par - * remove the hackish "style reading" from here: see comments in - * sp_object_get_style_property about the bugs in our current - * approach. However, note that SPStyle doesn't currently have - * stop-color and stop-opacity properties. - */ - { - gchar const *p = object->getStyleProperty( "stop-color", "black"); - if (streq(p, "currentColor")) { - stop->currentColor = true; - } else { - stop->specified_color = SPStop::readStopColor( p ); - } - } - { - gchar const *p = object->getStyleProperty( "stop-opacity", "1"); - gdouble opacity = sp_svg_read_percentage(p, stop->opacity); - stop->opacity = opacity; - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); - break; - } - case SP_PROP_STOP_COLOR: { - { - gchar const *p = object->getStyleProperty( "stop-color", "black"); - if (streq(p, "currentColor")) { - stop->currentColor = true; - } else { - stop->currentColor = false; - stop->specified_color = SPStop::readStopColor( p ); - } - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); - break; - } - case SP_PROP_STOP_OPACITY: { - { - gchar const *p = object->getStyleProperty( "stop-opacity", "1"); - gdouble opacity = sp_svg_read_percentage(p, stop->opacity); - stop->opacity = opacity; - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); - break; - } - case SP_ATTR_OFFSET: { - stop->offset = sp_svg_read_percentage(value, 0.0); - object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); - break; - } - case SP_PROP_STOP_PATH: { - if (value) { - stop->path_string = new Glib::ustring( value ); - //Geom::PathVector pv = sp_svg_read_pathv(value); - //SPCurve *curve = new SPCurve(pv); - //if( curve ) { - // std::cout << "Got Curve" << std::endl; - //curve->unref(); - //} - } - break; - } - default: { - if (((SPObjectClass *) sp_stop_parent_class)->set) - (* ((SPObjectClass *) sp_stop_parent_class)->set)(object, key, value); - break; - } - } -} - -/** - * Virtual write: write object attributes to repr. - */ -static Inkscape::XML::Node * -sp_stop_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) -{ - SPStop *stop = SP_STOP(object); - - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:stop"); - } - - Glib::ustring colorStr = stop->specified_color.toString(); - gfloat opacity = stop->opacity; - - if (((SPObjectClass *) sp_stop_parent_class)->write) { - (* ((SPObjectClass *) sp_stop_parent_class)->write)(object, xml_doc, repr, flags); - } - - // Since we do a hackish style setting here (because SPStyle does not support stop-color and - // stop-opacity), we must do it AFTER calling the parent write method; otherwise - // sp_object_write would clear our style= attribute (bug 1695287) - - Inkscape::CSSOStringStream os; - os << "stop-color:"; - if (stop->currentColor) { - os << "currentColor"; - } else { - os << colorStr; - } - os << ";stop-opacity:" << opacity; - repr->setAttribute("style", os.str().c_str()); - repr->setAttribute("stop-color", NULL); - repr->setAttribute("stop-opacity", NULL); - sp_repr_set_css_double(repr, "offset", stop->offset); - /* strictly speaking, offset an SVG <number> rather than a CSS one, but exponents make no sense - * for offset proportions. */ - - return repr; -} - - bool SPGradient::hasStops() const { return has_stops; @@ -344,396 +136,196 @@ gboolean SPGradient::isEquivalent(SPGradient *that) } -/** - * Return stop's color as 32bit value. - */ -guint32 -sp_stop_get_rgba32(SPStop const *const stop) -{ - guint32 rgb0 = 0; - /* Default value: arbitrarily black. (SVG1.1 and CSS2 both say that the initial - * value depends on user agent, and don't give any further restrictions that I can - * see.) */ - if (stop->currentColor) { - char const *str = stop->getStyleProperty( "color", NULL); - if (str) { - rgb0 = sp_svg_read_color(str, rgb0); - } - unsigned const alpha = static_cast<unsigned>(stop->opacity * 0xff + 0.5); - g_return_val_if_fail((alpha & ~0xff) == 0, - rgb0 | 0xff); - return rgb0 | alpha; - } else { - return stop->specified_color.toRGBA32( stop->opacity ); - } -} - -/* - * Mesh Row - */ - -/** - * Callback to initialize SPMeshRow vtable. - */ -static void sp_meshrow_class_init(SPMeshRowClass *klass) -{ - SPObjectClass *sp_object_class = (SPObjectClass *) klass; - - sp_object_class->build = sp_meshrow_build; - sp_object_class->set = sp_meshrow_set; - sp_object_class->write = sp_meshrow_write; -} - -/** - * Callback to initialize SPMeshRow object. - */ -static void sp_meshrow_init(SPMeshRow * /*meshrow*/) -{ - // Do nothing -} - -/** - * Virtual build: set meshrow attributes from its associated XML node. - */ -static void sp_meshrow_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) -{ - if (((SPObjectClass *) sp_meshrow_parent_class)->build) - (* ((SPObjectClass *) sp_meshrow_parent_class)->build)(object, document, repr); - - // No attributes -} - -/** - * Virtual set: set attribute to value. - */ -static void sp_meshrow_set(SPObject * /*object*/, unsigned /*key*/, gchar const * /*value*/) -{ - // Do nothing -} - -/** - * Virtual write: write object attributes to repr. - */ -static Inkscape::XML::Node * -sp_meshrow_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) -{ - //SPMeshRow *meshrow = SP_MESHROW(object); - - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:meshRow"); - } - - if (((SPObjectClass *) sp_meshrow_parent_class)->write) { - (* ((SPObjectClass *) sp_meshrow_parent_class)->write)(object, xml_doc, repr, flags); - } - - return repr; -} - -/* - * Mesh Patch - */ - -/** - * Callback to initialize SPMeshPatch vtable. - */ -static void sp_meshpatch_class_init(SPMeshPatchClass *klass) -{ - SPObjectClass *sp_object_class = (SPObjectClass *) klass; - - sp_object_class->build = sp_meshpatch_build; - sp_object_class->set = sp_meshpatch_set; - sp_object_class->write = sp_meshpatch_write; -} - -/** - * Callback to initialize SPMeshPatch object. - */ -static void sp_meshpatch_init(SPMeshPatch * /*meshpatch*/) -{ - // Do nothing -} - -/** - * Virtual build: set meshpatch attributes from its associated XML node. - */ -static void sp_meshpatch_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) -{ - if (((SPObjectClass *) sp_meshpatch_parent_class)->build) - (* ((SPObjectClass *) sp_meshpatch_parent_class)->build)(object, document, repr); - - object->readAttr( "tensor" ); -} - -/** - * Virtual set: set attribute to value. - */ -static void -sp_meshpatch_set(SPObject *object, unsigned key, gchar const *value) -{ - SPMeshPatch *patch = SP_MESHPATCH(object); - - switch (key) { - case SP_ATTR_TENSOR: { - if (value) { - patch->tensor_string = new Glib::ustring( value ); - // std::cout << "sp_meshpatch_set: Tensor string: " << patch->tensor_string->c_str() << std::endl; - } - break; - } - default: { - // Do nothing - } - } -} - -/** - * Virtual write: write object attributes to repr. - */ -static Inkscape::XML::Node * -sp_meshpatch_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) -{ - //SPMeshPatch *meshpatch = SP_MESHPATCH(object); - - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:meshPatch"); - } - - if (((SPObjectClass *) sp_meshpatch_parent_class)->write) { - (* ((SPObjectClass *) sp_meshpatch_parent_class)->write)(object, xml_doc, repr, flags); - } - - return repr; -} - - /* * Gradient */ +SPGradient::SPGradient() : SPPaintServer(), units(), + spread(), + ref(NULL), + state(2), + vector() { -static SPPaintServerClass *gradient_parent_class; - -/** - * Registers SPGradient class and returns its type. - */ -GType SPGradient::getType() -{ - static GType gradient_type = 0; - if (!gradient_type) { - - GTypeInfo gradient_info = { - sizeof(SPGradientClass), - NULL, NULL, - (GClassInitFunc) SPGradientImpl::classInit, - NULL, NULL, - sizeof(SPGradient), - 16, - (GInstanceInitFunc) SPGradientImpl::init, - NULL, /* value_table */ - }; - gradient_type = g_type_register_static(SP_TYPE_PAINT_SERVER, "SPGradient", - &gradient_info, (GTypeFlags)0); - } - return gradient_type; -} - -/** - * SPGradient vtable initialization. - */ -void SPGradientImpl::classInit(SPGradientClass *klass) -{ - SPObjectClass *sp_object_class = (SPObjectClass *) klass; - - gradient_parent_class = (SPPaintServerClass *)g_type_class_ref(SP_TYPE_PAINT_SERVER); - - sp_object_class->build = SPGradientImpl::build; - sp_object_class->release = SPGradientImpl::release; - sp_object_class->set = SPGradientImpl::setGradientAttr; - sp_object_class->child_added = SPGradientImpl::childAdded; - sp_object_class->remove_child = SPGradientImpl::removeChild; - sp_object_class->modified = SPGradientImpl::modified; - sp_object_class->write = SPGradientImpl::write; -} + this->has_patches = 0; -/** - * Callback for SPGradient object initialization. - */ -void SPGradientImpl::init(SPGradient *gr) -{ - gr->ref = new SPGradientReference(gr); - gr->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(SPGradientImpl::gradientRefChanged), gr)); + this->ref = new SPGradientReference(this); + this->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(SPGradient::gradientRefChanged), this)); /** \todo * Fixme: reprs being rearranged (e.g. via the XML editor) * may require us to clear the state. */ - gr->state = SP_GRADIENT_STATE_UNKNOWN; + this->state = SP_GRADIENT_STATE_UNKNOWN; - gr->units = SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX; - gr->units_set = FALSE; + this->units = SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX; + this->units_set = FALSE; - gr->gradientTransform = Geom::identity(); - gr->gradientTransform_set = FALSE; + this->gradientTransform = Geom::identity(); + this->gradientTransform_set = FALSE; - gr->spread = SP_GRADIENT_SPREAD_PAD; - gr->spread_set = FALSE; + this->spread = SP_GRADIENT_SPREAD_PAD; + this->spread_set = FALSE; - gr->has_stops = FALSE; + this->has_stops = FALSE; - gr->vector.built = false; - gr->vector.stops.clear(); + this->vector.built = false; + this->vector.stops.clear(); + + //new (&this->modified_connection) sigc::connection(); +} - new (&gr->modified_connection) sigc::connection(); +SPGradient::~SPGradient() { } /** * Virtual build: set gradient attributes from its associated repr. */ -void SPGradientImpl::build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +void SPGradient::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPGradient *gradient = SP_GRADIENT(object); - // Work-around in case a swatch had been marked for immediate collection: if ( repr->attribute("osb:paint") && repr->attribute("inkscape:collect") ) { repr->setAttribute("inkscape:collect", 0); } - if (((SPObjectClass *) gradient_parent_class)->build) { - (* ((SPObjectClass *) gradient_parent_class)->build)(object, document, repr); - } + SPPaintServer::build(document, repr); - for ( SPObject *ochild = object->firstChild() ; ochild ; ochild = ochild->getNext() ) { + for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { if (SP_IS_STOP(ochild)) { - gradient->has_stops = TRUE; + this->has_stops = TRUE; break; } } - object->readAttr( "gradientUnits" ); - object->readAttr( "gradientTransform" ); - object->readAttr( "spreadMethod" ); - object->readAttr( "xlink:href" ); - object->readAttr( "osb:paint" ); + this->readAttr( "gradientUnits" ); + this->readAttr( "gradientTransform" ); + this->readAttr( "spreadMethod" ); + this->readAttr( "xlink:href" ); + this->readAttr( "osb:paint" ); // Register ourselves - document->addResource("gradient", object); + document->addResource("gradient", this); } /** * Virtual release of SPGradient members before destruction. */ -void SPGradientImpl::release(SPObject *object) +void SPGradient::release() { - SPGradient *gradient = (SPGradient *) object; #ifdef SP_GRADIENT_VERBOSE - g_print("Releasing gradient %s\n", object->getId()); + g_print("Releasing this %s\n", this->getId()); #endif - if (object->document) { + if (this->document) { // Unregister ourselves - object->document->removeResource("gradient", object); + this->document->removeResource("gradient", this); } - if (gradient->ref) { - gradient->modified_connection.disconnect(); - gradient->ref->detach(); - delete gradient->ref; - gradient->ref = NULL; + if (this->ref) { + this->modified_connection.disconnect(); + this->ref->detach(); + delete this->ref; + this->ref = NULL; } - gradient->modified_connection.~connection(); + //this->modified_connection.~connection(); - if (((SPObjectClass *) gradient_parent_class)->release) - ((SPObjectClass *) gradient_parent_class)->release(object); + SPPaintServer::release(); } /** * Set gradient attribute to value. */ -void SPGradientImpl::setGradientAttr(SPObject *object, unsigned key, gchar const *value) +void SPGradient::set(unsigned key, gchar const *value) { - SPGradient *gr = SP_GRADIENT(object); - switch (key) { case SP_ATTR_GRADIENTUNITS: if (value) { if (!strcmp(value, "userSpaceOnUse")) { - gr->units = SP_GRADIENT_UNITS_USERSPACEONUSE; + this->units = SP_GRADIENT_UNITS_USERSPACEONUSE; } else { - gr->units = SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX; + this->units = SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX; } - gr->units_set = TRUE; + + this->units_set = TRUE; } else { - gr->units = SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX; - gr->units_set = FALSE; + this->units = SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX; + this->units_set = FALSE; } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_GRADIENTTRANSFORM: { Geom::Affine t; if (value && sp_svg_transform_read(value, &t)) { - gr->gradientTransform = t; - gr->gradientTransform_set = TRUE; + this->gradientTransform = t; + this->gradientTransform_set = TRUE; } else { - gr->gradientTransform = Geom::identity(); - gr->gradientTransform_set = FALSE; + this->gradientTransform = Geom::identity(); + this->gradientTransform_set = FALSE; } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; } case SP_ATTR_SPREADMETHOD: if (value) { if (!strcmp(value, "reflect")) { - gr->spread = SP_GRADIENT_SPREAD_REFLECT; + this->spread = SP_GRADIENT_SPREAD_REFLECT; } else if (!strcmp(value, "repeat")) { - gr->spread = SP_GRADIENT_SPREAD_REPEAT; + this->spread = SP_GRADIENT_SPREAD_REPEAT; } else { - gr->spread = SP_GRADIENT_SPREAD_PAD; + this->spread = SP_GRADIENT_SPREAD_PAD; } - gr->spread_set = TRUE; + + this->spread_set = TRUE; } else { - gr->spread_set = FALSE; + this->spread_set = FALSE; } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_XLINK_HREF: if (value) { try { - gr->ref->attach(Inkscape::URI(value)); + this->ref->attach(Inkscape::URI(value)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); - gr->ref->detach(); + this->ref->detach(); } } else { - gr->ref->detach(); + this->ref->detach(); } break; + case SP_ATTR_OSB_SWATCH: { bool newVal = (value != 0); bool modified = false; - if (newVal != gr->swatch) { - gr->swatch = newVal; + + if (newVal != this->swatch) { + this->swatch = newVal; modified = true; } + if (newVal) { // Might need to flip solid/gradient - Glib::ustring paintVal = ( gr->hasStops() && (gr->getStopCount() == 0) ) ? "solid" : "gradient"; + Glib::ustring paintVal = ( this->hasStops() && (this->getStopCount() == 0) ) ? "solid" : "gradient"; + if ( paintVal != value ) { - gr->setAttribute( "osb:paint", paintVal.c_str(), 0 ); + this->setAttribute( "osb:paint", paintVal.c_str(), 0 ); modified = true; } } + if (modified) { - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); } } break; default: - if (((SPObjectClass *) gradient_parent_class)->set) { - ((SPObjectClass *) gradient_parent_class)->set(object, key, value); - } + SPPaintServer::set(key, value); break; } } @@ -741,7 +333,7 @@ void SPGradientImpl::setGradientAttr(SPObject *object, unsigned key, gchar const /** * Gets called when the gradient is (re)attached to another gradient. */ -void SPGradientImpl::gradientRefChanged(SPObject *old_ref, SPObject *ref, SPGradient *gr) +void SPGradient::gradientRefChanged(SPObject *old_ref, SPObject *ref, SPGradient *gr) { if (old_ref) { gr->modified_connection.disconnect(); @@ -749,7 +341,7 @@ void SPGradientImpl::gradientRefChanged(SPObject *old_ref, SPObject *ref, SPGrad if ( SP_IS_GRADIENT(ref) && ref != gr ) { - gr->modified_connection = ref->connectModified(sigc::bind<2>(sigc::ptr_fun(&SPGradientImpl::gradientRefModified), gr)); + gr->modified_connection = ref->connectModified(sigc::bind<2>(sigc::ptr_fun(&SPGradient::gradientRefModified), gr)); } // Per SVG, all unset attributes must be inherited from linked gradient. @@ -770,83 +362,78 @@ void SPGradientImpl::gradientRefChanged(SPObject *old_ref, SPObject *ref, SPGrad /** * Callback for child_added event. */ -void SPGradientImpl::childAdded(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +void SPGradient::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) { - SPGradient *gr = SP_GRADIENT(object); - - gr->invalidateVector(); + this->invalidateVector(); - if (((SPObjectClass *) gradient_parent_class)->child_added) { - (* ((SPObjectClass *) gradient_parent_class)->child_added)(object, child, ref); - } + SPPaintServer::child_added(child, ref); - SPObject *ochild = object->get_child_by_repr(child); + SPObject *ochild = this->get_child_by_repr(child); if ( ochild && SP_IS_STOP(ochild) ) { - gr->has_stops = TRUE; - if ( gr->getStopCount() > 0 ) { - gchar const * attr = gr->getAttribute("osb:paint"); + this->has_stops = TRUE; + if ( this->getStopCount() > 0 ) { + gchar const * attr = this->getAttribute("osb:paint"); if ( attr && strcmp(attr, "gradient") ) { - gr->setAttribute( "osb:paint", "gradient", 0 ); + this->setAttribute( "osb:paint", "gradient", 0 ); } } } /// \todo Fixme: should we schedule "modified" here? - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); } /** * Callback for remove_child event. */ -void SPGradientImpl::removeChild(SPObject *object, Inkscape::XML::Node *child) +void SPGradient::remove_child(Inkscape::XML::Node *child) { - SPGradient *gr = SP_GRADIENT(object); + this->invalidateVector(); - gr->invalidateVector(); + SPPaintServer::remove_child(child); - if (((SPObjectClass *) gradient_parent_class)->remove_child) { - (* ((SPObjectClass *) gradient_parent_class)->remove_child)(object, child); - } - - gr->has_stops = FALSE; - for ( SPObject *ochild = object->firstChild() ; ochild ; ochild = ochild->getNext() ) { + this->has_stops = FALSE; + for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { if (SP_IS_STOP(ochild)) { - gr->has_stops = TRUE; + this->has_stops = TRUE; break; } } - if ( gr->getStopCount() == 0 ) { - gchar const * attr = gr->getAttribute("osb:paint"); + if ( this->getStopCount() == 0 ) { + gchar const * attr = this->getAttribute("osb:paint"); + if ( attr && strcmp(attr, "solid") ) { - gr->setAttribute( "osb:paint", "solid", 0 ); + this->setAttribute( "osb:paint", "solid", 0 ); } } /* Fixme: should we schedule "modified" here? */ - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); } /** * Callback for modified event. */ -void SPGradientImpl::modified(SPObject *object, guint flags) +void SPGradient::modified(guint flags) { - SPGradient *gr = SP_GRADIENT(object); - if (flags & SP_OBJECT_CHILD_MODIFIED_FLAG) { - if( gr->get_type() != SP_GRADIENT_TYPE_MESH ) { - gr->invalidateVector(); + // CPPIFY + //if( this->get_type() != SP_GRADIENT_TYPE_MESH ) { + if (!SP_IS_MESHGRADIENT(this)) { + this->invalidateVector(); } else { - gr->invalidateArray(); + this->invalidateArray(); } } if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - if( gr->get_type() != SP_GRADIENT_TYPE_MESH ) { - gr->ensureVector(); + // CPPIFY + //if( this->get_type() != SP_GRADIENT_TYPE_MESH ) { + if (!SP_IS_MESHGRADIENT(this)) { + this->ensureVector(); } else { - gr->ensureArray(); + this->ensureArray(); } } @@ -855,18 +442,23 @@ void SPGradientImpl::modified(SPObject *object, guint flags) // FIXME: climb up the ladder of hrefs GSList *l = NULL; - for (SPObject *child = object->firstChild() ; child; child = child->getNext() ) { - g_object_ref(G_OBJECT(child)); + + for (SPObject *child = this->firstChild() ; child; child = child->getNext() ) { + sp_object_ref(child); l = g_slist_prepend(l, child); } + l = g_slist_reverse(l); + while (l) { SPObject *child = SP_OBJECT(l->data); l = g_slist_remove(l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { child->emitModified(flags); } - g_object_unref(G_OBJECT(child)); + + sp_object_unref(child); } } @@ -895,22 +487,21 @@ int SPGradient::getStopCount() const /** * Write gradient attributes to repr. */ -Inkscape::XML::Node *SPGradientImpl::write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +Inkscape::XML::Node *SPGradient::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - SPGradient *gr = SP_GRADIENT(object); - - if (((SPObjectClass *) gradient_parent_class)->write) { - (* ((SPObjectClass *) gradient_parent_class)->write)(object, xml_doc, repr, flags); - } + SPPaintServer::write(xml_doc, repr, flags); if (flags & SP_OBJECT_WRITE_BUILD) { GSList *l = NULL; - for (SPObject *child = object->firstChild(); child; child = child->getNext()) { + + for (SPObject *child = this->firstChild(); child; child = child->getNext()) { Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags); + if (crepr) { l = g_slist_prepend(l, crepr); } } + while (l) { repr->addChild((Inkscape::XML::Node *) l->data, NULL); Inkscape::GC::release((Inkscape::XML::Node *) l->data); @@ -918,14 +509,14 @@ Inkscape::XML::Node *SPGradientImpl::write(SPObject *object, Inkscape::XML::Docu } } - if (gr->ref->getURI()) { - gchar *uri_string = gr->ref->getURI()->toString(); + if (this->ref->getURI()) { + gchar *uri_string = this->ref->getURI()->toString(); repr->setAttribute("xlink:href", uri_string); g_free(uri_string); } - if ((flags & SP_OBJECT_WRITE_ALL) || gr->units_set) { - switch (gr->units) { + if ((flags & SP_OBJECT_WRITE_ALL) || this->units_set) { + switch (this->units) { case SP_GRADIENT_UNITS_USERSPACEONUSE: repr->setAttribute("gradientUnits", "userSpaceOnUse"); break; @@ -935,17 +526,17 @@ Inkscape::XML::Node *SPGradientImpl::write(SPObject *object, Inkscape::XML::Docu } } - if ((flags & SP_OBJECT_WRITE_ALL) || gr->gradientTransform_set) { - gchar *c=sp_svg_transform_write(gr->gradientTransform); + if ((flags & SP_OBJECT_WRITE_ALL) || this->gradientTransform_set) { + gchar *c=sp_svg_transform_write(this->gradientTransform); repr->setAttribute("gradientTransform", c); g_free(c); } - if ((flags & SP_OBJECT_WRITE_ALL) || gr->spread_set) { - /* FIXME: Ensure that gr->spread is the inherited value - * if !gr->spread_set. Not currently happening: see SPGradient::modified. + if ((flags & SP_OBJECT_WRITE_ALL) || this->spread_set) { + /* FIXME: Ensure that this->spread is the inherited value + * if !this->spread_set. Not currently happening: see SPGradient::modified. */ - switch (gr->spread) { + switch (this->spread) { case SP_GRADIENT_SPREAD_REFLECT: repr->setAttribute("spreadMethod", "reflect"); break; @@ -958,8 +549,8 @@ Inkscape::XML::Node *SPGradientImpl::write(SPObject *object, Inkscape::XML::Docu } } - if ( (flags & SP_OBJECT_WRITE_EXT) && gr->isSwatch() ) { - if ( gr->isSolid() ) { + if ( (flags & SP_OBJECT_WRITE_EXT) && this->isSwatch() ) { + if ( this->isSolid() ) { repr->setAttribute( "osb:paint", "solid" ); } else { repr->setAttribute( "osb:paint", "gradient" ); @@ -1191,7 +782,7 @@ sp_gradient_repr_write_vector(SPGradient *gr) } -void SPGradientImpl::gradientRefModified(SPObject */*href*/, guint /*flags*/, SPGradient *gradient) +void SPGradient::gradientRefModified(SPObject */*href*/, guint /*flags*/, SPGradient *gradient) { if ( gradient->invalidateVector() ) { gradient->requestModified(SP_OBJECT_MODIFIED_FLAG); @@ -1405,424 +996,12 @@ sp_gradient_set_gs2d_matrix(SPGradient *gr, Geom::Affine const &ctm, gr->requestModified(SP_OBJECT_MODIFIED_FLAG); } -/* - * Linear Gradient - */ -static void sp_lineargradient_build(SPObject *object, - SPDocument *document, - Inkscape::XML::Node *repr); -static void sp_lineargradient_set(SPObject *object, unsigned key, gchar const *value); -static Inkscape::XML::Node *sp_lineargradient_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, - guint flags); -static cairo_pattern_t *sp_lineargradient_create_pattern(SPPaintServer *ps, cairo_t *ct, Geom::OptRect const &bbox, double opacity); -G_DEFINE_TYPE(SPLinearGradient, sp_lineargradient, SP_TYPE_GRADIENT); -/** - * SPLinearGradient vtable initialization. - */ -static void sp_lineargradient_class_init(SPLinearGradientClass *klass) -{ - SPObjectClass *sp_object_class = (SPObjectClass *) klass; - SPPaintServerClass *ps_class = (SPPaintServerClass *) klass; - - sp_object_class->build = sp_lineargradient_build; - sp_object_class->set = sp_lineargradient_set; - sp_object_class->write = sp_lineargradient_write; - - ps_class->pattern_new = sp_lineargradient_create_pattern; -} - -/** - * Callback for SPLinearGradient object initialization. - */ -static void sp_lineargradient_init(SPLinearGradient *lg) -{ - lg->x1.unset(SVGLength::PERCENT, 0.0, 0.0); - lg->y1.unset(SVGLength::PERCENT, 0.0, 0.0); - lg->x2.unset(SVGLength::PERCENT, 1.0, 1.0); - lg->y2.unset(SVGLength::PERCENT, 0.0, 0.0); -} - -/** - * Callback: set attributes from associated repr. - */ -static void sp_lineargradient_build(SPObject *object, - SPDocument *document, - Inkscape::XML::Node *repr) -{ - if (((SPObjectClass *) sp_lineargradient_parent_class)->build) - (* ((SPObjectClass *) sp_lineargradient_parent_class)->build)(object, document, repr); - - object->readAttr( "x1" ); - object->readAttr( "y1" ); - object->readAttr( "x2" ); - object->readAttr( "y2" ); -} - -/** - * Callback: set attribute. - */ -static void -sp_lineargradient_set(SPObject *object, unsigned key, gchar const *value) -{ - SPLinearGradient *lg = SP_LINEARGRADIENT(object); - - switch (key) { - case SP_ATTR_X1: - lg->x1.readOrUnset(value, SVGLength::PERCENT, 0.0, 0.0); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_Y1: - lg->y1.readOrUnset(value, SVGLength::PERCENT, 0.0, 0.0); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_X2: - lg->x2.readOrUnset(value, SVGLength::PERCENT, 1.0, 1.0); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_Y2: - lg->y2.readOrUnset(value, SVGLength::PERCENT, 0.0, 0.0); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - default: - if (((SPObjectClass *) sp_lineargradient_parent_class)->set) - (* ((SPObjectClass *) sp_lineargradient_parent_class)->set)(object, key, value); - break; - } -} - -/** - * Callback: write attributes to associated repr. - */ -static Inkscape::XML::Node * -sp_lineargradient_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) -{ - SPLinearGradient *lg = SP_LINEARGRADIENT(object); - - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:linearGradient"); - } - - if ((flags & SP_OBJECT_WRITE_ALL) || lg->x1._set) - sp_repr_set_svg_double(repr, "x1", lg->x1.computed); - if ((flags & SP_OBJECT_WRITE_ALL) || lg->y1._set) - sp_repr_set_svg_double(repr, "y1", lg->y1.computed); - if ((flags & SP_OBJECT_WRITE_ALL) || lg->x2._set) - sp_repr_set_svg_double(repr, "x2", lg->x2.computed); - if ((flags & SP_OBJECT_WRITE_ALL) || lg->y2._set) - sp_repr_set_svg_double(repr, "y2", lg->y2.computed); - - if (((SPObjectClass *) sp_lineargradient_parent_class)->write) - (* ((SPObjectClass *) sp_lineargradient_parent_class)->write)(object, xml_doc, repr, flags); - - return repr; -} - -/** - * Directly set properties of linear gradient and request modified. - */ -void -sp_lineargradient_set_position(SPLinearGradient *lg, - gdouble x1, gdouble y1, - gdouble x2, gdouble y2) -{ - g_return_if_fail(lg != NULL); - g_return_if_fail(SP_IS_LINEARGRADIENT(lg)); - - /* fixme: units? (Lauris) */ - lg->x1.set(SVGLength::NONE, x1, x1); - lg->y1.set(SVGLength::NONE, y1, y1); - lg->x2.set(SVGLength::NONE, x2, x2); - lg->y2.set(SVGLength::NONE, y2, y2); - - lg->requestModified(SP_OBJECT_MODIFIED_FLAG); -} - -/* - * Radial Gradient - */ - -static void sp_radialgradient_build(SPObject *object, - SPDocument *document, - Inkscape::XML::Node *repr); -static void sp_radialgradient_set(SPObject *object, unsigned key, gchar const *value); -static Inkscape::XML::Node *sp_radialgradient_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, - guint flags); -static cairo_pattern_t *sp_radialgradient_create_pattern(SPPaintServer *ps, cairo_t *ct, Geom::OptRect const &bbox, double opacity); -G_DEFINE_TYPE(SPRadialGradient, sp_radialgradient, SP_TYPE_GRADIENT); - -/** - * SPRadialGradient vtable initialization. - */ -static void sp_radialgradient_class_init(SPRadialGradientClass *klass) -{ - SPObjectClass *sp_object_class = (SPObjectClass *) klass; - SPPaintServerClass *ps_class = (SPPaintServerClass *) klass; - - sp_object_class->build = sp_radialgradient_build; - sp_object_class->set = sp_radialgradient_set; - sp_object_class->write = sp_radialgradient_write; - - ps_class->pattern_new = sp_radialgradient_create_pattern; -} - -/** - * Callback for SPRadialGradient object initialization. - */ -static void -sp_radialgradient_init(SPRadialGradient *rg) -{ - rg->cx.unset(SVGLength::PERCENT, 0.5, 0.5); - rg->cy.unset(SVGLength::PERCENT, 0.5, 0.5); - rg->r.unset(SVGLength::PERCENT, 0.5, 0.5); - rg->fx.unset(SVGLength::PERCENT, 0.5, 0.5); - rg->fy.unset(SVGLength::PERCENT, 0.5, 0.5); -} - -/** - * Set radial gradient attributes from associated repr. - */ -static void -sp_radialgradient_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) -{ - if (((SPObjectClass *) sp_radialgradient_parent_class)->build) - (* ((SPObjectClass *) sp_radialgradient_parent_class)->build)(object, document, repr); - - object->readAttr( "cx" ); - object->readAttr( "cy" ); - object->readAttr( "r" ); - object->readAttr( "fx" ); - object->readAttr( "fy" ); -} - -/** - * Set radial gradient attribute. - */ -static void -sp_radialgradient_set(SPObject *object, unsigned key, gchar const *value) -{ - SPRadialGradient *rg = SP_RADIALGRADIENT(object); - - switch (key) { - case SP_ATTR_CX: - if (!rg->cx.read(value)) { - rg->cx.unset(SVGLength::PERCENT, 0.5, 0.5); - } - if (!rg->fx._set) { - rg->fx.value = rg->cx.value; - rg->fx.computed = rg->cx.computed; - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_CY: - if (!rg->cy.read(value)) { - rg->cy.unset(SVGLength::PERCENT, 0.5, 0.5); - } - if (!rg->fy._set) { - rg->fy.value = rg->cy.value; - rg->fy.computed = rg->cy.computed; - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_R: - if (!rg->r.read(value)) { - rg->r.unset(SVGLength::PERCENT, 0.5, 0.5); - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_FX: - if (!rg->fx.read(value)) { - rg->fx.unset(rg->cx.unit, rg->cx.value, rg->cx.computed); - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_FY: - if (!rg->fy.read(value)) { - rg->fy.unset(rg->cy.unit, rg->cy.value, rg->cy.computed); - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - default: - if (((SPObjectClass *) sp_radialgradient_parent_class)->set) - ((SPObjectClass *) sp_radialgradient_parent_class)->set(object, key, value); - break; - } -} - -/** - * Write radial gradient attributes to associated repr. - */ -static Inkscape::XML::Node * -sp_radialgradient_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) -{ - SPRadialGradient *rg = SP_RADIALGRADIENT(object); - - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:radialGradient"); - } - - if ((flags & SP_OBJECT_WRITE_ALL) || rg->cx._set) sp_repr_set_svg_double(repr, "cx", rg->cx.computed); - if ((flags & SP_OBJECT_WRITE_ALL) || rg->cy._set) sp_repr_set_svg_double(repr, "cy", rg->cy.computed); - if ((flags & SP_OBJECT_WRITE_ALL) || rg->r._set) sp_repr_set_svg_double(repr, "r", rg->r.computed); - if ((flags & SP_OBJECT_WRITE_ALL) || rg->fx._set) sp_repr_set_svg_double(repr, "fx", rg->fx.computed); - if ((flags & SP_OBJECT_WRITE_ALL) || rg->fy._set) sp_repr_set_svg_double(repr, "fy", rg->fy.computed); - - if (((SPObjectClass *) sp_radialgradient_parent_class)->write) - (* ((SPObjectClass *) sp_radialgradient_parent_class)->write)(object, xml_doc, repr, flags); - - return repr; -} - -/** - * Directly set properties of radial gradient and request modified. - */ -void -sp_radialgradient_set_position(SPRadialGradient *rg, - gdouble cx, gdouble cy, gdouble fx, gdouble fy, gdouble r) -{ - g_return_if_fail(rg != NULL); - g_return_if_fail(SP_IS_RADIALGRADIENT(rg)); - - /* fixme: units? (Lauris) */ - rg->cx.set(SVGLength::NONE, cx, cx); - rg->cy.set(SVGLength::NONE, cy, cy); - rg->fx.set(SVGLength::NONE, fx, fx); - rg->fy.set(SVGLength::NONE, fy, fy); - rg->r.set(SVGLength::NONE, r, r); - - rg->requestModified(SP_OBJECT_MODIFIED_FLAG); -} - -/* - * Mesh Gradient - */ - -//#define MESH_DEBUG - -static void sp_meshgradient_build(SPObject *object, - SPDocument *document, - Inkscape::XML::Node *repr); -static void sp_meshgradient_set(SPObject *object, unsigned key, gchar const *value); -static Inkscape::XML::Node *sp_meshgradient_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, - guint flags); -static cairo_pattern_t *sp_meshgradient_create_pattern(SPPaintServer *ps, cairo_t *ct, Geom::OptRect const &bbox, double opacity); -G_DEFINE_TYPE(SPMeshGradient, sp_meshgradient, SP_TYPE_GRADIENT); - -/** - * SPMeshGradient vtable initialization. - */ -static void sp_meshgradient_class_init(SPMeshGradientClass *klass) -{ -#ifdef MESH_DEBUG - std::cout << "sp_meshgradient_class_init()" << std::endl; -#endif - SPObjectClass *sp_object_class = (SPObjectClass *) klass; - SPPaintServerClass *ps_class = (SPPaintServerClass *) klass; - - sp_object_class->build = sp_meshgradient_build; - sp_object_class->set = sp_meshgradient_set; - sp_object_class->write = sp_meshgradient_write; - - ps_class->pattern_new = sp_meshgradient_create_pattern; -} - -/** - * Callback for SPMeshGradient object initialization. - */ -static void -sp_meshgradient_init(SPMeshGradient *mg) -{ - // Start coordinate of mesh - mg->x.unset(SVGLength::NONE, 0.0, 0.0); - mg->y.unset(SVGLength::NONE, 0.0, 0.0); -} - -/** - * Set mesh gradient attributes from associated repr. - */ -static void -sp_meshgradient_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) -{ - if (((SPObjectClass *) sp_meshgradient_parent_class)->build) - (* ((SPObjectClass *) sp_meshgradient_parent_class)->build)(object, document, repr); - - // Start coordinate of mesh - object->readAttr( "x" ); - object->readAttr( "y" ); -} - -/** - * Set mesh gradient attribute. - */ -static void -sp_meshgradient_set(SPObject *object, unsigned key, gchar const *value) -{ - SPMeshGradient *mg = SP_MESHGRADIENT(object); - - switch (key) { - case SP_ATTR_X: - if (!mg->x.read(value)) { - mg->x.unset(SVGLength::NONE, 0.0, 0.0); - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_Y: - if (!mg->y.read(value)) { - mg->y.unset(SVGLength::NONE, 0.0, 0.0); - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - default: - if (((SPObjectClass *) sp_meshgradient_parent_class)->set) - ((SPObjectClass *) sp_meshgradient_parent_class)->set(object, key, value); - break; - } -} - -/** - * Write mesh gradient attributes to associated repr. - */ -static Inkscape::XML::Node * -sp_meshgradient_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) -{ - -#ifdef MESH_DEBUG - std::cout << "sp_meshgradient_write() ***************************" << std::endl; -#endif - SPMeshGradient *mg = SP_MESHGRADIENT(object); - - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:meshGradient"); - } - - if ((flags & SP_OBJECT_WRITE_ALL) || mg->x._set) sp_repr_set_svg_double(repr, "x", mg->x.computed); - if ((flags & SP_OBJECT_WRITE_ALL) || mg->y._set) sp_repr_set_svg_double(repr, "y", mg->y.computed); - - if (((SPObjectClass *) sp_meshgradient_parent_class)->write) - (* ((SPObjectClass *) sp_meshgradient_parent_class)->write)(object, xml_doc, repr, flags); - - return repr; -} - -/** - * Directly set properties of mesh gradient and request modified. - */ -void -sp_meshgradient_set_position(SPMeshGradient *mg, gdouble x, gdouble y) -{ - g_return_if_fail(mg != NULL); - g_return_if_fail(SP_IS_MESHGRADIENT(mg)); - - mg->x.set(SVGLength::NONE, x, x); - mg->y.set(SVGLength::NONE, y, y); - - mg->requestModified(SP_OBJECT_MODIFIED_FLAG); -} /* CAIRO RENDERING STUFF */ -static void +void sp_gradient_pattern_common_setup(cairo_pattern_t *cp, SPGradient *gr, Geom::OptRect const &bbox, @@ -1860,216 +1039,14 @@ sp_gradient_pattern_common_setup(cairo_pattern_t *cp, ink_cairo_pattern_set_matrix(cp, gs2user.inverse()); } -static cairo_pattern_t * -sp_radialgradient_create_pattern(SPPaintServer *ps, - cairo_t *ct, - Geom::OptRect const &bbox, - double opacity) -{ - SPRadialGradient *rg = SP_RADIALGRADIENT(ps); - SPGradient *gr = SP_GRADIENT(ps); - - gr->ensureVector(); - - Geom::Point focus(rg->fx.computed, rg->fy.computed); - Geom::Point center(rg->cx.computed, rg->cy.computed); - double radius = rg->r.computed; - double scale = 1.0; - double tolerance = cairo_get_tolerance(ct); - - // NOTE: SVG2 will allow the use of a focus circle which can - // have its center outside the first circle. - - // code below suggested by Cairo devs to overcome tolerance problems - // more: https://bugs.freedesktop.org/show_bug.cgi?id=40918 - - // Corrected for - // https://bugs.launchpad.net/inkscape/+bug/970355 - - Geom::Affine gs2user = gr->gradientTransform; - Geom::Scale gs2user_scale; - - if (gr->getUnits() == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX && bbox) { - Geom::Affine bbox2user(bbox->width(), 0, 0, bbox->height(), bbox->left(), bbox->top()); - gs2user *= bbox2user; - gs2user_scale = Geom::Scale( gs2user[0], gs2user[3] ); - } - - Geom::Point d = focus - center; - Geom::Point d_user = d * gs2user_scale; - Geom::Point r_user( radius, 0 ); - r_user *= gs2user_scale; - - if (d_user.length() + tolerance > r_user.length()) { - scale = r_user.length() / d_user.length(); - double dx = d_user.x(), dy = d_user.y(); - cairo_user_to_device_distance(ct, &dx, &dy); - if (!Geom::are_near(dx, 0, tolerance) || - !Geom::are_near(dy, 0, tolerance)) - { - scale *= 1.0 - 2.0 * tolerance / hypot(dx, dy); - } - } - - cairo_pattern_t *cp = cairo_pattern_create_radial( - scale * d.x() + center.x(), scale * d.y() + center.y(), 0, - center.x(), center.y(), radius); - - sp_gradient_pattern_common_setup(cp, gr, bbox, opacity); - - return cp; -} - -static cairo_pattern_t *sp_meshgradient_create_pattern(SPPaintServer *ps, - cairo_t * /* ct */, -#if defined(MESH_DEBUG) || (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 4)) - Geom::OptRect const &bbox, - double opacity -#else - Geom::OptRect const & /*bbox*/, - double /*opacity*/ -#endif - ) -{ - using Geom::X; - using Geom::Y; - -#ifdef MESH_DEBUG - std::cout << "sp_meshgradient_create_pattern: (" << bbox->x0 << "," << bbox->y0 << ") (" << bbox->x1 << "," << bbox->y1 << ") " << opacity << std::endl; -#endif - //SPMeshGradient *mg = SP_MESHGRADIENT(ps); - SPGradient *gr = SP_GRADIENT(ps); - - gr->ensureArray(); - - cairo_pattern_t *cp = NULL; - -#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 4) - SPMeshNodeArray* array = &(gr->array); - - cp = cairo_pattern_create_mesh(); - - for( unsigned int i = 0; i < array->patch_rows(); ++i ) { - for( unsigned int j = 0; j < array->patch_columns(); ++j ) { - - SPMeshPatchI patch( &(array->nodes), i, j ); - - cairo_mesh_pattern_begin_patch( cp ); - cairo_mesh_pattern_move_to( cp, patch.getPoint( 0, 0 )[X], patch.getPoint( 0, 0 )[Y] ); - - for( unsigned int k = 0; k < 4; ++k ) { -#ifdef DEBUG_MESH - std::cout << i << " " << j << " " - << patch.getPathType( k ) << " ("; - for( int p = 0; p < 4; ++p ) { - std::cout << patch.getPoint( k, p ); - } - std::cout << ") " - << patch.getColor( k ).toString() << std::endl; -#endif - - switch ( patch.getPathType( k ) ) { - case 'l': - case 'L': - case 'z': - case 'Z': - cairo_mesh_pattern_line_to( cp, - patch.getPoint( k, 3 )[X], - patch.getPoint( k, 3 )[Y] ); - break; - case 'c': - case 'C': - { - std::vector< Geom::Point > pts = patch.getPointsForSide( k ); - cairo_mesh_pattern_curve_to( cp, - pts[1][X], pts[1][Y], - pts[2][X], pts[2][Y], - pts[3][X], pts[3][Y] ); - break; - } - default: - // Shouldn't happen - std::cout << "sp_meshgradient_create_pattern: path error" << std::endl; - } - - if( patch.tensorIsSet(k) ) { - // Tensor point defined relative to corner. - Geom::Point t = patch.getTensorPoint(k); - cairo_mesh_pattern_set_control_point( cp, k, t[X], t[Y] ); - //std::cout << " sp_meshgradient_create_pattern: tensor " << k - // << " set to " << t << "." << std::endl; - } else { - // Geom::Point t = patch.coonsTensorPoint(k); - //std::cout << " sp_meshgradient_create_pattern: tensor " << k - // << " calculated as " << t << "." <<std::endl; - } - - cairo_mesh_pattern_set_corner_color_rgba( - cp, k, - patch.getColor( k ).v.c[0], - patch.getColor( k ).v.c[1], - patch.getColor( k ).v.c[2], - patch.getOpacity( k ) * opacity ); - } - - cairo_mesh_pattern_end_patch( cp ); - } - } - - // set pattern matrix - Geom::Affine gs2user = gr->gradientTransform; - if (gr->getUnits() == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { - Geom::Affine bbox2user(bbox->width(), 0, 0, bbox->height(), bbox->left(), bbox->top()); - gs2user *= bbox2user; - } - ink_cairo_pattern_set_matrix(cp, gs2user.inverse()); - -#else - static bool shown = false; - if( !shown ) { - std::cout << "sp_meshgradient_create_pattern: needs cairo >= 1.11.4, using " - << cairo_version_string() << std::endl; - shown = true; - } -#endif - -/* - cairo_pattern_t *cp = cairo_pattern_create_radial( - rg->fx.computed, rg->fy.computed, 0, - rg->cx.computed, rg->cy.computed, rg->r.computed); - sp_gradient_pattern_common_setup(cp, gr, bbox, opacity); -*/ - - return cp; -} - -static cairo_pattern_t * -sp_lineargradient_create_pattern(SPPaintServer *ps, - cairo_t */* ct */, - Geom::OptRect const &bbox, - double opacity) -{ - SPLinearGradient *lg = SP_LINEARGRADIENT(ps); - SPGradient *gr = SP_GRADIENT(ps); - - gr->ensureVector(); - - cairo_pattern_t *cp = cairo_pattern_create_linear( - lg->x1.computed, lg->y1.computed, - lg->x2.computed, lg->y2.computed); - - sp_gradient_pattern_common_setup(cp, gr, bbox, opacity); - - return cp; -} - cairo_pattern_t * sp_gradient_create_preview_pattern(SPGradient *gr, double width) { cairo_pattern_t *pat = NULL; - if( gr->get_type() != SP_GRADIENT_TYPE_MESH ) { - + // CPPIFY + //if( gr->get_type() != SP_GRADIENT_TYPE_MESH ) { + if (!SP_IS_MESHGRADIENT(gr)) { gr->ensureVector(); pat = cairo_pattern_create_linear(0, 0, width, 0); @@ -2085,13 +1062,6 @@ sp_gradient_create_preview_pattern(SPGradient *gr, double width) return pat; } -void -sp_meshgradient_repr_write(SPMeshGradient *mg) -{ - mg->array.write( mg ); -} - - /* Local Variables: mode:c++ |
