summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/attributes.cpp1
-rw-r--r--src/attributes.h1
-rw-r--r--src/document.cpp6
-rw-r--r--src/sp-namedview.cpp47
-rw-r--r--src/sp-namedview.h1
-rw-r--r--src/ui/dialog/export.cpp12
-rw-r--r--src/viewbox.cpp82
-rw-r--r--src/viewbox.h12
8 files changed, 148 insertions, 14 deletions
diff --git a/src/attributes.cpp b/src/attributes.cpp
index b06ff6048..cc75d94c6 100644
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
@@ -89,6 +89,7 @@ static SPStyleProp const props[] = {
{SP_ATTR_INKSCAPE_ZOOM, "inkscape:zoom"},
{SP_ATTR_INKSCAPE_CX, "inkscape:cx"},
{SP_ATTR_INKSCAPE_CY, "inkscape:cy"},
+ {SP_ATTR_INKSCAPE_DOCUMENT_ROTATION, "inkscape:document-rotation"},
{SP_ATTR_INKSCAPE_WINDOW_WIDTH, "inkscape:window-width"},
{SP_ATTR_INKSCAPE_WINDOW_HEIGHT, "inkscape:window-height"},
{SP_ATTR_INKSCAPE_WINDOW_X, "inkscape:window-x"},
diff --git a/src/attributes.h b/src/attributes.h
index ff426e8cf..ba82c18f1 100644
--- a/src/attributes.h
+++ b/src/attributes.h
@@ -97,6 +97,7 @@ enum SPAttributeEnum {
SP_ATTR_INKSCAPE_ZOOM,
SP_ATTR_INKSCAPE_CX,
SP_ATTR_INKSCAPE_CY,
+ SP_ATTR_INKSCAPE_DOCUMENT_ROTATION,
SP_ATTR_INKSCAPE_WINDOW_WIDTH,
SP_ATTR_INKSCAPE_WINDOW_HEIGHT,
SP_ATTR_INKSCAPE_WINDOW_X,
diff --git a/src/document.cpp b/src/document.cpp
index 920e47cb8..a371fe1e5 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -386,6 +386,7 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc,
if (!bordercolor.empty()) {
rnew->setAttribute("bordercolor", bordercolor.data());
}
+ sp_repr_set_svg_double(rnew, "inkscape:document-rotation", 0.);
sp_repr_set_svg_double(rnew, "borderopacity",
prefs->getDouble("/template/base/borderopacity", 1.0));
sp_repr_set_svg_double(rnew, "objecttolerance",
@@ -407,6 +408,11 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc,
rroot->addChild(rnew, NULL);
// clean up
Inkscape::GC::release(rnew);
+ } else {
+ Inkscape::XML::Node *nv_repr = sp_item_group_get_child_by_name(document->root, NULL, "sodipodi:namedview")->getRepr();
+ if (!nv_repr->attribute("inkscape:document-rotation")) {
+ sp_repr_set_svg_double(nv_repr, "inkscape:document-rotation", 0.);
+ }
}
// Defs
diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp
index b9526433f..69fc78b33 100644
--- a/src/sp-namedview.cpp
+++ b/src/sp-namedview.cpp
@@ -29,12 +29,14 @@
#include "desktop-events.h"
#include "sp-guide.h"
+#include "sp-root.h"
#include "sp-item-group.h"
#include "sp-namedview.h"
#include "preferences.h"
#include "desktop.h"
+#include "selection.h"
+#include "inkscape.h"
#include "conn-avoid-ref.h" // for defaultConnSpacing.
-#include "sp-root.h"
#include <gtkmm/window.h>
using Inkscape::DocumentUndo;
@@ -49,6 +51,7 @@ using Inkscape::Util::unit_table;
#define DEFAULTPAGECOLOR 0xffffff00
static void sp_namedview_setup_guides(SPNamedView * nv);
+static void sp_namedview_set_document_rotation(SPDocument * doc, SPNamedView * nv);
static void sp_namedview_lock_guides(SPNamedView * nv);
static void sp_namedview_show_single_guide(SPGuide* guide, bool show);
static void sp_namedview_lock_single_guide(SPGuide* guide, bool show);
@@ -72,6 +75,7 @@ SPNamedView::SPNamedView() : SPObjectGroup(), snap_manager(this) {
this->pagecolor = 0;
this->cx = 0;
this->pageshadow = 0;
+ this->document_rotation = 0;
this->window_width = 0;
this->window_height = 0;
this->window_maximized = 0;
@@ -212,6 +216,7 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) {
this->readAttr( "inkscape:zoom" );
this->readAttr( "inkscape:cx" );
this->readAttr( "inkscape:cy" );
+ this->readAttr( "inkscape:document-rotation" );
this->readAttr( "inkscape:window-width" );
this->readAttr( "inkscape:window-height" );
this->readAttr( "inkscape:window-x" );
@@ -409,6 +414,13 @@ void SPNamedView::set(unsigned int key, const gchar* value) {
this->cy = value ? g_ascii_strtod(value, NULL) : HUGE_VAL; // HUGE_VAL means not set
this->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
+ case SP_ATTR_INKSCAPE_DOCUMENT_ROTATION:
+ this->document_rotation = value ? g_ascii_strtod(value, NULL) : 0; // zero means not set
+ if (value && document) {
+ sp_namedview_set_document_rotation(document, this);
+ }
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
case SP_ATTR_INKSCAPE_WINDOW_WIDTH:
this->window_width = value? atoi(value) : -1; // -1 means not set
this->requestModified(SP_OBJECT_MODIFIED_FLAG);
@@ -939,6 +951,39 @@ static void sp_namedview_lock_guides(SPNamedView *nv)
}
}
+static void sp_namedview_set_document_rotation(SPDocument *doc, SPNamedView *nv)
+{
+ SPDesktop * desktop = SP_ACTIVE_DESKTOP;
+ Geom::Rect area;
+ Geom::Point p = Geom::Point();
+ if (desktop) {
+ area = desktop->get_display_area();
+ p = area.midpoint();
+ p *= desktop->doc2dt();
+ p *= doc->getRoot()->rotation.inverse();
+ }
+ doc->getRoot()->set_rotation(nv->document_rotation);
+ if (nv->document_rotation) {
+ nv->showborder = FALSE;
+ } else {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ nv->showborder = prefs->getBool("/template/base/showborder", 1.0);
+ }
+ if (desktop) {
+ p *= doc->getRoot()->rotation;
+ //desktop->scroll_world_in_svg_coords (p[Geom::X], p[Geom::Y], true);
+ // *= doc->getRoot()->c2p * doc->getRoot()->rotation();
+ //desktop->zoom_absolute (p[Geom::X], p[Geom::Y], desktop->current_zoom());
+ std::cout << p << "pppppp\n";
+// Geom::Point min_pt = Geom::Point(p[Geom::X] - (area.width() / 2.0), p[Geom::Y] - (area.height() / 2.0));
+// Geom::Point max_pt = Geom::Point(p[Geom::X] + (area.width() / 2.0), p[Geom::Y] + (area.height() / 2.0));
+// Geom::Rect const new_area(min_pt, max_pt);
+// desktop->set_display_area (new_area, 0, false);
+ Inkscape::Selection * sel = desktop->getSelection();
+ sel->clear();
+ }
+}
+
static void sp_namedview_show_single_guide(SPGuide* guide, bool show)
{
if (show) {
diff --git a/src/sp-namedview.h b/src/sp-namedview.h
index d8ac1a77e..9e523632d 100644
--- a/src/sp-namedview.h
+++ b/src/sp-namedview.h
@@ -54,6 +54,7 @@ public:
double zoom;
double cx;
double cy;
+ double document_rotation;
int window_width;
int window_height;
int window_x;
diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp
index 64a5d9866..f0d54d784 100644
--- a/src/ui/dialog/export.cpp
+++ b/src/ui/dialog/export.cpp
@@ -975,7 +975,12 @@ void Export::onExport ()
SPNamedView *nv = desktop->getNamedView();
SPDocument *doc = desktop->getDocument();
-
+ Geom::Affine rot = doc->getRoot()->c2p;
+ doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
+ //double rotate_angle = doc->getRoot()->get_rotation();
+ //Inkscape::XML::Node *nv_repr = sp_item_group_get_child_by_name(doc->getRoot(), NULL, "sodipodi:namedview")->getRepr();
+ //sp_repr_set_svg_double(nv_repr, "inkscape:document-rotation", 0.);
+ doc->ensureUpToDate();
bool exportSuccessful = false;
bool hide = hide_export.get_active ();
@@ -999,6 +1004,7 @@ void Export::onExport ()
if (num < 1) {
desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No items selected."));
+ doc->getRoot()->c2p *= doc->getRoot()->rotation;
return;
}
@@ -1090,6 +1096,7 @@ void Export::onExport ()
if (filename.empty()) {
desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You have to enter a filename."));
sp_ui_error_dialog(_("You have to enter a filename"));
+ doc->getRoot()->c2p *= doc->getRoot()->rotation;
return;
}
@@ -1106,6 +1113,7 @@ void Export::onExport ()
if (!((x1 > x0) && (y1 > y0) && (width > 0) && (height > 0))) {
desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("The chosen area to be exported is invalid."));
sp_ui_error_dialog(_("The chosen area to be exported is invalid"));
+ doc->getRoot()->c2p *= doc->getRoot()->rotation;
return;
}
@@ -1128,6 +1136,7 @@ void Export::onExport ()
g_free(safeDir);
g_free(error);
+ doc->getRoot()->c2p *= doc->getRoot()->rotation;
return;
}
@@ -1277,6 +1286,7 @@ void Export::onExport ()
}
}
}
+ doc->getRoot()->c2p *= doc->getRoot()->rotation;
} // end of sp_export_export_clicked()
/// Called when Browse button is clicked
diff --git a/src/viewbox.cpp b/src/viewbox.cpp
index 1b50fe71c..e40e477ef 100644
--- a/src/viewbox.cpp
+++ b/src/viewbox.cpp
@@ -17,6 +17,12 @@
#include "viewbox.h"
#include "enums.h"
#include "sp-item.h"
+#include "display/sp-canvas-group.h"
+#include "display/canvas-bpath.h"
+#include "display/curve.h"
+#include "inkscape.h"
+#include "desktop.h"
+
SPViewBox::SPViewBox()
: viewBox_set(false)
@@ -25,6 +31,8 @@ SPViewBox::SPViewBox()
, aspect_align(SP_ASPECT_XMID_YMID) // Default per spec
, aspect_clip(SP_ASPECT_MEET)
, c2p(Geom::identity())
+ , rotation(Geom::identity())
+ , angle(0)
{
}
@@ -159,6 +167,14 @@ void SPViewBox::set_preserveAspectRatio(const gchar* value) {
}
}
+double SPViewBox::get_rotation() {
+ return this->angle;
+}
+
+void SPViewBox::set_rotation(double angle_val) {
+ this->angle = angle_val;
+}
+
// Apply scaling from viewbox
void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) {
@@ -224,18 +240,60 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) {
}
/* Viewbox transform from scale and position */
- Geom::Affine q;
- q[0] = scale_x;
- q[1] = 0.0;
- q[2] = 0.0;
- q[3] = scale_y;
- q[4] = x - scale_x * this->viewBox.left();
- q[5] = y - scale_y * this->viewBox.top();
-
- // std::cout << " q\n" << q << std::endl;
-
- /* Append viewbox transformation */
- this->c2p = q * this->c2p;
+ Geom::Affine vbt = Geom::identity();
+ vbt[0] = scale_x;
+ vbt[1] = 0.0;
+ vbt[2] = 0.0;
+ vbt[3] = scale_y;
+ vbt[4] = x - scale_x * this->viewBox.left();
+ vbt[5] = y - scale_y * this->viewBox.top();
+ // std::cout << " q\n" << q << std::endl
+ /* Append viewbox and turn transformation */
+ if (this->angle > 0.0 || this->angle < 0.0 ) { //!0
+ Geom::Point r0 = this->viewBox.min();
+ Geom::Point r1 = this->viewBox.max();
+ Geom::Point p = (r0 + r1) / 2;
+ SPDesktop * desktop = SP_ACTIVE_DESKTOP;
+ SPCanvasItem *vw_rot = NULL;
+ if (desktop) {
+ if (this->page_border_rotated) {
+ desktop->remove_temporary_canvasitem(this->page_border_rotated);
+ this->page_border_rotated = NULL;
+ }
+ SPCurve *c = new SPCurve();
+ c->moveto(this->viewBox.min());
+ c->lineto(Geom::Point(this->viewBox.max()[Geom::X],this->viewBox.min()[Geom::Y]));
+ c->lineto(Geom::Point(this->viewBox.max()[Geom::X],this->viewBox.max()[Geom::Y]));
+ c->lineto(Geom::Point(this->viewBox.min()[Geom::X],this->viewBox.max()[Geom::Y]));
+ c->closepath();
+ vw_rot = sp_canvas_bpath_new(desktop->getTempGroup(), c, true);
+ sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(vw_rot), 0xFF00009A, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
+ sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(vw_rot), 0, SP_WIND_RULE_NONZERO);
+ this->page_border_rotated = desktop->add_temporary_canvasitem(vw_rot, 0);
+ Geom::PathVector const box = c->get_pathvector();
+ Geom::OptRect bbox = box.boundsFast();
+ if (bbox){
+ r0 = (*bbox).min();
+ r1 = (*bbox).max();
+ p = (r0 + r1) / 2;
+ }
+ Geom::Affine rot = Geom::identity();
+ rot *= Geom::Translate(p).inverse() * Geom::Rotate(Geom::rad_from_deg(-angle)) * Geom::Translate(p);
+ sp_canvas_item_affine_absolute(vw_rot, rot * vbt);
+ this->page_border_rotated = desktop->add_temporary_canvasitem(vw_rot, 0);
+ }
+ rotation = Geom::Translate(p).inverse() * Geom::Rotate(Geom::rad_from_deg(angle)) * Geom::Translate(p);
+ this->c2p = rotation * vbt * this->c2p;
+ } else {
+ SPDesktop * desktop = SP_ACTIVE_DESKTOP;
+ if (desktop) {
+ if (this->page_border_rotated) {
+ desktop->remove_temporary_canvasitem(this->page_border_rotated);
+ this->page_border_rotated = NULL;
+ }
+ }
+ this->c2p = vbt * this->c2p;
+ }
}
SPItemCtx SPViewBox::get_rctx(const SPItemCtx* ictx, double scale_none) {
diff --git a/src/viewbox.h b/src/viewbox.h
index c71abb610..df47c025b 100644
--- a/src/viewbox.h
+++ b/src/viewbox.h
@@ -17,6 +17,13 @@
#include <2geom/rect.h>
#include <glib.h>
+#include "display/sp-canvas.h"
+
+namespace Inkscape {
+ namespace Display {
+ class TemporaryItem;
+ }
+}
class SPItemCtx;
@@ -36,6 +43,11 @@ public:
/* Child to parent additional transform */
Geom::Affine c2p;
+ Geom::Affine rotation;
+ double angle;
+ double get_rotation();
+ void set_rotation(double angle_val);
+ Inkscape::Display::TemporaryItem *page_border_rotated;
void set_viewBox(const gchar* value);
void set_preserveAspectRatio(const gchar* value);