summaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/Makefile_insert12
-rw-r--r--src/interface.cpp1
-rw-r--r--src/selection-chemistry.cpp4
-rw-r--r--src/sp-animation.cpp.THIS361
-rw-r--r--src/sp-animation.h.THIS129
-rw-r--r--src/sp-gradient-fns.h47
-rw-r--r--src/sp-gradient.cpp1333
-rw-r--r--src/sp-gradient.h64
-rw-r--r--src/sp-linear-gradient-fns.h40
-rw-r--r--src/sp-linear-gradient.cpp133
-rw-r--r--src/sp-linear-gradient.h21
-rw-r--r--src/sp-mesh-gradient-fns.h38
-rw-r--r--src/sp-mesh-gradient.cpp231
-rw-r--r--src/sp-mesh-gradient.h22
-rw-r--r--src/sp-mesh-patch-fns.h36
-rw-r--r--src/sp-mesh-patch.cpp77
-rw-r--r--src/sp-mesh-patch.h30
-rw-r--r--src/sp-mesh-row-fns.h36
-rw-r--r--src/sp-mesh-row.cpp53
-rw-r--r--src/sp-mesh-row.h30
-rw-r--r--src/sp-paint-server.cpp34
-rw-r--r--src/sp-paint-server.h27
-rw-r--r--src/sp-pattern.cpp300
-rw-r--r--src/sp-pattern.h24
-rw-r--r--src/sp-radial-gradient-fns.h39
-rw-r--r--src/sp-radial-gradient.cpp213
-rw-r--r--src/sp-radial-gradient.h22
-rw-r--r--src/sp-stop.cpp195
-rw-r--r--src/sp-stop.h27
-rw-r--r--src/ui/clipboard.cpp5
-rw-r--r--src/ui/dialog/swatches.cpp1
-rw-r--r--src/ui/widget/selected-style.cpp4
-rw-r--r--src/ui/widget/style-swatch.cpp4
-rw-r--r--src/widgets/gradient-image.cpp1
-rw-r--r--src/widgets/paint-selector.cpp4
35 files changed, 1262 insertions, 2336 deletions
diff --git a/src/Makefile_insert b/src/Makefile_insert
index ef076a242..5b4481a40 100644
--- a/src/Makefile_insert
+++ b/src/Makefile_insert
@@ -168,7 +168,6 @@ ink_common_sources += \
sp-glyph.cpp sp-glyph.h \
sp-glyph-kerning.cpp sp-glyph-kerning.h \
sp-gradient.cpp sp-gradient.h \
- sp-gradient-fns.h \
sp-gradient-reference.cpp sp-gradient-reference.h \
sp-gradient-spread.h \
sp-gradient-units.h \
@@ -184,8 +183,7 @@ ink_common_sources += \
sp-item-rm-unsatisfied-cns.cpp sp-item-rm-unsatisfied-cns.h \
sp-item-transform.cpp sp-item-transform.h \
sp-item-update-cns.cpp sp-item-update-cns.h \
- sp-linear-gradient-fns.h \
- sp-linear-gradient.h \
+ sp-linear-gradient.cpp sp-linear-gradient.h \
sp-line.cpp sp-line.h \
splivarot.cpp splivarot.h \
sp-lpe-item.cpp sp-lpe-item.h \
@@ -193,11 +191,8 @@ ink_common_sources += \
sp-mask.cpp sp-mask.h \
sp-metadata.cpp sp-metadata.h \
sp-mesh-array.cpp sp-mesh-array.h \
- sp-mesh-gradient-fns.h \
- sp-mesh-gradient.h \
- sp-mesh-patch-fns.h \
+ sp-mesh-gradient.cpp sp-mesh-gradient.h \
sp-mesh-patch.cpp sp-mesh-patch.h \
- sp-mesh-row-fns.h \
sp-mesh-row.cpp sp-mesh-row.h \
sp-metric.h \
sp-metrics.cpp sp-metrics.h \
@@ -213,8 +208,7 @@ ink_common_sources += \
sp-pattern.cpp sp-pattern.h \
sp-polygon.cpp sp-polygon.h \
sp-polyline.cpp sp-polyline.h \
- sp-radial-gradient-fns.h \
- sp-radial-gradient.h \
+ sp-radial-gradient.cpp sp-radial-gradient.h \
sp-rect.cpp sp-rect.h \
sp-root.cpp sp-root.h \
sp-script.cpp sp-script.h \
diff --git a/src/interface.cpp b/src/interface.cpp
index ab1e550a3..3f480d5e8 100644
--- a/src/interface.cpp
+++ b/src/interface.cpp
@@ -47,7 +47,6 @@
#include "widgets/desktop-widget.h"
#include "sp-item-group.h"
#include "sp-text.h"
-#include "sp-gradient-fns.h"
#include "sp-gradient.h"
#include "sp-flowtext.h"
#include "sp-namedview.h"
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 1827ea7ff..07a037557 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -69,10 +69,10 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS;
#include "document-undo.h"
#include "sp-gradient.h"
#include "sp-gradient-reference.h"
-#include "sp-linear-gradient-fns.h"
+#include "sp-linear-gradient.h"
#include "sp-pattern.h"
#include "sp-symbol.h"
-#include "sp-radial-gradient-fns.h"
+#include "sp-radial-gradient.h"
#include "gradient-context.h"
#include "sp-namedview.h"
#include "preferences.h"
diff --git a/src/sp-animation.cpp.THIS b/src/sp-animation.cpp.THIS
deleted file mode 100644
index f5e224ef1..000000000
--- a/src/sp-animation.cpp.THIS
+++ /dev/null
@@ -1,361 +0,0 @@
-/** \file
- * SVG <animate> implementation.
- *
- * N.B. This file is currently just a stub file with no meaningful implementation.
- */
-/*
- * Authors:
- * Lauris Kaplinski <lauris@kaplinski.com>
- * Abhishek Sharma
- *
- * Copyright (C) 2002 Lauris Kaplinski
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include "sp-animation.h"
-
-#if 0
-/* Feel free to remove this function and its calls. */
-static void log_set_attr(char const *const classname, unsigned int const key, char const *const value)
-{
- unsigned char const *const attr_name = sp_attribute_name(key);
- if (value) {
- g_print("%s: Set %s=%s\n", classname, attr_name, value);
- } else {
- g_print("%s: unset %s.\n", classname, attr_name);
- }
-}
-#else
-# define log_set_attr(_classname, _key, _value) static_cast<void>(0)
-#endif
-
-/* Animation base class */
-
-static void sp_animation_class_init(SPAnimationClass *klass);
-static void sp_animation_init(SPAnimation *animation);
-
-//static void sp_animation_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
-static void sp_animation_release(SPObject *object);
-static void sp_animation_set(SPObject *object, unsigned int key, gchar const *value);
-
-static SPObjectClass *animation_parent_class;
-
-GType sp_animation_get_type(void)
-{
- static GType animation_type = 0;
-
- if (!animation_type) {
- GTypeInfo animation_info = {
- sizeof(SPAnimationClass),
- NULL, NULL,
- (GClassInitFunc) sp_animation_class_init,
- NULL, NULL,
- sizeof(SPAnimation),
- 16,
- (GInstanceInitFunc) sp_animation_init,
- NULL, /* value_table */
- };
- animation_type = g_type_register_static(SP_TYPE_OBJECT, "SPAnimation", &animation_info, (GTypeFlags)0);
- }
- return animation_type;
-}
-
-static void sp_animation_class_init(SPAnimationClass *klass)
-{
- //GObjectClass *gobject_class = (GObjectClass *) klass;
- SPObjectClass *sp_object_class = (SPObjectClass *) klass;
-
- animation_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass);
-
- //sp_object_class->build = sp_animation_build;
-// sp_object_class->release = sp_animation_release;
-// sp_object_class->set = sp_animation_set;
-}
-
-CAnimation::CAnimation(SPAnimation* animation) : CObject(animation) {
- this->spanimation = animation;
-}
-
-CAnimation::~CAnimation() {
-}
-
-static void sp_animation_init(SPAnimation *animation)
-{
- animation->canimation = new CAnimation(animation);
- animation->cobject = animation->canimation;
-}
-
-
-//static void sp_animation_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
-//{
-// if (((SPObjectClass *) animation_parent_class)->build)
-// ((SPObjectClass *) animation_parent_class)->build(object, document, repr);
-//
-// object->readAttr( "xlink:href" );
-// object->readAttr( "attributeName" );
-// object->readAttr( "attributeType" );
-// object->readAttr( "begin" );
-// object->readAttr( "dur" );
-// object->readAttr( "end" );
-// object->readAttr( "min" );
-// object->readAttr( "max" );
-// object->readAttr( "restart" );
-// object->readAttr( "repeatCount" );
-// object->readAttr( "repeatDur" );
-// object->readAttr( "fill" );
-//}
-
-void CAnimation::onBuild(SPDocument *document, Inkscape::XML::Node *repr) {
- SPAnimation* object = this->spanimation;
-
- CObject::onBuild(document, repr);
-
- object->readAttr( "xlink:href" );
- object->readAttr( "attributeName" );
- object->readAttr( "attributeType" );
- object->readAttr( "begin" );
- object->readAttr( "dur" );
- object->readAttr( "end" );
- object->readAttr( "min" );
- object->readAttr( "max" );
- object->readAttr( "restart" );
- object->readAttr( "repeatCount" );
- object->readAttr( "repeatDur" );
- object->readAttr( "fill" );
-}
-
-static void sp_animation_release(SPObject *object)
-{
- ((SPAnimation*)object)->canimation->onRelease();
-}
-
-void CAnimation::onRelease() {
-}
-
-static void sp_animation_set(SPObject *object, unsigned int key, gchar const *value)
-{
- //SPAnimation *animation = SP_ANIMATION(object);
-//
-// log_set_attr("SPAnimation", key, value);
-//
-// if (((SPObjectClass *) animation_parent_class)->set)
-// ((SPObjectClass *) animation_parent_class)->set(object, key, value);
- ((SPAnimation*)object)->canimation->onSet(key, value);
-}
-
-void CAnimation::onSet(unsigned int key, gchar const *value) {
- CObject::onSet(key, value);
-}
-
-
-/* Interpolated animation base class */
-
-static void sp_ianimation_class_init(SPIAnimationClass *klass);
-static void sp_ianimation_init(SPIAnimation *animation);
-
-//static void sp_ianimation_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
-static void sp_ianimation_release(SPObject *object);
-static void sp_ianimation_set(SPObject *object, unsigned int key, gchar const *value);
-
-static SPObjectClass *ianimation_parent_class;
-
-GType sp_ianimation_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- GTypeInfo info = {
- sizeof(SPIAnimationClass),
- NULL, NULL,
- (GClassInitFunc) sp_ianimation_class_init,
- NULL, NULL,
- sizeof(SPIAnimation),
- 16,
- (GInstanceInitFunc) sp_ianimation_init,
- NULL, /* value_table */
- };
- type = g_type_register_static(SP_TYPE_OBJECT, "SPIAnimation", &info, (GTypeFlags)0);
- }
- return type;
-}
-
-static void sp_ianimation_class_init(SPIAnimationClass *klass)
-{
- //GObjectClass *gobject_class = (GObjectClass *) klass;
- SPObjectClass *sp_object_class = (SPObjectClass *) klass;
-
- ianimation_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass);
-
- //sp_object_class->build = sp_ianimation_build;
-// sp_object_class->release = sp_ianimation_release;
-// sp_object_class->set = sp_ianimation_set;
-}
-
-CIAnimation::CIAnimation(SPIAnimation* animation) : CAnimation(animation) {
- this->spianimation = animation;
-}
-
-static void sp_ianimation_init(SPIAnimation *animation)
-{
- animation->cianimation = new CIAnimation(animation);
- animation->canimation = animation->cianimation;
- animation->cobject = animation->cianimation;
-}
-
-
-//static void sp_ianimation_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
-//{
-// if (((SPObjectClass *) ianimation_parent_class)->build)
-// ((SPObjectClass *) ianimation_parent_class)->build(object, document, repr);
-//
-// object->readAttr( "calcMode" );
-// object->readAttr( "values" );
-// object->readAttr( "keyTimes" );
-// object->readAttr( "keySplines" );
-// object->readAttr( "from" );
-// object->readAttr( "to" );
-// object->readAttr( "by" );
-// object->readAttr( "additive" );
-// object->readAttr( "accumulate" );
-//}
-
-void CIAnimation::onBuild(SPDocument *document, Inkscape::XML::Node *repr) {
- SPIAnimation* object = this->spianimation;
-
- CAnimation::onBuild(document, repr);
-
- object->readAttr( "calcMode" );
- object->readAttr( "values" );
- object->readAttr( "keyTimes" );
- object->readAttr( "keySplines" );
- object->readAttr( "from" );
- object->readAttr( "to" );
- object->readAttr( "by" );
- object->readAttr( "additive" );
- object->readAttr( "accumulate" );
-}
-
-static void sp_ianimation_release(SPObject *object)
-{
- ((SPIAnimation*)object)->cianimation->onRelease();
-}
-
-void CIAnimation::onRelease() {
-
-}
-
-static void sp_ianimation_set(SPObject *object, unsigned int key, gchar const *value)
-{
- //SPIAnimation *ianimation = SP_IANIMATION(object);
-
-// log_set_attr("SPIAnimation", key, value);
-//
-// if (((SPObjectClass *) ianimation_parent_class)->set)
-// ((SPObjectClass *) ianimation_parent_class)->set(object, key, value);
- ((SPIAnimation*)object)->cianimation->onSet(key, value);
-}
-
-void CIAnimation::onSet(unsigned int key, gchar const *value) {
- CAnimation::onSet(key, value);
-}
-
-/* SVG <animate> */
-
-static void sp_animate_class_init(SPAnimateClass *klass);
-static void sp_animate_init(SPAnimate *animate);
-
-//static void sp_animate_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
-static void sp_animate_release(SPObject *object);
-static void sp_animate_set(SPObject *object, unsigned int key, gchar const *value);
-
-static SPIAnimationClass *animate_parent_class;
-
-GType sp_animate_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- GTypeInfo info = {
- sizeof(SPAnimateClass),
- NULL, NULL,
- (GClassInitFunc) sp_animate_class_init,
- NULL, NULL,
- sizeof(SPAnimate),
- 16,
- (GInstanceInitFunc) sp_animate_init,
- NULL, /* value_table */
- };
- type = g_type_register_static(SP_TYPE_IANIMATION, "SPAnimate", &info, (GTypeFlags)0);
- }
- return type;
-}
-
-static void sp_animate_class_init(SPAnimateClass *klass)
-{
- //GObjectClass *gobject_class = (GObjectClass *) klass;
- SPObjectClass *sp_object_class = (SPObjectClass *) klass;
-
- animate_parent_class = (SPIAnimationClass*)g_type_class_peek_parent(klass);
-
- //sp_object_class->build = sp_animate_build;
-// sp_object_class->release = sp_animate_release;
-// sp_object_class->set = sp_animate_set;
-}
-
-CAnimate::CAnimate(SPAnimate* animate) : CIAnimation(animate) {
- this->spanimate = animate;
-}
-
-static void sp_animate_init(SPAnimate *animate)
-{
- animate->canimate = new CAnimate(animate);
- animate->cianimation = animate->canimate;
- animate->canimation = animate->canimate;
- animate->cobject = animate->canimate;
-}
-
-
-//static void sp_animate_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
-//{
-// if (((SPObjectClass *) animate_parent_class)->build)
-// ((SPObjectClass *) animate_parent_class)->build(object, document, repr);
-//}
-
-void CAnimate::onBuild(SPDocument *document, Inkscape::XML::Node *repr) {
- CIAnimation::onBuild(document, repr);
-}
-
-static void sp_animate_release(SPObject *object)
-{
- ((SPAnimate*)object)->canimate->onRelease();
-}
-
-void CAnimate::onRelease() {
-}
-
-static void sp_animate_set(SPObject *object, unsigned int key, gchar const *value)
-{
- //SPAnimate *animate = SP_ANIMATE(object);
-
-// log_set_attr("SPAnimate", key, value);
-//
-// if (((SPObjectClass *) animate_parent_class)->set)
-// ((SPObjectClass *) animate_parent_class)->set(object, key, value);
- ((SPAnimate*)object)->canimate->onSet(key, value);
-}
-
-void CAnimate::onSet(unsigned int key, gchar const *value) {
- CIAnimation::onSet(key, value);
-}
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/sp-animation.h.THIS b/src/sp-animation.h.THIS
deleted file mode 100644
index fc7315cb2..000000000
--- a/src/sp-animation.h.THIS
+++ /dev/null
@@ -1,129 +0,0 @@
-#ifndef __SP_ANIMATION_H__
-#define __SP_ANIMATION_H__
-
-/*
- * SVG <animate> implementation
- *
- * Authors:
- * Lauris Kaplinski <lauris@kaplinski.com>
- *
- * Copyright (C) 2002 Lauris Kaplinski
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include "sp-object.h"
-
-
-
-/* Animation base class */
-
-#define SP_TYPE_ANIMATION (sp_animation_get_type ())
-#define SP_ANIMATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_ANIMATION, SPAnimation))
-#define SP_IS_ANIMATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_ANIMATION))
-
-class SPAnimation;
-class SPAnimationClass;
-
-class CAnimation;
-
-class SPAnimation : public SPObject {
-public:
- CAnimation* canimation;
-};
-
-struct SPAnimationClass {
- SPObjectClass parent_class;
-};
-
-class CAnimation : public CObject {
-public:
- CAnimation(SPAnimation* animation);
- virtual ~CAnimation();
-
- virtual void onBuild(SPDocument* doc, Inkscape::XML::Node* repr);
- virtual void onRelease();
-
- virtual void onSet(unsigned int key, const gchar* value);
-
-private:
- SPAnimation* spanimation;
-};
-
-GType sp_animation_get_type (void);
-
-/* Interpolated animation base class */
-
-#define SP_TYPE_IANIMATION (sp_ianimation_get_type ())
-#define SP_IANIMATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_IANIMATION, SPIAnimation))
-#define SP_IS_IANIMATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_IANIMATION))
-
-class SPIAnimation;
-class SPIAnimationClass;
-
-class CIAnimation;
-
-class SPIAnimation : public SPAnimation {
-public:
- CIAnimation* cianimation;
-};
-
-struct SPIAnimationClass {
- SPAnimationClass parent_class;
-};
-
-class CIAnimation : public CAnimation {
-public:
- CIAnimation(SPIAnimation* animation);
- virtual ~CIAnimation();
-
- virtual void onBuild(SPDocument* doc, Inkscape::XML::Node* repr);
- virtual void onRelease();
-
- virtual void onSet(unsigned int key, const gchar* value);
-
-private:
- SPIAnimation* spianimation;
-};
-
-GType sp_ianimation_get_type (void);
-
-/* SVG <animate> */
-
-#define SP_TYPE_ANIMATE (sp_animate_get_type ())
-#define SP_ANIMATE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_ANIMATE, SPAnimate))
-#define SP_IS_ANIMATE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_ANIMATE))
-
-class SPAnimate;
-class SPAnimateClass;
-
-class CAnimate;
-
-class SPAnimate : public SPIAnimation {
-public:
- CAnimate* canimate;
-};
-
-struct SPAnimateClass {
- SPIAnimationClass parent_class;
-};
-
-class CAnimate : public CIAnimation {
-public:
- CAnimate(SPAnimate* animate);
- virtual ~CAnimate();
-
- virtual void onBuild(SPDocument* doc, Inkscape::XML::Node* repr);
- virtual void onRelease();
-
- virtual void onSet(unsigned int key, const gchar* value);
-
-private:
- SPAnimate* spanimate;
-};
-
-GType sp_animate_get_type (void);
-
-
-
-#endif
diff --git a/src/sp-gradient-fns.h b/src/sp-gradient-fns.h
deleted file mode 100644
index 165fd3ed8..000000000
--- a/src/sp-gradient-fns.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef SEEN_SP_GRADIENT_FNS_H
-#define SEEN_SP_GRADIENT_FNS_H
-
-/** \file
- * Macros and fn declarations related to gradients.
- */
-
-#include <glib.h>
-#include <glib-object.h>
-#include <2geom/forward.h>
-#include "sp-gradient-spread.h"
-#include "sp-gradient-units.h"
-
-class SPGradient;
-struct SPMeshGradient;
-
-SPGradientSpread sp_gradient_get_spread (SPGradient *gradient);
-
-/* Gradient repr methods */
-void sp_gradient_repr_write_vector(SPGradient *gr);
-void sp_gradient_repr_clear_vector(SPGradient *gr);
-
-void sp_meshgradient_repr_write(SPMeshGradient *mg);
-
-cairo_pattern_t *sp_gradient_create_preview_pattern(SPGradient *gradient, double width);
-
-/** Transforms to/from gradient position space in given environment */
-Geom::Affine sp_gradient_get_g2d_matrix(SPGradient const *gr, Geom::Affine const &ctm,
- Geom::Rect const &bbox);
-Geom::Affine sp_gradient_get_gs2d_matrix(SPGradient const *gr, Geom::Affine const &ctm,
- Geom::Rect const &bbox);
-void sp_gradient_set_gs2d_matrix(SPGradient *gr, Geom::Affine const &ctm, Geom::Rect const &bbox,
- Geom::Affine const &gs2d);
-
-
-#endif /* !SEEN_SP_GRADIENT_FNS_H */
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
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++
diff --git a/src/sp-gradient.h b/src/sp-gradient.h
index 2091e7ed5..8a03d59e6 100644
--- a/src/sp-gradient.h
+++ b/src/sp-gradient.h
@@ -27,12 +27,22 @@
#include <stddef.h>
#include <sigc++/connection.h>
+
+
+//#include <glib.h>
+//#include <glib-object.h>
+//#include <2geom/forward.h>
+//#include "sp-gradient-spread.h"
+//#include "sp-gradient-units.h"
+//
+//class SPGradient;
+//struct SPMeshGradient;
+
class SPGradientReference;
struct SPStop;
-#define SP_TYPE_GRADIENT (SPGradient::getType())
#define SP_GRADIENT(obj) ((SPGradient*)obj)
-#define SP_IS_GRADIENT(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPGradient)))
+#define SP_IS_GRADIENT(obj) (dynamic_cast<const SPGradient*>((SPObject*)obj))
enum SPGradientType {
SP_GRADIENT_TYPE_UNKNOWN,
@@ -85,8 +95,6 @@ std::vector<PaintTarget> const &allPaintTargets();
} // namespace Inkscape
-class CGradient;
-
/**
* Gradient
*
@@ -96,7 +104,7 @@ class CGradient;
class SPGradient : public SPPaintServer {
public:
SPGradient();
- CGradient* cgradient;
+ virtual ~SPGradient();
private:
/** gradientUnits attribute */
@@ -193,33 +201,12 @@ private:
void rebuildVector();
void rebuildArray();
- friend class CGradient;
-// friend class SPLGPainter;
-// friend class SPRGPainter;
-};
-
-/**
- * The SPGradient vtable.
- */
-struct SPGradientClass {
- SPPaintServerClass parent_class;
-};
-
-
-class CGradient : public CPaintServer {
public:
- CGradient(SPGradient* gradient);
- virtual ~CGradient();
-
- static void classInit(SPGradientClass *klass);
- static void init(SPGradient *gr);
-
virtual void build(SPDocument *document, Inkscape::XML::Node *repr);
virtual void release();
virtual void modified(guint flags);
virtual Inkscape::XML::Node* write(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);
@@ -227,13 +214,30 @@ public:
virtual void remove_child(Inkscape::XML::Node *child);
virtual void set(unsigned key, gchar const *value);
-
-protected:
- SPGradient* spgradient;
};
+void
+sp_gradient_pattern_common_setup(cairo_pattern_t *cp,
+ SPGradient *gr,
+ Geom::OptRect const &bbox,
+ double opacity);
+
+/* Gradient repr methods */
+void sp_gradient_repr_write_vector(SPGradient *gr);
+void sp_gradient_repr_clear_vector(SPGradient *gr);
+
+void sp_meshgradient_repr_write(SPMeshGradient *mg);
+
+cairo_pattern_t *sp_gradient_create_preview_pattern(SPGradient *gradient, double width);
+
+/** Transforms to/from gradient position space in given environment */
+Geom::Affine sp_gradient_get_g2d_matrix(SPGradient const *gr, Geom::Affine const &ctm,
+ Geom::Rect const &bbox);
+Geom::Affine sp_gradient_get_gs2d_matrix(SPGradient const *gr, Geom::Affine const &ctm,
+ Geom::Rect const &bbox);
+void sp_gradient_set_gs2d_matrix(SPGradient *gr, Geom::Affine const &ctm, Geom::Rect const &bbox,
+ Geom::Affine const &gs2d);
-#include "sp-gradient-fns.h"
#endif // SEEN_SP_GRADIENT_H
diff --git a/src/sp-linear-gradient-fns.h b/src/sp-linear-gradient-fns.h
deleted file mode 100644
index 059877a4e..000000000
--- a/src/sp-linear-gradient-fns.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef SP_LINEAR_GRADIENT_FNS_H
-#define SP_LINEAR_GRADIENT_FNS_H
-
-/** \file
- * Macros and fn declarations related to linear gradients.
- */
-
-#include <glib-object.h>
-#include <glib.h>
-
-#include "sp-linear-gradient.h"
-
-namespace Inkscape {
-namespace XML {
-class Node;
-}
-}
-
-struct SPLinearGradient;
-
-#define SP_TYPE_LINEARGRADIENT (sp_lineargradient_get_type())
-#define SP_LINEARGRADIENT(obj) ((SPLinearGradient*)obj)
-#define SP_IS_LINEARGRADIENT(obj) (dynamic_cast<const SPLinearGradient*>((SPObject*)obj))
-
-GType sp_lineargradient_get_type();
-
-void sp_lineargradient_set_position(SPLinearGradient *lg, gdouble x1, gdouble y1, gdouble x2, gdouble y2);
-
-#endif /* !SP_LINEAR_GRADIENT_FNS_H */
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/sp-linear-gradient.cpp b/src/sp-linear-gradient.cpp
new file mode 100644
index 000000000..d1d3f9d74
--- /dev/null
+++ b/src/sp-linear-gradient.cpp
@@ -0,0 +1,133 @@
+#include "sp-linear-gradient.h"
+
+#include "attributes.h"
+#include "xml/repr.h"
+
+#include "sp-factory.h"
+
+namespace {
+ SPObject* createLinearGradient() {
+ return new SPLinearGradient();
+ }
+
+ bool linearGradientRegistered = SPFactory::instance().registerObject("svg:linearGradient", createLinearGradient);
+}
+
+
+/*
+ * Linear Gradient
+ */
+SPLinearGradient::SPLinearGradient() : SPGradient() {
+ this->cobject = this;
+
+ this->x1.unset(SVGLength::PERCENT, 0.0, 0.0);
+ this->y1.unset(SVGLength::PERCENT, 0.0, 0.0);
+ this->x2.unset(SVGLength::PERCENT, 1.0, 1.0);
+ this->y2.unset(SVGLength::PERCENT, 0.0, 0.0);
+}
+
+SPLinearGradient::~SPLinearGradient() {
+}
+
+void SPLinearGradient::build(SPDocument *document, Inkscape::XML::Node *repr) {
+ SPGradient::build(document, repr);
+
+ this->readAttr( "x1" );
+ this->readAttr( "y1" );
+ this->readAttr( "x2" );
+ this->readAttr( "y2" );
+}
+
+/**
+ * Callback: set attribute.
+ */
+void SPLinearGradient::set(unsigned int key, const gchar* value) {
+ switch (key) {
+ case SP_ATTR_X1:
+ this->x1.readOrUnset(value, SVGLength::PERCENT, 0.0, 0.0);
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_Y1:
+ this->y1.readOrUnset(value, SVGLength::PERCENT, 0.0, 0.0);
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_X2:
+ this->x2.readOrUnset(value, SVGLength::PERCENT, 1.0, 1.0);
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_Y2:
+ this->y2.readOrUnset(value, SVGLength::PERCENT, 0.0, 0.0);
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ default:
+ SPGradient::set(key, value);
+ break;
+ }
+}
+
+/**
+ * Callback: write attributes to associated repr.
+ */
+Inkscape::XML::Node* SPLinearGradient::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
+ if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
+ repr = xml_doc->createElement("svg:linearGradient");
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->x1._set) {
+ sp_repr_set_svg_double(repr, "x1", this->x1.computed);
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->y1._set) {
+ sp_repr_set_svg_double(repr, "y1", this->y1.computed);
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->x2._set) {
+ sp_repr_set_svg_double(repr, "x2", this->x2.computed);
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->y2._set) {
+ sp_repr_set_svg_double(repr, "y2", this->y2.computed);
+ }
+
+ SPGradient::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);
+}
+
+
+cairo_pattern_t* SPLinearGradient::pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity) {
+ this->ensureVector();
+
+ cairo_pattern_t *cp = cairo_pattern_create_linear(
+ this->x1.computed, this->y1.computed,
+ this->x2.computed, this->y2.computed);
+
+ sp_gradient_pattern_common_setup(cp, this, bbox, opacity);
+
+ return cp;
+}
diff --git a/src/sp-linear-gradient.h b/src/sp-linear-gradient.h
index 39aeceeef..89065245d 100644
--- a/src/sp-linear-gradient.h
+++ b/src/sp-linear-gradient.h
@@ -7,43 +7,28 @@
#include "sp-gradient.h"
#include "svg/svg-length.h"
-#include "sp-linear-gradient-fns.h"
-class CLinearGradient;
+#define SP_LINEARGRADIENT(obj) ((SPLinearGradient*)obj)
+#define SP_IS_LINEARGRADIENT(obj) (dynamic_cast<const SPLinearGradient*>((SPObject*)obj))
/** Linear gradient. */
class SPLinearGradient : public SPGradient {
public:
SPLinearGradient();
- CLinearGradient* clineargradient;
+ virtual ~SPLinearGradient();
SVGLength x1;
SVGLength y1;
SVGLength x2;
SVGLength y2;
-};
-
-/// The SPLinearGradient vtable.
-struct SPLinearGradientClass {
- SPGradientClass parent_class;
-};
-
-class CLinearGradient : public CGradient {
public:
- CLinearGradient(SPLinearGradient* lineargradient);
- virtual ~CLinearGradient();
-
virtual void build(SPDocument *document, Inkscape::XML::Node *repr);
virtual void set(unsigned key, gchar const *value);
virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags);
virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity);
-
-protected:
- SPLinearGradient* splineargradient;
};
-
#endif /* !SP_LINEAR_GRADIENT_H */
/*
diff --git a/src/sp-mesh-gradient-fns.h b/src/sp-mesh-gradient-fns.h
deleted file mode 100644
index 88fc69637..000000000
--- a/src/sp-mesh-gradient-fns.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef SP_MESH_GRADIENT_FNS_H
-#define SP_MESH_GRADIENT_FNS_H
-
-/** \file
- * Macros and fn definitions related to mesh gradients.
- */
-
-#include <glib-object.h>
-#include <glib.h>
-
-namespace Inkscape {
-namespace XML {
-class Node;
-}
-}
-
-struct SPMeshGradient;
-
-#define SP_TYPE_MESHGRADIENT (sp_meshgradient_get_type())
-#define SP_MESHGRADIENT(obj) ((SPMeshGradient*)obj)
-#define SP_IS_MESHGRADIENT(obj) (dynamic_cast<const SPMeshGradient*>((SPObject*)obj))
-
-GType sp_meshgradient_get_type();
-
-void sp_meshgradient_set_position(SPMeshGradient *mg, gdouble x, gdouble y );
-
-#endif /* !SP_MESH_GRADIENT_FNS_H */
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/sp-mesh-gradient.cpp b/src/sp-mesh-gradient.cpp
new file mode 100644
index 000000000..5021b516e
--- /dev/null
+++ b/src/sp-mesh-gradient.cpp
@@ -0,0 +1,231 @@
+#include "sp-mesh-gradient.h"
+
+#include "attributes.h"
+#include "xml/repr.h"
+#include "display/cairo-utils.h"
+
+#include "sp-factory.h"
+
+namespace {
+ SPObject* createMeshGradient() {
+ return new SPMeshGradient();
+ }
+
+ bool meshGradientRegistered = SPFactory::instance().registerObject("svg:meshGradient", createMeshGradient);
+}
+
+
+/*
+ * Mesh Gradient
+ */
+//#define MESH_DEBUG
+SPMeshGradient::SPMeshGradient() : SPGradient() {
+ this->cobject = this;
+
+ // Start coordinate of mesh
+ this->x.unset(SVGLength::NONE, 0.0, 0.0);
+ this->y.unset(SVGLength::NONE, 0.0, 0.0);
+}
+
+SPMeshGradient::~SPMeshGradient() {
+}
+
+void SPMeshGradient::build(SPDocument *document, Inkscape::XML::Node *repr) {
+ SPGradient::build(document, repr);
+
+ // Start coordinate of mesh
+ this->readAttr( "x" );
+ this->readAttr( "y" );
+}
+
+
+void SPMeshGradient::set(unsigned key, gchar const *value) {
+ switch (key) {
+ case SP_ATTR_X:
+ if (!this->x.read(value)) {
+ this->x.unset(SVGLength::NONE, 0.0, 0.0);
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_Y:
+ if (!this->y.read(value)) {
+ this->y.unset(SVGLength::NONE, 0.0, 0.0);
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ default:
+ SPGradient::set(key, value);
+ break;
+ }
+}
+
+/**
+ * Write mesh gradient attributes to associated repr.
+ */
+Inkscape::XML::Node* SPMeshGradient::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
+#ifdef MESH_DEBUG
+ std::cout << "sp_meshgradient_write() ***************************" << std::endl;
+#endif
+
+ if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
+ repr = xml_doc->createElement("svg:meshGradient");
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->x._set) {
+ sp_repr_set_svg_double(repr, "x", this->x.computed);
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->y._set) {
+ sp_repr_set_svg_double(repr, "y", this->y.computed);
+ }
+
+ SPGradient::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);
+}
+
+void
+sp_meshgradient_repr_write(SPMeshGradient *mg)
+{
+ mg->array.write( mg );
+}
+
+
+cairo_pattern_t* SPMeshGradient::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;
+
+#ifdef MESH_DEBUG
+ std::cout << "sp_meshgradient_create_pattern: (" << bbox->x0 << "," << bbox->y0 << ") (" << bbox->x1 << "," << bbox->y1 << ") " << opacity << std::endl;
+#endif
+
+ this->ensureArray();
+
+ cairo_pattern_t *cp = NULL;
+
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 4)
+ SPMeshNodeArray* array = &(this->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 = this->gradientTransform;
+ if (this->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;
+}
diff --git a/src/sp-mesh-gradient.h b/src/sp-mesh-gradient.h
index d8f2b3770..bfd1c9c06 100644
--- a/src/sp-mesh-gradient.h
+++ b/src/sp-mesh-gradient.h
@@ -7,41 +7,25 @@
#include "svg/svg-length.h"
#include "sp-gradient.h"
-#include "sp-mesh-gradient-fns.h"
-class CMeshGradient;
+#define SP_MESHGRADIENT(obj) ((SPMeshGradient*)obj)
+#define SP_IS_MESHGRADIENT(obj) (dynamic_cast<const SPMeshGradient*>((SPObject*)obj))
/** Mesh gradient. */
class SPMeshGradient : public SPGradient {
public:
SPMeshGradient();
- CMeshGradient* cmeshgradient;
+ virtual ~SPMeshGradient();
SVGLength x; // Upper left corner of mesh
SVGLength y; // Upper right corner of mesh
-};
-
-/// The SPMeshGradient vtable.
-struct SPMeshGradientClass {
- SPGradientClass parent_class;
-};
-
-
-class CMeshGradient : public CGradient {
-public:
- CMeshGradient(SPMeshGradient* meshgradient);
- virtual ~CMeshGradient();
virtual void build(SPDocument *document, Inkscape::XML::Node *repr);
virtual void set(unsigned key, gchar const *value);
virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags);
virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity);
-
-protected:
- SPMeshGradient* spmeshgradient;
};
-
#endif /* !SP_MESH_GRADIENT_H */
/*
diff --git a/src/sp-mesh-patch-fns.h b/src/sp-mesh-patch-fns.h
deleted file mode 100644
index 163dfcdce..000000000
--- a/src/sp-mesh-patch-fns.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef SP_MESH_PATCH_FNS_H
-#define SP_MESH_PATCH_FNS_H
-
-/** \file
- * Macros and fn definitions related to mesh patchs.
- */
-
-#include <glib-object.h>
-
-namespace Inkscape {
-namespace XML {
-class Node;
-}
-}
-
-class SPMeshPatch;
-
-#define SP_TYPE_MESHPATCH (sp_meshpatch_get_type())
-#define SP_MESHPATCH(obj) ((SPMeshPatch*)obj)
-#define SP_IS_MESHPATCH(obj) (dynamic_cast<const SPMeshPatch*>((SPObject*)obj))
-
-GType sp_meshpatch_get_type();
-
-
-#endif /* !SP_MESH_PATCH_FNS_H */
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/sp-mesh-patch.cpp b/src/sp-mesh-patch.cpp
index ff1a18a01..e3e9044a5 100644
--- a/src/sp-mesh-patch.cpp
+++ b/src/sp-mesh-patch.cpp
@@ -17,6 +17,19 @@
#include "sp-mesh-patch.h"
#include "style.h"
+#include "attributes.h"
+#include "xml/repr.h"
+
+#include "sp-factory.h"
+
+namespace {
+ SPObject* createMeshPatch() {
+ return new SPMeshPatch();
+ }
+
+ bool meshPatchRegistered = SPFactory::instance().registerObject("svg:meshPatch", createMeshPatch);
+}
+
SPMeshPatch* SPMeshPatch::getNextMeshPatch()
{
SPMeshPatch *result = 0;
@@ -51,6 +64,70 @@ SPMeshPatch* SPMeshPatch::getPrevMeshPatch()
return result;
}
+
+/*
+ * Mesh Patch
+ */
+
+SPMeshPatch::SPMeshPatch() : SPObject(), CObject(this) {
+ delete this->cobject;
+ this->cobject = this;
+
+ this->tensor_string = NULL;
+}
+
+SPMeshPatch::~SPMeshPatch() {
+}
+
+void SPMeshPatch::build(SPDocument* doc, Inkscape::XML::Node* repr) {
+ SPMeshPatch* object = this;
+
+ CObject::build(doc, repr);
+
+ object->readAttr( "tensor" );
+}
+
+/**
+ * Virtual build: set meshpatch attributes from its associated XML node.
+ */
+
+void SPMeshPatch::set(unsigned int key, const gchar* value) {
+ SPMeshPatch* object = this;
+
+ 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* SPMeshPatch::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.
+ */
+
/*
Local Variables:
mode:c++
diff --git a/src/sp-mesh-patch.h b/src/sp-mesh-patch.h
index 37abbaf40..4f2b4a566 100644
--- a/src/sp-mesh-patch.h
+++ b/src/sp-mesh-patch.h
@@ -19,50 +19,26 @@
class SPObjectClass;
-struct SPMeshPatch;
-struct SPMeshPatchClass;
-
-#define SP_TYPE_MESHPATCH (sp_meshpatch_get_type())
#define SP_MESHPATCH(obj) ((SPMeshPatch*)obj)
-#define SP_IS_MESHPATCH(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPMeshPatch)))
-
-GType sp_meshpatch_get_type();
-
-class CMeshPatch;
+#define SP_IS_MESHPATCH(obj) (dynamic_cast<const SPMeshPatch*>((SPObject*)obj))
/** Gradient MeshPatch. */
-class SPMeshPatch : public SPObject {
+class SPMeshPatch : public SPObject, public CObject {
public:
SPMeshPatch();
- CMeshPatch* cmeshpatch;
+ virtual ~SPMeshPatch();
SPMeshPatch* getNextMeshPatch();
SPMeshPatch* getPrevMeshPatch();
Glib::ustring * tensor_string;
//SVGLength tx[4]; // Tensor points
//SVGLength ty[4]; // Tensor points
-};
-
-/// The SPMeshPatch vtable.
-struct SPMeshPatchClass {
- SPObjectClass parent_class;
-};
-
-
-class CMeshPatch : public CObject {
-public:
- CMeshPatch(SPMeshPatch* meshpatch);
- virtual ~CMeshPatch();
virtual void build(SPDocument* doc, Inkscape::XML::Node* repr);
virtual void set(unsigned int key, const gchar* value);
virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags);
-
-protected:
- SPMeshPatch* spmeshpatch;
};
-
#endif /* !SEEN_SP_MESHPATCH_H */
/*
diff --git a/src/sp-mesh-row-fns.h b/src/sp-mesh-row-fns.h
deleted file mode 100644
index 7f73c2104..000000000
--- a/src/sp-mesh-row-fns.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef SP_MESH_ROW_FNS_H
-#define SP_MESH_ROW_FNS_H
-
-/** \file
- * Macros and fn definitions related to mesh rows.
- */
-
-#include <glib-object.h>
-
-namespace Inkscape {
-namespace XML {
-class Node;
-}
-}
-
-class SPMeshRow;
-
-#define SP_TYPE_MESHROW (sp_meshrow_get_type())
-#define SP_MESHROW(obj) ((SPMeshRow*)obj)
-#define SP_IS_MESHROW(obj) (dynamic_cast<const SPMeshRow*>((SPObject*)obj))
-
-GType sp_meshrow_get_type();
-
-
-#endif /* !SP_MESH_ROW_FNS_H */
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/sp-mesh-row.cpp b/src/sp-mesh-row.cpp
index bc0c59776..9cffb3389 100644
--- a/src/sp-mesh-row.cpp
+++ b/src/sp-mesh-row.cpp
@@ -17,6 +17,18 @@
#include "sp-mesh-row.h"
#include "style.h"
+#include "xml/repr.h"
+
+#include "sp-factory.h"
+
+namespace {
+ SPObject* createMeshRow() {
+ return new SPMeshRow();
+ }
+
+ bool meshRowRegistered = SPFactory::instance().registerObject("svg:meshRow", createMeshRow);
+}
+
SPMeshRow* SPMeshRow::getNextMeshRow()
{
SPMeshRow *result = 0;
@@ -51,6 +63,47 @@ SPMeshRow* SPMeshRow::getPrevMeshRow()
return result;
}
+
+/*
+ * Mesh Row
+ */
+SPMeshRow::SPMeshRow() : SPObject(), CObject(this) {
+ delete this->cobject;
+ this->cobject = this;
+}
+
+SPMeshRow::~SPMeshRow() {
+}
+
+void SPMeshRow::build(SPDocument* doc, Inkscape::XML::Node* repr) {
+ CObject::build(doc, repr);
+}
+
+/**
+ * Virtual build: set meshrow attributes from its associated XML node.
+ */
+
+void SPMeshRow::set(unsigned int key, const gchar* value) {
+}
+
+/**
+ * Virtual set: set attribute to value.
+ */
+
+Inkscape::XML::Node* SPMeshRow::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.
+ */
+
/*
Local Variables:
mode:c++
diff --git a/src/sp-mesh-row.h b/src/sp-mesh-row.h
index 463292d44..aeb4af561 100644
--- a/src/sp-mesh-row.h
+++ b/src/sp-mesh-row.h
@@ -16,47 +16,23 @@
class SPObjectClass;
-struct SPMeshRow;
-struct SPMeshRowClass;
-
-#define SP_TYPE_MESHROW (sp_meshrow_get_type())
#define SP_MESHROW(obj) ((SPMeshRow*)obj)
-#define SP_IS_MESHROW(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPMeshRow)))
-
-GType sp_meshrow_get_type();
-
-class CMeshRow;
+#define SP_IS_MESHROW(obj) (dynamic_cast<const SPMeshRow*>((SPObject*)obj))
/** Gradient MeshRow. */
-class SPMeshRow : public SPObject {
+class SPMeshRow : public SPObject, public CObject {
public:
SPMeshRow();
- CMeshRow* cmeshrow;
+ virtual ~SPMeshRow();
SPMeshRow* getNextMeshRow();
SPMeshRow* getPrevMeshRow();
-};
-
-/// The SPMeshRow vtable.
-struct SPMeshRowClass {
- SPObjectClass parent_class;
-};
-
-
-class CMeshRow : public CObject {
-public:
- CMeshRow(SPMeshRow* meshrow);
- virtual ~CMeshRow();
virtual void build(SPDocument* doc, Inkscape::XML::Node* repr);
virtual void set(unsigned int key, const gchar* value);
virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags);
-
-protected:
- SPMeshRow* spmeshrow;
};
-
#endif /* !SEEN_SP_MESHROW_H */
/*
diff --git a/src/sp-paint-server.cpp b/src/sp-paint-server.cpp
index cabd6809c..b438e44b1 100644
--- a/src/sp-paint-server.cpp
+++ b/src/sp-paint-server.cpp
@@ -30,35 +30,15 @@ bool SPPaintServerReference::_acceptObject(SPObject *obj) const
return SP_IS_PAINT_SERVER(obj);
}
-G_DEFINE_TYPE(SPPaintServer, sp_paint_server, G_TYPE_OBJECT);
-static void sp_paint_server_class_init(SPPaintServerClass *psc)
-{
-}
-
-CPaintServer::CPaintServer(SPPaintServer* paintserver) : CObject(paintserver) {
- this->sppaintserver = paintserver;
-}
-
-CPaintServer::~CPaintServer() {
-}
-
-SPPaintServer::SPPaintServer() : SPObject() {
- SPPaintServer* ps = this;
-
- ps->cpaintserver = new CPaintServer(ps);
- ps->typeHierarchy.insert(typeid(SPPaintServer));
+SPPaintServer::SPPaintServer() : SPObject(), CObject(this) {
+ delete this->cobject;
+ this->cobject = this;
- delete ps->cobject;
- ps->cobject = ps->cpaintserver;
-
- ps->swatch = 0;
+ this->swatch = 0;
}
-static void
-sp_paint_server_init(SPPaintServer *ps)
-{
- new (ps) SPPaintServer();
+SPPaintServer::~SPPaintServer() {
}
cairo_pattern_t *sp_paint_server_invoke_create_pattern(SPPaintServer *ps,
@@ -71,13 +51,13 @@ cairo_pattern_t *sp_paint_server_invoke_create_pattern(SPPaintServer *ps,
cairo_pattern_t *cp = NULL;
- cp = ps->cpaintserver->pattern_new(ct, bbox, opacity);
+ cp = ps->pattern_new(ct, bbox, opacity);
return cp;
}
// CPPIFY: make pure virtual
-cairo_pattern_t* CPaintServer::pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity) {
+cairo_pattern_t* SPPaintServer::pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity) {
//throw;
// dummy_pattern
diff --git a/src/sp-paint-server.h b/src/sp-paint-server.h
index d00b57efc..d13c26481 100644
--- a/src/sp-paint-server.h
+++ b/src/sp-paint-server.h
@@ -20,18 +20,13 @@
#include "sp-object.h"
#include "uri-references.h"
-#define SP_TYPE_PAINT_SERVER (sp_paint_server_get_type())
#define SP_PAINT_SERVER(obj) ((SPPaintServer*)obj)
-#define SP_IS_PAINT_SERVER(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPPaintServer)))
+#define SP_IS_PAINT_SERVER(obj) (dynamic_cast<const SPPaintServer*>((SPObject*)obj))
-GType sp_paint_server_get_type(void) G_GNUC_CONST;
-
-class CPaintServer;
-
-class SPPaintServer : public SPObject {
+class SPPaintServer : public SPObject, public CObject {
public:
SPPaintServer();
- CPaintServer* cpaintserver;
+ virtual ~SPPaintServer();
protected:
bool swatch;
@@ -39,22 +34,8 @@ public:
bool isSwatch() const;
bool isSolid() const;
-};
-
-struct SPPaintServerClass {
- SPObjectClass sp_object_class;
-};
-
-class CPaintServer : public CObject {
-public:
- CPaintServer(SPPaintServer* paintserver);
- virtual ~CPaintServer();
-
- virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity);
-
-protected:
- SPPaintServer* sppaintserver;
+ virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity);
};
diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp
index e4132ac1d..27c5e9a25 100644
--- a/src/sp-pattern.cpp
+++ b/src/sp-pattern.cpp
@@ -53,161 +53,139 @@ namespace {
bool patternRegistered = SPFactory::instance().registerObject("svg:pattern", createPattern);
}
-G_DEFINE_TYPE(SPPattern, sp_pattern, G_TYPE_OBJECT);
-
-static void
-sp_pattern_class_init (SPPatternClass *klass)
-{
-}
-
-CPattern::CPattern(SPPattern* pattern) : CPaintServer(pattern) {
- this->sppattern = pattern;
-}
-
-CPattern::~CPattern() {
-}
-
SPPattern::SPPattern() : SPPaintServer() {
- SPPattern* pat = this;
-
- pat->cpattern = new CPattern(pat);
- pat->typeHierarchy.insert(typeid(SPPattern));
+ this->cobject = this;
- delete pat->cpaintserver;
- pat->cpaintserver = pat->cpattern;
- pat->cobject = pat->cpattern;
+ this->href = NULL;
- pat->href = NULL;
+ this->ref = new SPPatternReference(this);
+ this->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(pattern_ref_changed), this));
- pat->ref = new SPPatternReference(pat);
- pat->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(pattern_ref_changed), pat));
+ this->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX;
+ this->patternUnits_set = FALSE;
- pat->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX;
- pat->patternUnits_set = FALSE;
+ this->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE;
+ this->patternContentUnits_set = FALSE;
- pat->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE;
- pat->patternContentUnits_set = FALSE;
+ this->patternTransform = Geom::identity();
+ this->patternTransform_set = FALSE;
- pat->patternTransform = Geom::identity();
- pat->patternTransform_set = FALSE;
+ this->x.unset();
+ this->y.unset();
+ this->width.unset();
+ this->height.unset();
- pat->x.unset();
- pat->y.unset();
- pat->width.unset();
- pat->height.unset();
+ this->viewBox_set = FALSE;
- pat->viewBox_set = FALSE;
-
- new (&pat->modified_connection) sigc::connection();
+ new (&this->modified_connection) sigc::connection();
}
-static void
-sp_pattern_init (SPPattern *pat)
-{
- new (pat) SPPattern();
+SPPattern::~SPPattern() {
}
-void CPattern::build(SPDocument* doc, Inkscape::XML::Node* repr) {
- SPPattern* object = this->sppattern;
-
- CPaintServer::build(doc, repr);
+void SPPattern::build(SPDocument* doc, Inkscape::XML::Node* repr) {
+ SPPaintServer::build(doc, repr);
- object->readAttr( "patternUnits" );
- object->readAttr( "patternContentUnits" );
- object->readAttr( "patternTransform" );
- object->readAttr( "x" );
- object->readAttr( "y" );
- object->readAttr( "width" );
- object->readAttr( "height" );
- object->readAttr( "viewBox" );
- object->readAttr( "xlink:href" );
+ this->readAttr( "patternUnits" );
+ this->readAttr( "patternContentUnits" );
+ this->readAttr( "patternTransform" );
+ this->readAttr( "x" );
+ this->readAttr( "y" );
+ this->readAttr( "width" );
+ this->readAttr( "height" );
+ this->readAttr( "viewBox" );
+ this->readAttr( "xlink:href" );
/* Register ourselves */
- doc->addResource("pattern", object);
+ doc->addResource("pattern", this);
}
-void CPattern::release() {
- SPPattern* object = this->sppattern;
-
- SPPattern *pat = reinterpret_cast<SPPattern *>(object);
-
- if (object->document) {
+void SPPattern::release() {
+ if (this->document) {
// Unregister ourselves
- object->document->removeResource("pattern", object);
+ this->document->removeResource("pattern", this);
}
- if (pat->ref) {
- pat->modified_connection.disconnect();
- pat->ref->detach();
- delete pat->ref;
- pat->ref = NULL;
+ if (this->ref) {
+ this->modified_connection.disconnect();
+ this->ref->detach();
+ delete this->ref;
+ this->ref = NULL;
}
- pat->modified_connection.~connection();
+ this->modified_connection.~connection();
- CPaintServer::release();
+ SPPaintServer::release();
}
-void CPattern::set(unsigned int key, const gchar* value) {
- SPPattern* object = this->sppattern;
-
- SPPattern *pat = SP_PATTERN (object);
-
+void SPPattern::set(unsigned int key, const gchar* value) {
switch (key) {
case SP_ATTR_PATTERNUNITS:
if (value) {
if (!strcmp (value, "userSpaceOnUse")) {
- pat->patternUnits = SP_PATTERN_UNITS_USERSPACEONUSE;
+ this->patternUnits = SP_PATTERN_UNITS_USERSPACEONUSE;
} else {
- pat->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX;
+ this->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX;
}
- pat->patternUnits_set = TRUE;
+
+ this->patternUnits_set = TRUE;
} else {
- pat->patternUnits_set = FALSE;
+ this->patternUnits_set = FALSE;
}
- object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
+
case SP_ATTR_PATTERNCONTENTUNITS:
if (value) {
if (!strcmp (value, "userSpaceOnUse")) {
- pat->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE;
+ this->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE;
} else {
- pat->patternContentUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX;
+ this->patternContentUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX;
}
- pat->patternContentUnits_set = TRUE;
+
+ this->patternContentUnits_set = TRUE;
} else {
- pat->patternContentUnits_set = FALSE;
+ this->patternContentUnits_set = FALSE;
}
- object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
+
case SP_ATTR_PATTERNTRANSFORM: {
Geom::Affine t;
+
if (value && sp_svg_transform_read (value, &t)) {
- pat->patternTransform = t;
- pat->patternTransform_set = TRUE;
+ this->patternTransform = t;
+ this->patternTransform_set = TRUE;
} else {
- pat->patternTransform = Geom::identity();
- pat->patternTransform_set = FALSE;
+ this->patternTransform = Geom::identity();
+ this->patternTransform_set = FALSE;
}
- object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
}
case SP_ATTR_X:
- pat->x.readOrUnset(value);
- object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ this->x.readOrUnset(value);
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
+
case SP_ATTR_Y:
- pat->y.readOrUnset(value);
- object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ this->y.readOrUnset(value);
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
+
case SP_ATTR_WIDTH:
- pat->width.readOrUnset(value);
- object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ this->width.readOrUnset(value);
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
+
case SP_ATTR_HEIGHT:
- pat->height.readOrUnset(value);
- object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ this->height.readOrUnset(value);
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
+
case SP_ATTR_VIEWBOX: {
/* fixme: Think (Lauris) */
double x, y, width, height;
@@ -216,50 +194,69 @@ void CPattern::set(unsigned int key, const gchar* value) {
if (value) {
eptr = (gchar *) value;
x = g_ascii_strtod (eptr, &eptr);
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++;
+
+ while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
+ eptr++;
+ }
+
y = g_ascii_strtod (eptr, &eptr);
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++;
+
+ while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
+ eptr++;
+ }
+
width = g_ascii_strtod (eptr, &eptr);
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++;
+
+ while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
+ eptr++;
+ }
+
height = g_ascii_strtod (eptr, &eptr);
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++;
+
+ while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
+ eptr++;
+ }
+
if ((width > 0) && (height > 0)) {
- pat->viewBox = Geom::Rect::from_xywh(x, y, width, height);
- pat->viewBox_set = TRUE;
+ this->viewBox = Geom::Rect::from_xywh(x, y, width, height);
+ this->viewBox_set = TRUE;
} else {
- pat->viewBox_set = FALSE;
+ this->viewBox_set = FALSE;
}
} else {
- pat->viewBox_set = FALSE;
+ this->viewBox_set = FALSE;
}
- object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
break;
}
case SP_ATTR_XLINK_HREF:
- if ( value && pat->href && ( strcmp(value, pat->href) == 0 ) ) {
+ if ( value && this->href && ( strcmp(value, this->href) == 0 ) ) {
/* Href unchanged, do nothing. */
} else {
- g_free(pat->href);
- pat->href = NULL;
+ g_free(this->href);
+ this->href = NULL;
+
if (value) {
// First, set the href field; it's only used in the "unchanged" check above.
- pat->href = g_strdup(value);
+ this->href = g_strdup(value);
// Now do the attaching, which emits the changed signal.
if (value) {
try {
- pat->ref->attach(Inkscape::URI(value));
+ this->ref->attach(Inkscape::URI(value));
} catch (Inkscape::BadURIException &e) {
g_warning("%s", e.what());
- pat->ref->detach();
+ this->ref->detach();
}
} else {
- pat->ref->detach();
+ this->ref->detach();
}
}
}
break;
+
default:
- CPaintServer::set(key, value);
+ SPPaintServer::set(key, value);
break;
}
}
@@ -275,56 +272,60 @@ static GSList *pattern_getchildren(SPPattern *pat)
for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (pat_i->firstChild()) { // find the first one with children
- for (SPObject *child = pat->firstChild() ; child ; child = child->getNext() ) {
- l = g_slist_prepend (l, child);
- }
- break; // do not go further up the chain if children are found
- }
+ for (SPObject *child = pat->firstChild() ; child ; child = child->getNext() ) {
+ l = g_slist_prepend (l, child);
+ }
+ break; // do not go further up the chain if children are found
+ }
}
- return l;
+ return l;
}
-void CPattern::update(SPCtx* ctx, unsigned int flags) {
- SPPattern* object = this->sppattern;
-
- SPPattern *pat = SP_PATTERN (object);
+void SPPattern::update(SPCtx* ctx, unsigned int flags) {
+ if (flags & SP_OBJECT_MODIFIED_FLAG) {
+ flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
+ }
- if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
flags &= SP_OBJECT_MODIFIED_CASCADE;
- GSList *l = pattern_getchildren (pat);
+ GSList *l = pattern_getchildren (this);
l = g_slist_reverse (l);
while (l) {
SPObject *child = SP_OBJECT (l->data);
+
sp_object_ref (child, NULL);
l = g_slist_remove (l, child);
+
if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
child->updateDisplay(ctx, flags);
}
+
sp_object_unref (child, NULL);
}
}
-void CPattern::modified(unsigned int flags) {
- SPPattern* object = this->sppattern;
-
- SPPattern *pat = SP_PATTERN (object);
+void SPPattern::modified(unsigned int flags) {
+ if (flags & SP_OBJECT_MODIFIED_FLAG) {
+ flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
+ }
- if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
flags &= SP_OBJECT_MODIFIED_CASCADE;
- GSList *l = pattern_getchildren (pat);
+ GSList *l = pattern_getchildren (this);
l = g_slist_reverse (l);
while (l) {
SPObject *child = SP_OBJECT (l->data);
+
sp_object_ref (child, NULL);
l = g_slist_remove (l, child);
+
if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
child->emitModified(flags);
}
+
sp_object_unref (child, NULL);
}
}
@@ -338,6 +339,7 @@ pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat)
if (old_ref) {
pat->modified_connection.disconnect();
}
+
if (SP_IS_PATTERN (ref)) {
pat->modified_connection = ref->connectModified(sigc::bind<2>(sigc::ptr_fun(&pattern_ref_modified), pat));
}
@@ -580,20 +582,18 @@ static bool pattern_hasItemChildren (SPPattern const *pat)
return hasChildren;
}
-cairo_pattern_t* CPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) {
- SPPattern* ps = this->sppattern;
-
- SPPattern *pat = SP_PATTERN (ps);
-
+cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) {
bool needs_opacity = (1.0 - opacity) >= 1e-3;
bool visible = opacity >= 1e-3;
- if (!visible)
+ if (!visible) {
return NULL;
+ }
/* Show items */
SPPattern *shown = NULL;
- for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+
+ for (SPPattern *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
// find the first one with item children
if (pat_i && SP_IS_OBJECT (pat_i) && pattern_hasItemChildren(pat_i)) {
shown = pat_i;
@@ -623,13 +623,13 @@ cairo_pattern_t* CPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bb
// viewBox to pattern server
Geom::Affine vb2ps = Geom::identity();
- if (pat->viewBox_set) {
- Geom::Rect vb = *pattern_viewBox(pat);
- gdouble tmp_x = pattern_width (pat) / vb.width();
- gdouble tmp_y = pattern_height (pat) / vb.height();
+ if (this->viewBox_set) {
+ Geom::Rect vb = *pattern_viewBox(this);
+ gdouble tmp_x = pattern_width (this) / vb.width();
+ gdouble tmp_y = pattern_height (this) / vb.height();
// FIXME: preserveAspectRatio must be taken into account here too!
- vb2ps = Geom::Affine(tmp_x, 0.0, 0.0, tmp_y, pattern_x(pat) - vb.left() * tmp_x, pattern_y(pat) - vb.top() * tmp_y);
+ vb2ps = Geom::Affine(tmp_x, 0.0, 0.0, tmp_y, pattern_x(this) - vb.left() * tmp_x, pattern_y(this) - vb.top() * tmp_y);
}
// We must determine the size and scaling of the pattern at the time it is displayed and render
@@ -637,19 +637,19 @@ cairo_pattern_t* CPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bb
// Pattern server to user
Geom::Affine ps2user;
- ps2user = pattern_patternTransform(pat);
- if (!pat->viewBox_set && pattern_patternContentUnits (pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
+ ps2user = pattern_patternTransform(this);
+ if (!this->viewBox_set && pattern_patternContentUnits (this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
/* BBox to user coordinate system */
Geom::Affine bbox2user (bbox->width(), 0.0, 0.0, bbox->height(), bbox->left(), bbox->top());
ps2user *= bbox2user;
}
- ps2user = Geom::Translate (pattern_x (pat), pattern_y (pat)) * ps2user;
+ ps2user = Geom::Translate (pattern_x (this), pattern_y (this)) * ps2user;
// Pattern size in pattern space
- Geom::Rect pattern_tile = Geom::Rect::from_xywh(pattern_x(pat), pattern_y(pat),
- pattern_width(pat), pattern_height(pat));
+ Geom::Rect pattern_tile = Geom::Rect::from_xywh(pattern_x(this), pattern_y(this),
+ pattern_width(this), pattern_height(this));
- if (pattern_patternUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
+ if (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
// interpret x, y, width, height in relation to bbox
Geom::Affine bbox2user(bbox->width(), 0.0, 0.0, bbox->height(), bbox->left(), bbox->top());
pattern_tile = pattern_tile * bbox2user;
diff --git a/src/sp-pattern.h b/src/sp-pattern.h
index 7c56184fb..a2cef6068 100644
--- a/src/sp-pattern.h
+++ b/src/sp-pattern.h
@@ -16,11 +16,9 @@
#include <gtk/gtk.h>
#include "sp-item.h"
-#define SP_TYPE_PATTERN (sp_pattern_get_type ())
-#define SP_PATTERN(obj) ((SPPattern*)obj)
-#define SP_IS_PATTERN(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPPattern)))
-GType sp_pattern_get_type (void);
+#define SP_PATTERN(obj) ((SPPattern*)obj)
+#define SP_IS_PATTERN(obj) (dynamic_cast<const SPPattern*>((SPObject*)obj))
struct SPPatternReference;
@@ -32,12 +30,10 @@ struct SPPatternReference;
#include <sigc++/connection.h>
-class CPattern;
-
class SPPattern : public SPPaintServer {
public:
SPPattern();
- CPattern* cpattern;
+ virtual ~SPPattern();
/* Reference (href) */
gchar *href;
@@ -61,17 +57,6 @@ public:
guint viewBox_set : 1;
sigc::connection modified_connection;
-};
-
-struct SPPatternClass {
- SPPaintServerClass parent_class;
-};
-
-
-class CPattern : public CPaintServer {
-public:
- CPattern(SPPattern* pattern);
- virtual ~CPattern();
virtual void build(SPDocument* doc, Inkscape::XML::Node* repr);
virtual void release();
@@ -79,9 +64,6 @@ public:
virtual void update(SPCtx* ctx, unsigned int flags);
virtual void modified(unsigned int flags);
virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity);
-
-protected:
- SPPattern* sppattern;
};
diff --git a/src/sp-radial-gradient-fns.h b/src/sp-radial-gradient-fns.h
deleted file mode 100644
index aa2db64ca..000000000
--- a/src/sp-radial-gradient-fns.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef SP_RADIAL_GRADIENT_FNS_H
-#define SP_RADIAL_GRADIENT_FNS_H
-
-/** \file
- * Macros and fn definitions related to radial gradients.
- */
-
-#include <glib-object.h>
-
-#include "sp-radial-gradient.h"
-
-namespace Inkscape {
-namespace XML {
-class Node;
-}
-}
-
-struct SPRadialGradient;
-
-#define SP_TYPE_RADIALGRADIENT (sp_radialgradient_get_type())
-#define SP_RADIALGRADIENT(obj) ((SPRadialGradient*)obj)
-#define SP_IS_RADIALGRADIENT(obj) (dynamic_cast<const SPRadialGradient*>((SPObject*)obj))
-
-GType sp_radialgradient_get_type();
-
-void sp_radialgradient_set_position(SPRadialGradient *rg, gdouble cx, gdouble cy, gdouble fx, gdouble fy, gdouble r);
-
-#endif /* !SP_RADIAL_GRADIENT_FNS_H */
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/sp-radial-gradient.cpp b/src/sp-radial-gradient.cpp
new file mode 100644
index 000000000..31d8c3e56
--- /dev/null
+++ b/src/sp-radial-gradient.cpp
@@ -0,0 +1,213 @@
+#include "sp-radial-gradient.h"
+
+#include "attributes.h"
+#include "xml/repr.h"
+
+#include "2geom/transforms.h"
+
+#include "sp-factory.h"
+
+namespace {
+ SPObject* createRadialGradient() {
+ return new SPRadialGradient();
+ }
+
+ bool radialGradientRegistered = SPFactory::instance().registerObject("svg:radialGradient", createRadialGradient);
+}
+
+/*
+ * Radial Gradient
+ */
+SPRadialGradient::SPRadialGradient() : SPGradient() {
+ this->cobject = this;
+
+ this->cx.unset(SVGLength::PERCENT, 0.5, 0.5);
+ this->cy.unset(SVGLength::PERCENT, 0.5, 0.5);
+ this->r.unset(SVGLength::PERCENT, 0.5, 0.5);
+ this->fx.unset(SVGLength::PERCENT, 0.5, 0.5);
+ this->fy.unset(SVGLength::PERCENT, 0.5, 0.5);
+}
+
+SPRadialGradient::~SPRadialGradient() {
+}
+
+/**
+ * Set radial gradient attributes from associated repr.
+ */
+void SPRadialGradient::build(SPDocument *document, Inkscape::XML::Node *repr) {
+ SPGradient::build(document, repr);
+
+ this->readAttr( "cx" );
+ this->readAttr( "cy" );
+ this->readAttr( "r" );
+ this->readAttr( "fx" );
+ this->readAttr( "fy" );
+}
+
+/**
+ * Set radial gradient attribute.
+ */
+void SPRadialGradient::set(unsigned key, gchar const *value) {
+ switch (key) {
+ case SP_ATTR_CX:
+ if (!this->cx.read(value)) {
+ this->cx.unset(SVGLength::PERCENT, 0.5, 0.5);
+ }
+
+ if (!this->fx._set) {
+ this->fx.value = this->cx.value;
+ this->fx.computed = this->cx.computed;
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_CY:
+ if (!this->cy.read(value)) {
+ this->cy.unset(SVGLength::PERCENT, 0.5, 0.5);
+ }
+
+ if (!this->fy._set) {
+ this->fy.value = this->cy.value;
+ this->fy.computed = this->cy.computed;
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_R:
+ if (!this->r.read(value)) {
+ this->r.unset(SVGLength::PERCENT, 0.5, 0.5);
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_FX:
+ if (!this->fx.read(value)) {
+ this->fx.unset(this->cx.unit, this->cx.value, this->cx.computed);
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_FY:
+ if (!this->fy.read(value)) {
+ this->fy.unset(this->cy.unit, this->cy.value, this->cy.computed);
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ default:
+ SPGradient::set(key, value);
+ break;
+ }
+}
+
+/**
+ * Write radial gradient attributes to associated repr.
+ */
+Inkscape::XML::Node* SPRadialGradient::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
+ if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
+ repr = xml_doc->createElement("svg:radialGradient");
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->cx._set) {
+ sp_repr_set_svg_double(repr, "cx", this->cx.computed);
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->cy._set) {
+ sp_repr_set_svg_double(repr, "cy", this->cy.computed);
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->r._set) {
+ sp_repr_set_svg_double(repr, "r", this->r.computed);
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->fx._set) {
+ sp_repr_set_svg_double(repr, "fx", this->fx.computed);
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->fy._set) {
+ sp_repr_set_svg_double(repr, "fy", this->fy.computed);
+ }
+
+ SPGradient::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);
+}
+
+
+cairo_pattern_t* SPRadialGradient::pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity) {
+ this->ensureVector();
+
+ Geom::Point focus(this->fx.computed, this->fy.computed);
+ Geom::Point center(this->cx.computed, this->cy.computed);
+
+ double radius = this->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 = this->gradientTransform;
+ Geom::Scale gs2user_scale;
+
+ if (this->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, this, bbox, opacity);
+
+ return cp;
+}
diff --git a/src/sp-radial-gradient.h b/src/sp-radial-gradient.h
index c32e8b099..f3daac0a1 100644
--- a/src/sp-radial-gradient.h
+++ b/src/sp-radial-gradient.h
@@ -8,44 +8,28 @@
#include <glib.h>
#include "sp-gradient.h"
#include "svg/svg-length.h"
-#include "sp-radial-gradient-fns.h"
-class CRadialGradient;
+#define SP_RADIALGRADIENT(obj) ((SPRadialGradient*)obj)
+#define SP_IS_RADIALGRADIENT(obj) (dynamic_cast<const SPRadialGradient*>((SPObject*)obj))
/** Radial gradient. */
class SPRadialGradient : public SPGradient {
public:
SPRadialGradient();
- CRadialGradient* cradialgradient;
+ virtual ~SPRadialGradient();
SVGLength cx;
SVGLength cy;
SVGLength r;
SVGLength fx;
SVGLength fy;
-};
-
-/// The SPRadialGradient vtable.
-struct SPRadialGradientClass {
- SPGradientClass parent_class;
-};
-
-
-class CRadialGradient : public CGradient {
-public:
- CRadialGradient(SPRadialGradient* radialgradient);
- virtual ~CRadialGradient();
virtual void build(SPDocument *document, Inkscape::XML::Node *repr);
virtual void set(unsigned key, gchar const *value);
virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags);
virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity);
-
-protected:
- SPRadialGradient* spradialgradient;
};
-
#endif /* !SP_RADIAL_GRADIENT_H */
/*
diff --git a/src/sp-stop.cpp b/src/sp-stop.cpp
index 0c0a3b03a..71d06ced9 100644
--- a/src/sp-stop.cpp
+++ b/src/sp-stop.cpp
@@ -17,6 +17,177 @@
#include "sp-stop.h"
#include "style.h"
+#include "attributes.h"
+#include "streq.h"
+#include "svg/svg.h"
+#include "svg/svg-color.h"
+#include "svg/css-ostringstream.h"
+#include "xml/repr.h"
+
+#include "sp-factory.h"
+
+namespace {
+ SPObject* createStop() {
+ return new SPStop();
+ }
+
+ bool stopRegistered = SPFactory::instance().registerObject("svg:stop", createStop);
+}
+
+SPStop::SPStop() : SPObject(), CObject(this) {
+ delete this->cobject;
+ this->cobject = this;
+
+ this->path_string = NULL;
+
+ this->offset = 0.0;
+ this->currentColor = false;
+ this->specified_color.set( 0x000000ff );
+ this->opacity = 1.0;
+}
+
+SPStop::~SPStop() {
+}
+
+void SPStop::build(SPDocument* doc, Inkscape::XML::Node* repr) {
+ SPStop* object = this;
+
+ 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 SPStop::set(unsigned int key, const gchar* value) {
+ SPStop* object = this;
+
+ 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* SPStop::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) {
+ SPStop* object = this;
+
+ 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.
+ */
+
// A stop might have some non-stop siblings
SPStop* SPStop::getNextStop()
{
@@ -80,7 +251,29 @@ SPColor SPStop::getEffectiveColor() const
return ret;
}
-
+/**
+ * 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 );
+ }
+}
/*
Local Variables:
diff --git a/src/sp-stop.h b/src/sp-stop.h
index fd0c9e001..31a9dbb5d 100644
--- a/src/sp-stop.h
+++ b/src/sp-stop.h
@@ -16,19 +16,14 @@ namespace Glib {
class ustring;
}
-#define SP_TYPE_STOP (sp_stop_get_type())
#define SP_STOP(obj) ((SPStop*)obj)
-#define SP_IS_STOP(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPStop)))
-
-GType sp_stop_get_type();
-
-class CStop;
+#define SP_IS_STOP(obj) (dynamic_cast<const SPStop*>((SPObject*)obj))
/** Gradient stop. */
-class SPStop : public SPObject {
+class SPStop : public SPObject, public CObject {
public:
SPStop();
- CStop* cstop;
+ virtual ~SPStop();
/// \todo fixme: Should be SPSVGPercentage
gfloat offset;
@@ -54,25 +49,9 @@ public:
SPColor getEffectiveColor() const;
-};
-
-/// The SPStop vtable.
-struct SPStopClass {
- SPObjectClass parent_class;
-};
-
-
-class CStop : public CObject {
-public:
- CStop(SPStop* stop);
- virtual ~CStop();
-
virtual void build(SPDocument* doc, Inkscape::XML::Node* repr);
virtual void set(unsigned int key, const gchar* value);
virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags);
-
-protected:
- SPStop* spstop;
};
diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp
index f2b9fb02a..0fbc09df8 100644
--- a/src/ui/clipboard.cpp
+++ b/src/ui/clipboard.cpp
@@ -61,9 +61,8 @@
#include "sp-shape.h"
#include "sp-gradient.h"
#include "sp-gradient-reference.h"
-#include "sp-gradient-fns.h"
-#include "sp-linear-gradient-fns.h"
-#include "sp-radial-gradient-fns.h"
+#include "sp-linear-gradient.h"
+#include "sp-radial-gradient.h"
#include "sp-clippath.h"
#include "sp-mask.h"
#include "sp-textpath.h"
diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp
index 90cb1cdc9..2884de173 100644
--- a/src/ui/dialog/swatches.cpp
+++ b/src/ui/dialog/swatches.cpp
@@ -42,7 +42,6 @@
#include "path-prefix.h"
#include "preferences.h"
#include "sp-item.h"
-#include "sp-gradient-fns.h"
#include "sp-gradient.h"
#include "sp-gradient-vector.h"
#include "style.h"
diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp
index 18dbb984b..8cb0c5588 100644
--- a/src/ui/widget/selected-style.cpp
+++ b/src/ui/widget/selected-style.cpp
@@ -24,8 +24,8 @@
#include "style.h"
#include "desktop-style.h"
#include "sp-namedview.h"
-#include "sp-linear-gradient-fns.h"
-#include "sp-radial-gradient-fns.h"
+#include "sp-linear-gradient.h"
+#include "sp-radial-gradient.h"
#include "sp-pattern.h"
#include "ui/dialog/dialog-manager.h"
#include "ui/dialog/fill-and-stroke.h"
diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp
index a89f42575..2880961be 100644
--- a/src/ui/widget/style-swatch.cpp
+++ b/src/ui/widget/style-swatch.cpp
@@ -20,8 +20,8 @@
#include "ui/widget/color-preview.h"
#include "style.h"
-#include "sp-linear-gradient-fns.h"
-#include "sp-radial-gradient-fns.h"
+#include "sp-linear-gradient.h"
+#include "sp-radial-gradient.h"
#include "sp-pattern.h"
#include "xml/repr.h"
#include "xml/sp-css-attr.h"
diff --git a/src/widgets/gradient-image.cpp b/src/widgets/gradient-image.cpp
index 2d58355db..0ed0e5546 100644
--- a/src/widgets/gradient-image.cpp
+++ b/src/widgets/gradient-image.cpp
@@ -16,7 +16,6 @@
#include "display/cairo-utils.h"
#include "gradient-image.h"
#include "sp-gradient.h"
-#include "sp-gradient-fns.h"
#include <sigc++/functors/ptr_fun.h>
#include <sigc++/adaptors/bind.h>
diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp
index b0738b6a6..3509bf6b2 100644
--- a/src/widgets/paint-selector.cpp
+++ b/src/widgets/paint-selector.cpp
@@ -33,8 +33,8 @@
#include "xml/repr.h"
#include "sp-color-notebook.h"
-#include "sp-linear-gradient-fns.h"
-#include "sp-radial-gradient-fns.h"
+#include "sp-linear-gradient.h"
+#include "sp-radial-gradient.h"
/* fixme: Move it from dialogs to here */
#include "gradient-selector.h"
#include <inkscape.h>