summaryrefslogtreecommitdiffstats
path: root/src/object
diff options
context:
space:
mode:
authorThomas Holder <thomas@thomas-holder.de>2018-09-12 14:43:47 +0000
committerThomas Holder <thomas@thomas-holder.de>2018-09-12 14:43:47 +0000
commit1fa0c72b664afa4803dffd463ed11ce01632ab76 (patch)
treec1f746d4e8f7a5d65541cf6c05d3cdc79b3f9c10 /src/object
parentFix preferences crash (diff)
downloadinkscape-1fa0c72b664afa4803dffd463ed11ce01632ab76.tar.gz
inkscape-1fa0c72b664afa4803dffd463ed11ce01632ab76.zip
New option to invert y-axis
Replaces all hard coded or implicit desktop coordinate usage with doc2dt multiplication. New global preference: Interface > Origin at upper left https://bugs.launchpad.net/inkscape/+bug/170049
Diffstat (limited to 'src/object')
-rw-r--r--src/object/box3d.cpp17
-rw-r--r--src/object/persp3d.cpp75
-rw-r--r--src/object/sp-guide.cpp31
-rw-r--r--src/object/sp-item.cpp3
4 files changed, 95 insertions, 31 deletions
diff --git a/src/object/box3d.cpp b/src/object/box3d.cpp
index df95f4f84..7be7c10f7 100644
--- a/src/object/box3d.cpp
+++ b/src/object/box3d.cpp
@@ -149,6 +149,9 @@ void SPBox3D::set(unsigned int key, const gchar* value) {
case SP_ATTR_INKSCAPE_BOX3D_CORNER0:
if (value && strcmp(value, "0 : 0 : 0 : 0")) {
box->orig_corner0 = Proj::Pt3(value);
+ if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->is_yaxisdown()) {
+ box->orig_corner0[Proj::Y] *= -1;
+ }
box->save_corner0 = box->orig_corner0;
box3d_position_set(box);
}
@@ -156,6 +159,9 @@ void SPBox3D::set(unsigned int key, const gchar* value) {
case SP_ATTR_INKSCAPE_BOX3D_CORNER7:
if (value && strcmp(value, "0 : 0 : 0 : 0")) {
box->orig_corner7 = Proj::Pt3(value);
+ if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->is_yaxisdown()) {
+ box->orig_corner7[Proj::Y] *= -1;
+ }
box->save_corner7 = box->orig_corner7;
box3d_position_set(box);
}
@@ -227,8 +233,15 @@ Inkscape::XML::Node* SPBox3D::write(Inkscape::XML::Document *xml_doc, Inkscape::
}
}
- gchar *coordstr0 = box->orig_corner0.coord_string();
- gchar *coordstr7 = box->orig_corner7.coord_string();
+ auto corner0 = box->orig_corner0;
+ auto corner7 = box->orig_corner7;
+ if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->is_yaxisdown()) {
+ corner0[Proj::Y] *= -1;
+ corner7[Proj::Y] *= -1;
+ }
+
+ gchar *coordstr0 = corner0.coord_string();
+ gchar *coordstr7 = corner7.coord_string();
repr->setAttribute("inkscape:corner0", coordstr0);
repr->setAttribute("inkscape:corner7", coordstr7);
g_free(coordstr0);
diff --git a/src/object/persp3d.cpp b/src/object/persp3d.cpp
index 2183b6236..05ba5898b 100644
--- a/src/object/persp3d.cpp
+++ b/src/object/persp3d.cpp
@@ -84,6 +84,43 @@ void Persp3D::release() {
this->getRepr()->removeListenerByData(this);
}
+/**
+ * Apply viewBox and legacy desktop transformation to point loaded from SVG
+ */
+static Proj::Pt2 legacy_transform_forward(Proj::Pt2 pt, SPDocument const *doc) {
+ // Read values are in 'user units'.
+ auto root = doc->getRoot();
+ if (root->viewBox_set) {
+ pt[0] *= root->width.computed / root->viewBox.width();
+ pt[1] *= root->height.computed / root->viewBox.height();
+ }
+
+ // <inkscape:perspective> stores inverted y-axis coordinates
+ if (pt[2] && SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->is_yaxisdown()) {
+ pt[1] = doc->getHeight().value("px") - pt[1];
+ }
+
+ return pt;
+}
+
+/**
+ * Apply viewBox and legacy desktop transformation to point to be written to SVG
+ */
+static Proj::Pt2 legacy_transform_backward(Proj::Pt2 pt, SPDocument const *doc) {
+ // <inkscape:perspective> stores inverted y-axis coordinates
+ if (pt[2] && SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->is_yaxisdown()) {
+ pt[1] = doc->getHeight().value("px") - pt[1];
+ }
+
+ // Written values are in 'user units'.
+ auto root = doc->getRoot();
+ if (root->viewBox_set) {
+ pt[0] *= root->viewBox.width() / root->width.computed;
+ pt[1] *= root->viewBox.height() / root->height.computed;
+ }
+
+ return pt;
+}
/**
* Virtual set: set attribute to value.
@@ -92,20 +129,11 @@ void Persp3D::release() {
// should we move VPs into their own repr (as it's done for SPStop, e.g.)?
void Persp3D::set(unsigned key, gchar const *value) {
- // Read values are in 'user units'.
- double scale_x = 1.0;
- double scale_y = 1.0;
- SPRoot *root = document->getRoot();
- if( root->viewBox_set ) {
- scale_x = root->width.computed / root->viewBox.width();
- scale_y = root->height.computed / root->viewBox.height();
- }
-
switch (key) {
case SP_ATTR_INKSCAPE_PERSP3D_VP_X: {
if (value) {
Proj::Pt2 pt (value);
- Proj::Pt2 ptn ( pt[0]*scale_x, pt[1]*scale_y, pt[2] );
+ Proj::Pt2 ptn = legacy_transform_forward(pt, document);
perspective_impl->tmat.set_image_pt( Proj::X, ptn );
}
break;
@@ -113,7 +141,7 @@ void Persp3D::set(unsigned key, gchar const *value) {
case SP_ATTR_INKSCAPE_PERSP3D_VP_Y: {
if (value) {
Proj::Pt2 pt (value);
- Proj::Pt2 ptn ( pt[0]*scale_x, pt[1]*scale_y, pt[2] );
+ Proj::Pt2 ptn = legacy_transform_forward(pt, document);
perspective_impl->tmat.set_image_pt( Proj::Y, ptn );
}
break;
@@ -121,7 +149,7 @@ void Persp3D::set(unsigned key, gchar const *value) {
case SP_ATTR_INKSCAPE_PERSP3D_VP_Z: {
if (value) {
Proj::Pt2 pt (value);
- Proj::Pt2 ptn ( pt[0]*scale_x, pt[1]*scale_y, pt[2] );
+ Proj::Pt2 ptn = legacy_transform_forward(pt, document);
perspective_impl->tmat.set_image_pt( Proj::Z, ptn );
}
break;
@@ -129,7 +157,7 @@ void Persp3D::set(unsigned key, gchar const *value) {
case SP_ATTR_INKSCAPE_PERSP3D_ORIGIN: {
if (value) {
Proj::Pt2 pt (value);
- Proj::Pt2 ptn ( pt[0]*scale_x, pt[1]*scale_y, pt[2] );
+ Proj::Pt2 ptn = legacy_transform_forward(pt, document);
perspective_impl->tmat.set_image_pt( Proj::W, ptn );
}
break;
@@ -236,37 +264,32 @@ Inkscape::XML::Node* Persp3D::write(Inkscape::XML::Document *xml_doc, Inkscape::
}
if (flags & SP_OBJECT_WRITE_EXT) {
-
- // Written values are in 'user units'.
- double scale_x = 1.0;
- double scale_y = 1.0;
- SPRoot *root = document->getRoot();
- if( root->viewBox_set ) {
- scale_x = root->viewBox.width() / root->width.computed;
- scale_y = root->viewBox.height() / root->height.computed;
- }
{
Proj::Pt2 pt = perspective_impl->tmat.column( Proj::X );
Inkscape::SVGOStringStream os;
- os << pt[0] * scale_x << " : " << pt[1] * scale_y << " : " << pt[2];
+ pt = legacy_transform_backward(pt, document);
+ os << pt[0] << " : " << pt[1] << " : " << pt[2];
repr->setAttribute("inkscape:vp_x", os.str().c_str());
}
{
Proj::Pt2 pt = perspective_impl->tmat.column( Proj::Y );
Inkscape::SVGOStringStream os;
- os << pt[0] * scale_x << " : " << pt[1] * scale_y << " : " << pt[2];
+ pt = legacy_transform_backward(pt, document);
+ os << pt[0] << " : " << pt[1] << " : " << pt[2];
repr->setAttribute("inkscape:vp_y", os.str().c_str());
}
{
Proj::Pt2 pt = perspective_impl->tmat.column( Proj::Z );
Inkscape::SVGOStringStream os;
- os << pt[0] * scale_x << " : " << pt[1] * scale_y << " : " << pt[2];
+ pt = legacy_transform_backward(pt, document);
+ os << pt[0] << " : " << pt[1] << " : " << pt[2];
repr->setAttribute("inkscape:vp_z", os.str().c_str());
}
{
Proj::Pt2 pt = perspective_impl->tmat.column( Proj::W );
Inkscape::SVGOStringStream os;
- os << pt[0] * scale_x << " : " << pt[1] * scale_y << " : " << pt[2];
+ pt = legacy_transform_backward(pt, document);
+ os << pt[0] << " : " << pt[1] << " : " << pt[2];
repr->setAttribute("inkscape:persp3d-origin", os.str().c_str());
}
}
diff --git a/src/object/sp-guide.cpp b/src/object/sp-guide.cpp
index 0b8558230..acb0707d0 100644
--- a/src/object/sp-guide.cpp
+++ b/src/object/sp-guide.cpp
@@ -131,6 +131,12 @@ void SPGuide::set(unsigned int key, const gchar *value) {
g_strfreev (strarray);
if (success == 2 && (fabs(newx) > 1e-6 || fabs(newy) > 1e-6)) {
Geom::Point direction(newx, newy);
+
+ // <sodipodi:guide> stores inverted y-axis coordinates
+ if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->is_yaxisdown()) {
+ direction[Geom::Y] *= -1.0;
+ }
+
direction.normalize();
this->normal_to_line = direction;
} else {
@@ -176,6 +182,11 @@ void SPGuide::set(unsigned int key, const gchar *value) {
this->point_on_line = Geom::Point(newx, 0);
}
}
+
+ // <sodipodi:guide> stores inverted y-axis coordinates
+ if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->is_yaxisdown()) {
+ this->point_on_line[Geom::Y] = document->getHeight().value("px") - this->point_on_line[Geom::Y];
+ }
} else {
// default to (0,0) for bad arguments
this->point_on_line = Geom::Point(0,0);
@@ -217,6 +228,12 @@ SPGuide *SPGuide::createSPGuide(SPDocument *doc, Geom::Point const &pt1, Geom::P
}
}
+ // <sodipodi:guide> stores inverted y-axis coordinates
+ if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->is_yaxisdown()) {
+ newy = doc->getHeight().value("px") - newy;
+ n[Geom::Y] *= -1.0;
+ }
+
sp_repr_set_point(repr, "position", Geom::Point( newx, newy ));
sp_repr_set_point(repr, "orientation", n);
@@ -368,6 +385,11 @@ void SPGuide::moveto(Geom::Point const point_on_line, bool const commit)
double newx = point_on_line.x();
double newy = point_on_line.y();
+ // <sodipodi:guide> stores inverted y-axis coordinates
+ if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->is_yaxisdown()) {
+ newy = document->getHeight().value("px") - newy;
+ }
+
SPRoot *root = document->getRoot();
if( root->viewBox_set ) {
// check to see if scaling is uniform
@@ -414,7 +436,14 @@ void SPGuide::set_normal(Geom::Point const normal_to_line, bool const commit)
case, so that the guide's new position is available for sp_item_rm_unsatisfied_cns. */
if (commit) {
//XML Tree being used directly while it shouldn't be
- sp_repr_set_point(getRepr(), "orientation", normal_to_line);
+ auto normal = normal_to_line;
+
+ // <sodipodi:guide> stores inverted y-axis coordinates
+ if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->is_yaxisdown()) {
+ normal[Geom::Y] *= -1.0;
+ }
+
+ sp_repr_set_point(getRepr(), "orientation", normal);
}
/* DISABLED CODE BECAUSE SPGuideAttachment IS NOT USE AT THE MOMENT (johan)
diff --git a/src/object/sp-item.cpp b/src/object/sp-item.cpp
index d7c461f92..474687cc6 100644
--- a/src/object/sp-item.cpp
+++ b/src/object/sp-item.cpp
@@ -918,8 +918,7 @@ Geom::OptRect SPItem::desktopGeometricBounds() const
Geom::OptRect SPItem::desktopVisualBounds() const
{
- /// @fixme hardcoded desktop transform
- Geom::Affine m = Geom::Scale(1, -1) * Geom::Translate(0, document->getHeight().value("px"));
+ Geom::Affine const& m = SP_ACTIVE_DESKTOP->doc2dt();
Geom::OptRect ret = documentVisualBounds();
if (ret) *ret *= m;
return ret;