summaryrefslogtreecommitdiffstats
path: root/src/sp-gradient.cpp
diff options
context:
space:
mode:
authorMarkus Engel <markus.engel@tum.de>2013-04-05 23:36:16 +0000
committerMarkus Engel <markus.engel@tum.de>2013-04-05 23:36:16 +0000
commitb0cc47554b385fb68643d07efe6e42366c7121ad (patch)
treebb7fb4babd001b1397386197d7e486187fd0db4d /src/sp-gradient.cpp
parentMerged Item. (diff)
downloadinkscape-b0cc47554b385fb68643d07efe6e42366c7121ad.tar.gz
inkscape-b0cc47554b385fb68643d07efe6e42366c7121ad.zip
Merged PaintServer and subclasses; moved Gradient classes to own files.
(bzr r11608.1.82)
Diffstat (limited to 'src/sp-gradient.cpp')
-rw-r--r--src/sp-gradient.cpp1333
1 files changed, 132 insertions, 1201 deletions
diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp
index 70e90f33c..530e5be40 100644
--- a/src/sp-gradient.cpp
+++ b/src/sp-gradient.cpp
@@ -60,231 +60,6 @@
/// Has to be power of 2 Seems to be unused.
//#define NCOLORS NR_GRADIENT_VECTOR_LENGTH
-#include "sp-factory.h"
-
-namespace {
- SPObject* createStop() {
- return new SPStop();
- }
-
- SPObject* createMeshRow() {
- return new SPMeshRow();
- }
-
- SPObject* createMeshPatch() {
- return new SPMeshPatch();
- }
-
- SPObject* createLinearGradient() {
- return new SPLinearGradient();
- }
-
- SPObject* createRadialGradient() {
- return new SPRadialGradient();
- }
-
- SPObject* createMeshGradient() {
- return new SPMeshGradient();
- }
-
- bool stopRegistered = SPFactory::instance().registerObject("svg:stop", createStop);
- bool meshRowRegistered = SPFactory::instance().registerObject("svg:meshRow", createMeshRow);
- bool meshPatchRegistered = SPFactory::instance().registerObject("svg:meshPatch", createMeshPatch);
- bool linearGradientRegistered = SPFactory::instance().registerObject("svg:linearGradient", createLinearGradient);
- bool radialGradientRegistered = SPFactory::instance().registerObject("svg:radialGradient", createRadialGradient);
- bool meshGradientRegistered = SPFactory::instance().registerObject("svg:meshGradient", createMeshGradient);
-}
-
-
-// SPStop
-G_DEFINE_TYPE(SPStop, sp_stop, G_TYPE_OBJECT);
-
-// SPMeshRow
-G_DEFINE_TYPE(SPMeshRow, sp_meshrow, G_TYPE_OBJECT);
-
-// SPMeshPatch
-G_DEFINE_TYPE(SPMeshPatch, sp_meshpatch, G_TYPE_OBJECT);
-
-
-/**
- * Callback to initialize SPStop vtable.
- */
-static void sp_stop_class_init(SPStopClass *klass)
-{
-}
-
-CStop::CStop(SPStop* stop) : CObject(stop) {
- this->spstop = stop;
-}
-
-CStop::~CStop() {
-}
-
-SPStop::SPStop() : SPObject() {
- SPStop* stop = this;
-
- stop->cstop = new CStop(stop);
- stop->typeHierarchy.insert(typeid(SPStop));
-
- delete stop->cobject;
- stop->cobject = stop->cstop;
-
- stop->path_string = NULL;
-
- stop->offset = 0.0;
- stop->currentColor = false;
- stop->specified_color.set( 0x000000ff );
- stop->opacity = 1.0;
-}
-
-/**
- * Callback to initialize SPStop object.
- */
-static void
-sp_stop_init(SPStop *stop)
-{
- new (stop) SPStop();
-}
-
-void CStop::build(SPDocument* doc, Inkscape::XML::Node* repr) {
- SPStop* object = this->spstop;
-
- CObject::build(doc, repr);
-
- object->readAttr( "offset" );
- object->readAttr( "stop-color" );
- object->readAttr( "stop-opacity" );
- object->readAttr( "style" );
- object->readAttr( "path" ); // For mesh
-}
-
-/**
- * Virtual build: set stop attributes from its associated XML node.
- */
-
-void CStop::set(unsigned int key, const gchar* value) {
- SPStop* object = this->spstop;
-
- 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: {
- CObject::set(key, value);
- break;
- }
- }
-}
-
-/**
- * Virtual set: set attribute to value.
- */
-
-Inkscape::XML::Node* CStop::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) {
- SPStop* object = this->spstop;
-
- 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;
-
- CObject::write(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;
-}
-
-/**
- * Virtual write: write object attributes to repr.
- */
-
bool SPGradient::hasStops() const
{
return has_stops;
@@ -361,425 +136,199 @@ 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)
-{
-}
-
-CMeshRow::CMeshRow(SPMeshRow* meshrow) : CObject(meshrow) {
- this->spmeshrow = meshrow;
-}
-
-CMeshRow::~CMeshRow() {
-}
-
-SPMeshRow::SPMeshRow() : SPObject() {
- SPMeshRow* meshrow = this;
-
- meshrow->cmeshrow = new CMeshRow(meshrow);
- meshrow->typeHierarchy.insert(typeid(SPMeshRow));
-
- delete meshrow->cobject;
- meshrow->cobject = meshrow->cmeshrow;
-}
-
-/**
- * Callback to initialize SPMeshRow object.
- */
-static void sp_meshrow_init(SPMeshRow * meshrow)
-{
- new (meshrow) SPMeshRow();
-}
-
-void CMeshRow::build(SPDocument* doc, Inkscape::XML::Node* repr) {
- CObject::build(doc, repr);
-}
-
-/**
- * Virtual build: set meshrow attributes from its associated XML node.
- */
-
-void CMeshRow::set(unsigned int key, const gchar* value) {
-}
-
-/**
- * Virtual set: set attribute to value.
- */
-
-Inkscape::XML::Node* CMeshRow::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) {
- if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
- repr = xml_doc->createElement("svg:meshRow");
- }
-
- CObject::write(xml_doc, repr, flags);
-
- return repr;
-}
-
-/**
- * Virtual write: write object attributes to repr.
- */
-
-/*
- * Mesh Patch
- */
-
-/**
- * Callback to initialize SPMeshPatch vtable.
- */
-static void sp_meshpatch_class_init(SPMeshPatchClass *klass)
-{
-}
-
-CMeshPatch::CMeshPatch(SPMeshPatch* meshpatch) : CObject(meshpatch) {
- this->spmeshpatch = meshpatch;
-}
-
-CMeshPatch::~CMeshPatch() {
-}
-
-SPMeshPatch::SPMeshPatch() : SPObject() {
- SPMeshPatch* meshpatch = this;
-
- meshpatch->cmeshpatch = new CMeshPatch(meshpatch);
- meshpatch->typeHierarchy.insert(typeid(SPMeshPatch));
-
- delete meshpatch->cobject;
- meshpatch->cobject = meshpatch->cmeshpatch;
-
- meshpatch->tensor_string = NULL;
-}
-
-/**
- * Callback to initialize SPMeshPatch object.
- */
-static void sp_meshpatch_init(SPMeshPatch * meshpatch)
-{
- new (meshpatch) SPMeshPatch();
-}
-
-void CMeshPatch::build(SPDocument* doc, Inkscape::XML::Node* repr) {
- SPMeshPatch* object = this->spmeshpatch;
-
- CObject::build(doc, repr);
-
- object->readAttr( "tensor" );
-}
-
-/**
- * Virtual build: set meshpatch attributes from its associated XML node.
- */
-
-void CMeshPatch::set(unsigned int key, const gchar* value) {
- SPMeshPatch* object = this->spmeshpatch;
-
- 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 set: set attribute to value.
- */
-
-Inkscape::XML::Node* CMeshPatch::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) {
- if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
- repr = xml_doc->createElement("svg:meshPatch");
- }
-
- CObject::write(xml_doc, repr, flags);
-
- return repr;
-}
-
-/**
- * Virtual write: write object attributes to repr.
- */
-
-
/*
* Gradient
*/
-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,
- 0, //(GClassInitFunc) CGradient::classInit,
- NULL, NULL,
- sizeof(SPGradient),
- 16,
- (GInstanceInitFunc) CGradient::init,
- NULL, /* value_table */
- };
- gradient_type = g_type_register_static(G_TYPE_OBJECT, "SPGradient",
- &gradient_info, (GTypeFlags)0);
- }
- return gradient_type;
-}
-
-/**
- * SPGradient vtable initialization.
- */
-void CGradient::classInit(SPGradientClass *klass)
-{
- gradient_parent_class = (SPPaintServerClass *)g_type_class_ref(SP_TYPE_PAINT_SERVER);
-}
-
-CGradient::CGradient(SPGradient* gradient) : CPaintServer(gradient) {
- this->spgradient = gradient;
-}
-
-CGradient::~CGradient() {
-}
-
-SPGradient::SPGradient() : SPPaintServer(), units(),
+SPGradient::SPGradient() : SPPaintServer(), units(),
spread(),
ref(NULL),
state(2),
vector() {
- SPGradient* gr = this;
-
- gr->cgradient = new CGradient(gr);
- gr->typeHierarchy.insert(typeid(SPGradient));
+ this->cobject = this;
- delete gr->cpaintserver;
- gr->cpaintserver = gr->cgradient;
- gr->cobject = gr->cgradient;
+ this->has_patches = 0;
- gr->has_patches = 0;
-
- gr->ref = new SPGradientReference(gr);
- gr->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(CGradient::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 (&gr->modified_connection) sigc::connection();
+ new (&this->modified_connection) sigc::connection();
}
-/**
- * Callback for SPGradient object initialization.
- */
-void CGradient::init(SPGradient *gr)
-{
- new (gr) SPGradient();
+SPGradient::~SPGradient() {
}
/**
* Virtual build: set gradient attributes from its associated repr.
*/
-void CGradient::build(SPDocument *document, Inkscape::XML::Node *repr)
+void SPGradient::build(SPDocument *document, Inkscape::XML::Node *repr)
{
- SPGradient* object = this->spgradient;
- 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);
}
- CPaintServer::build(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 CGradient::release()
+void SPGradient::release()
{
- SPGradient* object = this->spgradient;
- 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();
- CPaintServer::release();
+ SPPaintServer::release();
}
/**
* Set gradient attribute to value.
*/
-void CGradient::set(unsigned key, gchar const *value)
+void SPGradient::set(unsigned key, gchar const *value)
{
- SPGradient* object = this->spgradient;
- 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:
- CPaintServer::set(key, value);
+ SPPaintServer::set(key, value);
break;
}
}
@@ -787,7 +336,7 @@ void CGradient::set(unsigned key, gchar const *value)
/**
* Gets called when the gradient is (re)attached to another gradient.
*/
-void CGradient::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();
@@ -795,7 +344,7 @@ void CGradient::gradientRefChanged(SPObject *old_ref, SPObject *ref, SPGradient
if ( SP_IS_GRADIENT(ref)
&& ref != gr )
{
- gr->modified_connection = ref->connectModified(sigc::bind<2>(sigc::ptr_fun(&CGradient::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.
@@ -816,82 +365,74 @@ void CGradient::gradientRefChanged(SPObject *old_ref, SPObject *ref, SPGradient
/**
* Callback for child_added event.
*/
-void CGradient::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
+void SPGradient::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
{
- SPGradient* object = this->spgradient;
- SPGradient *gr = SP_GRADIENT(object);
-
- gr->invalidateVector();
+ this->invalidateVector();
- CPaintServer::child_added(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 CGradient::remove_child(Inkscape::XML::Node *child)
+void SPGradient::remove_child(Inkscape::XML::Node *child)
{
- SPGradient* object = this->spgradient;
- SPGradient *gr = SP_GRADIENT(object);
+ this->invalidateVector();
- gr->invalidateVector();
+ SPPaintServer::remove_child(child);
- CPaintServer::remove_child(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 CGradient::modified(guint flags)
+void SPGradient::modified(guint flags)
{
- SPGradient* object = this->spgradient;
- SPGradient *gr = SP_GRADIENT(object);
-
if (flags & SP_OBJECT_CHILD_MODIFIED_FLAG) {
- if( gr->get_type() != SP_GRADIENT_TYPE_MESH ) {
- gr->invalidateVector();
+ if( this->get_type() != SP_GRADIENT_TYPE_MESH ) {
+ this->invalidateVector();
} else {
- gr->invalidateArray();
+ this->invalidateArray();
}
}
if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) {
- if( gr->get_type() != SP_GRADIENT_TYPE_MESH ) {
- gr->ensureVector();
+ if( this->get_type() != SP_GRADIENT_TYPE_MESH ) {
+ this->ensureVector();
} else {
- gr->ensureArray();
+ this->ensureArray();
}
}
@@ -900,17 +441,22 @@ void CGradient::modified(guint flags)
// FIXME: climb up the ladder of hrefs
GSList *l = NULL;
- for (SPObject *child = object->firstChild() ; child; child = child->getNext() ) {
+
+ 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);
}
+
sp_object_unref(child);
}
}
@@ -940,21 +486,21 @@ int SPGradient::getStopCount() const
/**
* Write gradient attributes to repr.
*/
-Inkscape::XML::Node *CGradient::write(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* object = this->spgradient;
- SPGradient *gr = SP_GRADIENT(object);
-
- CPaintServer::write(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);
@@ -962,14 +508,14 @@ Inkscape::XML::Node *CGradient::write(Inkscape::XML::Document *xml_doc, Inkscape
}
}
- 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;
@@ -979,17 +525,17 @@ Inkscape::XML::Node *CGradient::write(Inkscape::XML::Document *xml_doc, Inkscape
}
}
- 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;
@@ -1002,8 +548,8 @@ Inkscape::XML::Node *CGradient::write(Inkscape::XML::Document *xml_doc, Inkscape
}
}
- 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" );
@@ -1235,7 +781,7 @@ sp_gradient_repr_write_vector(SPGradient *gr)
}
-void CGradient::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);
@@ -1449,422 +995,12 @@ sp_gradient_set_gs2d_matrix(SPGradient *gr, Geom::Affine const &ctm,
gr->requestModified(SP_OBJECT_MODIFIED_FLAG);
}
-/*
- * Linear Gradient
- */
-G_DEFINE_TYPE(SPLinearGradient, sp_lineargradient, G_TYPE_OBJECT);
-/**
- * SPLinearGradient vtable initialization.
- */
-static void sp_lineargradient_class_init(SPLinearGradientClass *klass)
-{
-}
-
-CLinearGradient::CLinearGradient(SPLinearGradient* lineargradient) : CGradient(lineargradient) {
- this->splineargradient = lineargradient;
-}
-
-CLinearGradient::~CLinearGradient() {
-}
-SPLinearGradient::SPLinearGradient() : SPGradient() {
- SPLinearGradient* lg = this;
-
- lg->clineargradient = new CLinearGradient(lg);
- lg->typeHierarchy.insert(typeid(SPLinearGradient));
-
- delete lg->cgradient;
- lg->cgradient = lg->clineargradient;
- lg->cpaintserver = lg->clineargradient;
- lg->cobject = lg->clineargradient;
-
- 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 for SPLinearGradient object initialization.
- */
-static void sp_lineargradient_init(SPLinearGradient *lg)
-{
- new (lg) SPLinearGradient();
-}
-
-void CLinearGradient::build(SPDocument *document, Inkscape::XML::Node *repr) {
- SPLinearGradient* object = this->splineargradient;
-
- CGradient::build(document, repr);
-
- object->readAttr( "x1" );
- object->readAttr( "y1" );
- object->readAttr( "x2" );
- object->readAttr( "y2" );
-}
-
-/**
- * Callback: set attribute.
- */
-void CLinearGradient::set(unsigned int key, const gchar* value) {
- SPLinearGradient* object = this->splineargradient;
-
- 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:
- CGradient::set(key, value);
- break;
- }
-}
-
-/**
- * Callback: write attributes to associated repr.
- */
-Inkscape::XML::Node* CLinearGradient::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
- SPLinearGradient* object = this->splineargradient;
-
- 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);
-
- CGradient::write(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
- */
-G_DEFINE_TYPE(SPRadialGradient, sp_radialgradient, G_TYPE_OBJECT);
-
-/**
- * SPRadialGradient vtable initialization.
- */
-static void sp_radialgradient_class_init(SPRadialGradientClass *klass)
-{
-}
-
-CRadialGradient::CRadialGradient(SPRadialGradient* radialgradient) : CGradient(radialgradient) {
- this->spradialgradient = radialgradient;
-}
-
-CRadialGradient::~CRadialGradient() {
-}
-
-SPRadialGradient::SPRadialGradient() : SPGradient() {
- SPRadialGradient* rg = this;
-
- rg->cradialgradient = new CRadialGradient(rg);
- rg->typeHierarchy.insert(typeid(SPRadialGradient));
-
- delete rg->cgradient;
- rg->cgradient = rg->cradialgradient;
- rg->cpaintserver = rg->cradialgradient;
- rg->cobject = rg->cradialgradient;
-
- 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);
-}
-
-/**
- * Callback for SPRadialGradient object initialization.
- */
-static void
-sp_radialgradient_init(SPRadialGradient *rg)
-{
- new (rg) SPRadialGradient();
-}
-
-/**
- * Set radial gradient attributes from associated repr.
- */
-void CRadialGradient::build(SPDocument *document, Inkscape::XML::Node *repr) {
- SPRadialGradient* object = this->spradialgradient;
-
- CGradient::build(document, repr);
-
- object->readAttr( "cx" );
- object->readAttr( "cy" );
- object->readAttr( "r" );
- object->readAttr( "fx" );
- object->readAttr( "fy" );
-}
-
-/**
- * Set radial gradient attribute.
- */
-void CRadialGradient::set(unsigned key, gchar const *value) {
- SPRadialGradient* object = this->spradialgradient;
-
- 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:
- CGradient::set(key, value);
- break;
- }
-}
-
-/**
- * Write radial gradient attributes to associated repr.
- */
-Inkscape::XML::Node* CRadialGradient::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
- SPRadialGradient* object = this->spradialgradient;
-
- 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);
-
- CGradient::write(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
-
-G_DEFINE_TYPE(SPMeshGradient, sp_meshgradient, G_TYPE_OBJECT);
-
-/**
- * SPMeshGradient vtable initialization.
- */
-static void sp_meshgradient_class_init(SPMeshGradientClass *klass)
-{
-#ifdef MESH_DEBUG
- std::cout << "sp_meshgradient_class_init()" << std::endl;
-#endif
-}
-
-CMeshGradient::CMeshGradient(SPMeshGradient* meshgradient) : CGradient(meshgradient) {
- this->spmeshgradient = meshgradient;
-}
-
-CMeshGradient::~CMeshGradient() {
-}
-
-SPMeshGradient::SPMeshGradient() : SPGradient() {
- SPMeshGradient* mg = this;
-
- mg->cmeshgradient = new CMeshGradient(mg);
- mg->typeHierarchy.insert(typeid(SPMeshGradient));
-
- delete mg->cgradient;
- mg->cgradient = mg->cmeshgradient;
- mg->cpaintserver = mg->cmeshgradient;
- mg->cobject = mg->cmeshgradient;
-
- // Start coordinate of mesh
- mg->x.unset(SVGLength::NONE, 0.0, 0.0);
- mg->y.unset(SVGLength::NONE, 0.0, 0.0);
-}
-
-/**
- * Callback for SPMeshGradient object initialization.
- */
-static void
-sp_meshgradient_init(SPMeshGradient *mg)
-{
- new (mg) SPMeshGradient();
-}
-
-void CMeshGradient::build(SPDocument *document, Inkscape::XML::Node *repr) {
- SPMeshGradient* object = this->spmeshgradient;
-
- CGradient::build(document, repr);
-
- // Start coordinate of mesh
- object->readAttr( "x" );
- object->readAttr( "y" );
-}
-
-
-void CMeshGradient::set(unsigned key, gchar const *value) {
- SPMeshGradient* object = this->spmeshgradient;
-
- 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:
- CGradient::set(key, value);
- break;
- }
-}
-
-/**
- * Write mesh gradient attributes to associated repr.
- */
-Inkscape::XML::Node* CMeshGradient::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
- SPMeshGradient* object = this->spmeshgradient;
-
-#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);
-
- CGradient::write(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,
@@ -1902,205 +1038,6 @@ sp_gradient_pattern_common_setup(cairo_pattern_t *cp,
ink_cairo_pattern_set_matrix(cp, gs2user.inverse());
}
-
-cairo_pattern_t* CRadialGradient::pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity) {
- SPRadialGradient* ps = this->spradialgradient;
-
- 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;
-}
-
-cairo_pattern_t* CMeshGradient::pattern_new(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;
-
- SPMeshGradient* ps = this->spmeshgradient;
-
-#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;
-}
-
-cairo_pattern_t* CLinearGradient::pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity) {
- SPLinearGradient* ps = this->splineargradient;
-
- 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)
{
@@ -2123,12 +1060,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++