summaryrefslogtreecommitdiffstats
path: root/src/object/sp-mesh-gradient.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 11:50:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 11:50:49 +0000
commitc853ffb5b2f75f5a889ed2e3ef89b818a736e87a (patch)
tree7d13a0883bb7936b84d6ecdd7bc332b41ed04bee /src/object/sp-mesh-gradient.cpp
parentInitial commit. (diff)
downloadinkscape-c853ffb5b2f75f5a889ed2e3ef89b818a736e87a.tar.xz
inkscape-c853ffb5b2f75f5a889ed2e3ef89b818a736e87a.zip
Adding upstream version 1.3+ds.upstream/1.3+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/object/sp-mesh-gradient.cpp')
-rw-r--r--src/object/sp-mesh-gradient.cpp231
1 files changed, 231 insertions, 0 deletions
diff --git a/src/object/sp-mesh-gradient.cpp b/src/object/sp-mesh-gradient.cpp
new file mode 100644
index 0000000..4bbc455
--- /dev/null
+++ b/src/object/sp-mesh-gradient.cpp
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/** @file
+ * TODO: insert short description here
+ *//*
+ * Authors: see git history
+ *
+ * Copyright (C) 2018 Authors
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+#include <glibmm.h>
+
+#include "attributes.h"
+#include "display/cairo-utils.h"
+#include "display/drawing-paintserver.h"
+
+#include "sp-mesh-gradient.h"
+
+/*
+ * Mesh Gradient
+ */
+//#define MESH_DEBUG
+//#define OBJECT_TRACE
+
+SPMeshGradient::SPMeshGradient() : SPGradient(), type( SP_MESH_TYPE_COONS ), type_set(false) {
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMeshGradient::SPMeshGradient" );
+#endif
+
+ // Start coordinate of mesh
+ this->x.unset(SVGLength::NONE, 0.0, 0.0);
+ this->y.unset(SVGLength::NONE, 0.0, 0.0);
+
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMeshGradient::SPMeshGradient", false );
+#endif
+}
+
+SPMeshGradient::~SPMeshGradient() {
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMeshGradient::~SPMeshGradient (empty function)" );
+ objectTrace( "SPMeshGradient::~SPMeshGradient", false );
+#endif
+}
+
+void SPMeshGradient::build(SPDocument *document, Inkscape::XML::Node *repr) {
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMeshGradient::build" );
+#endif
+
+ SPGradient::build(document, repr);
+
+ // Start coordinate of meshgradient
+ this->readAttr(SPAttr::X);
+ this->readAttr(SPAttr::Y);
+
+ this->readAttr(SPAttr::TYPE);
+
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMeshGradient::build", false );
+#endif
+}
+
+
+void SPMeshGradient::set(SPAttr key, gchar const *value) {
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMeshGradient::set" );
+#endif
+
+ switch (key) {
+ case SPAttr::X:
+ if (!this->x.read(value)) {
+ this->x.unset(SVGLength::NONE, 0.0, 0.0);
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SPAttr::Y:
+ if (!this->y.read(value)) {
+ this->y.unset(SVGLength::NONE, 0.0, 0.0);
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SPAttr::TYPE:
+ if (value) {
+ if (!strcmp(value, "coons")) {
+ this->type = SP_MESH_TYPE_COONS;
+ } else if (!strcmp(value, "bicubic")) {
+ this->type = SP_MESH_TYPE_BICUBIC;
+ } else {
+ std::cerr << "SPMeshGradient::set(): invalid value " << value << std::endl;
+ }
+ this->type_set = TRUE;
+ } else {
+ // std::cout << "SPMeshGradient::set() No value " << std::endl;
+ this->type = SP_MESH_TYPE_COONS;
+ this->type_set = FALSE;
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ default:
+ SPGradient::set(key, value);
+ break;
+ }
+
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMeshGradient::set", false );
+#endif
+}
+
+/**
+ * Write mesh gradient attributes to associated repr.
+ */
+Inkscape::XML::Node* SPMeshGradient::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMeshGradient::write", false );
+#endif
+
+ if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
+ repr = xml_doc->createElement("svg:meshgradient");
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->x._set) {
+ repr->setAttributeSvgDouble("x", this->x.computed);
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->y._set) {
+ repr->setAttributeSvgDouble("y", this->y.computed);
+ }
+
+ if ((flags & SP_OBJECT_WRITE_ALL) || this->type_set) {
+ switch (this->type) {
+ case SP_MESH_TYPE_COONS:
+ repr->setAttribute("type", "coons");
+ break;
+ case SP_MESH_TYPE_BICUBIC:
+ repr->setAttribute("type", "bicubic");
+ break;
+ default:
+ // Do nothing
+ break;
+ }
+ }
+
+ SPGradient::write(xml_doc, repr, flags);
+
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMeshGradient::write", false );
+#endif
+ return repr;
+}
+
+std::unique_ptr<Inkscape::DrawingPaintServer> SPMeshGradient::create_drawing_paintserver()
+{
+ ensureArray();
+
+ SPMeshNodeArray* my_array = &array;
+
+ if (type_set) {
+ switch (type) {
+ case SP_MESH_TYPE_COONS:
+ // std::cout << "SPMeshGradient::pattern_new: Coons" << std::endl;
+ break;
+ case SP_MESH_TYPE_BICUBIC:
+ array.bicubic(&array_smoothed, type);
+ my_array = &array_smoothed;
+ break;
+ }
+ }
+
+ int rows = my_array->patch_rows();
+ int cols = my_array->patch_columns();
+
+ std::vector<std::vector<Inkscape::DrawingMeshGradient::PatchData>> patchdata;
+ patchdata.resize(rows);
+ for (auto &row : patchdata) {
+ row.resize(cols);
+ }
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ auto patch = SPMeshPatchI(&my_array->nodes, i, j);
+ auto &data = patchdata[i][j];
+
+ for (int x = 0; x < 4; x++) {
+ for (int y = 0; y < 4; y++) {
+ data.points[x][y] = patch.getPoint(x, y);
+ }
+ }
+
+ for (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
+
+ data.pathtype[k] = patch.getPathType(k);
+
+ if (patch.tensorIsSet(k)) {
+ data.tensorIsSet[k] = true;
+ data.tensorpoints[k] = patch.getTensorPoint(k);
+ //auto t = patch.getTensorPoint(k);
+ //std::cout << " sp_mesh_create_pattern: tensor " << k
+ // << " set to " << t << "." << std::endl;
+ } else {
+ data.tensorIsSet[k] = false;
+ //auto t = patch.coonsTensorPoint(k);
+ //std::cout << " sp_mesh_create_pattern: tensor " << k
+ // << " calculated as " << t << "." << std::endl;
+ }
+
+ auto color = patch.getColor(k);
+ for (int r = 0; r < 3; r++) {
+ data.color[k][r] = color.v.c[r];
+ }
+
+ data.opacity[k] = patch.getOpacity(k);
+ }
+ }
+ }
+
+ return std::make_unique<Inkscape::DrawingMeshGradient>(getSpread(), getUnits(), gradientTransform,
+ rows, cols, std::move(patchdata));
+}