diff options
Diffstat (limited to 'src/object/persp3d.cpp')
| -rw-r--r-- | src/object/persp3d.cpp | 75 |
1 files changed, 49 insertions, 26 deletions
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()); } } |
