summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: fce0467)
raw | patch | inline | side by side (parent: fce0467)
author | Maximilian Albert <maximilian.albert@gmail.com> | |
Sat, 26 Dec 2009 00:32:25 +0000 (01:32 +0100) | ||
committer | Maximilian Albert <maximilian.albert@gmail.com> | |
Sat, 26 Dec 2009 00:32:25 +0000 (01:32 +0100) |
diff --git a/src/box3d.cpp b/src/box3d.cpp
index 460465637de0d0e1f1290f40733cf3fb8f74105a..aa2dc55e36cad3b833b26d9c1a17108f68d68c13 100644 (file)
--- a/src/box3d.cpp
+++ b/src/box3d.cpp
if (old_ref) {
sp_signal_disconnect_by_data(old_ref, box);
persp3d_remove_box (SP_PERSP3D(old_ref), box);
- /* Note: This sometimes leads to attempts to remove boxes twice from the list of selected/transformed
- boxes in a perspectives, but this should be uncritical. */
- persp3d_remove_box_transform (SP_PERSP3D(old_ref), box);
}
if ( SP_IS_PERSP3D(ref) && ref != box ) // FIXME: Comparisons sane?
{
persp3d_add_box (SP_PERSP3D(ref), box);
- /* Note: This sometimes leads to attempts to add boxes twice to the list of selected/transformed
- boxes in a perspectives, but this should be uncritical. */
- persp3d_add_box_transform (SP_PERSP3D(ref), box);
}
}
{
SPBox3D *box = SP_BOX3D(item);
- /* check whether we need to unlink any boxes from their perspectives */
- Persp3D *persp = box3d_get_perspective(box);
- Persp3D *transf_persp;
-
- if (sp_desktop_document(inkscape_active_desktop()) == SP_OBJECT_DOCUMENT(item) &&
- !persp3d_has_all_boxes_in_selection (persp)) {
- std::list<SPBox3D *> selboxes = sp_desktop_selection(inkscape_active_desktop())->box3DList();
-
- /* create a new perspective as a copy of the current one and link the selected boxes to it */
- transf_persp = persp3d_create_xml_element (SP_OBJECT_DOCUMENT(persp), persp->perspective_impl);
-
- for (std::list<SPBox3D *>::iterator b = selboxes.begin(); b != selboxes.end(); ++b) {
- box3d_switch_perspectives(*b, persp, transf_persp);
- }
- } else {
- transf_persp = persp;
- }
-
- /* only transform the perspective once, even if it has several selected boxes */
- if(!persp3d_was_transformed (transf_persp)) {
- /* concatenate the affine transformation with the perspective mapping; this
- function also triggers repr updates of boxes and the perspective itself */
- persp3d_apply_affine_transformation(transf_persp, xform);
- }
-
- box3d_mark_transformed(box);
-
- if (persp3d_all_transformed(transf_persp)) {
- /* all boxes were transformed; make perspective sensitive for further transformations */
- persp3d_unset_transforms(transf_persp);
- }
+ // We don't apply the transform to the box directly but instead to its perspective (which is
+ // done in sp_selection_apply_affine). Here we only adjust strokes, patterns, etc.
Geom::Matrix ret(Geom::Matrix(xform).without_translation());
gdouble const sw = hypot(ret[0], ret[1]);
box3d_exchange_coords(box);
}
-void
-box3d_add_to_selection(SPBox3D *box) {
- Persp3D *persp = box3d_get_perspective(box);
- g_return_if_fail(persp);
- persp3d_add_box_transform(persp, box);
-}
-
-void
-box3d_remove_from_selection(SPBox3D *box) {
- Persp3D *persp = box3d_get_perspective(box);
- if (!persp) {
- /* this can happen if a box is deleted through undo and the persp_ref is already detached;
- should we rebuild the boxes of each perspective in this case or is it safe to leave it alone? */
- return;
- }
- persp3d_remove_box_transform(persp, box);
-}
-
-void
-box3d_mark_transformed(SPBox3D *box) {
- Persp3D *persp = box3d_get_perspective(box);
- g_return_if_fail(persp);
- persp3d_set_box_transformed(persp, box, true);
-}
-
static void
box3d_extract_boxes_rec(SPObject *obj, std::list<SPBox3D *> &boxes) {
if (SP_IS_BOX3D(obj)) {
@@ -1388,9 +1328,6 @@ box3d_switch_perspectives(SPBox3D *box, Persp3D *old_persp, Persp3D *new_persp,
persp3d_remove_box (old_persp, box);
persp3d_add_box (new_persp, box);
- persp3d_remove_box_transform (old_persp, box);
- persp3d_add_box_transform (new_persp, box);
-
gchar *href = g_strdup_printf("#%s", SP_OBJECT_REPR(new_persp)->attribute("id"));
SP_OBJECT_REPR(box)->setAttribute("inkscape:perspectiveID", href);
g_free(href);
diff --git a/src/box3d.h b/src/box3d.h
index b6d962a3c924375ca6c6b3daa34df8c0e4dc53a7..9f2e1d78e8ac33210b80d30c5abaa56969600911 100644 (file)
--- a/src/box3d.h
+++ b/src/box3d.h
void box3d_relabel_corners(SPBox3D *box);
void box3d_check_for_swapped_coords(SPBox3D *box);
-void box3d_add_to_selection(SPBox3D *box);
-void box3d_remove_from_selection(SPBox3D *box);
-void box3d_mark_transformed(SPBox3D *box);
-
std::list<SPBox3D *> box3d_extract_boxes(SPObject *obj);
Persp3D *box3d_get_perspective(SPBox3D const *box);
diff --git a/src/persp3d.cpp b/src/persp3d.cpp
index 3f1e8851fe7075185e9f3b4e3a8c7781cb5ac8cf..6a697ec9b5e1d9893ed76b787144abc608c8bb50 100644 (file)
--- a/src/persp3d.cpp
+++ b/src/persp3d.cpp
static void persp3d_on_repr_attr_changed (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive, void * data);
+static void persp3d_update_with_point (Persp3DImpl *persp_impl, Proj::Axis const axis, Proj::Pt2 const &new_image);
+static gchar * persp3d_pt_to_str (Persp3DImpl *persp_impl, Proj::Axis const axis);
+
static SPObjectClass *persp3d_parent_class;
static int global_counter = 0;
Persp3DImpl::Persp3DImpl() {
tmat = Proj::TransfMat3x4 ();
-
- boxes_transformed = new std::map<SPBox3D *, bool>;
- boxes_transformed->clear();
document = NULL;
my_counter = global_counter++;
}
-Persp3DImpl::~Persp3DImpl() {
- delete boxes_transformed;
-}
-
/**
* Registers Persp3d class and returns its type.
*/
return false;
}
-void
-persp3d_add_box_transform (Persp3D *persp, SPBox3D *box) {
- Persp3DImpl *persp_impl = persp->perspective_impl;
-
- std::map<SPBox3D *, bool>::iterator i = persp_impl->boxes_transformed->find(box);
- if (i != persp_impl->boxes_transformed->end() && (*i).second == true) {
- g_print ("Warning! In %s (%d): trying to add transform status for box %d twice when it's already listed as true.\n", SP_OBJECT_REPR(persp_impl)->attribute("id"), persp_impl->my_counter, box->my_counter);
- return;
- }
-
- (*persp_impl->boxes_transformed)[box] = false;
-}
-
-void
-persp3d_remove_box_transform (Persp3D *persp, SPBox3D *box) {
- persp->perspective_impl->boxes_transformed->erase(box);
-}
-
-void
-persp3d_set_box_transformed (Persp3D *persp, SPBox3D *box, bool transformed) {
- Persp3DImpl *persp_impl = persp->perspective_impl;
-
- if (persp_impl->boxes_transformed->find(box) == persp_impl->boxes_transformed->end()) {
- g_print ("Warning! In %s (%d): trying to set transform status for box %d, but it is not listed in the perspective!! Aborting.\n",
- SP_OBJECT_REPR(persp)->attribute("id"), persp_impl->my_counter,
- box->my_counter);
- return;
- }
-
- (*persp_impl->boxes_transformed)[box] = transformed;
-}
-
-bool
-persp3d_was_transformed (Persp3D *persp) {
- Persp3DImpl *persp_impl = persp->perspective_impl;
-
- if (persp_impl->boxes_transformed->size() == 1) {
- /* either the transform has not been applied to the single box associated to this perspective yet
- or the transform was already reset; in both cases we need to return false because upcoming
- transforms need to be applied */
- (*persp_impl->boxes_transformed->begin()).second = false; // make sure the box is marked as untransformed (in case more boxes are added later)
- return false;
- }
-
- for (std::map<SPBox3D *, bool>::iterator i = persp_impl->boxes_transformed->begin();
- i != persp_impl->boxes_transformed->end(); ++i) {
- if ((*i).second == true) {
- // at least one of the boxes in the perspective has already been transformed;
- return true;
- }
- }
- return false; // all boxes in the perspective are still untransformed; a pending transformation should be applied
-}
-
-bool
-persp3d_all_transformed(Persp3D *persp) {
- Persp3DImpl *persp_impl = persp->perspective_impl;
-
- for (std::map<SPBox3D *, bool>::iterator i = persp_impl->boxes_transformed->begin();
- i != persp_impl->boxes_transformed->end(); ++i) {
- if ((*i).second == false) {
- return false;
- }
- }
- return true;
-}
-
-void
-persp3d_unset_transforms(Persp3D *persp) {
- Persp3DImpl *persp_impl = persp->perspective_impl;
-
- for (std::map<SPBox3D *, bool>::iterator i = persp_impl->boxes_transformed->begin();
- i != persp_impl->boxes_transformed->end(); ++i) {
- (*i).second = false;
- }
-}
-
void
persp3d_update_box_displays (Persp3D *persp) {
Persp3DImpl *persp_impl = persp->perspective_impl;
/* checks whether all boxes linked to this perspective are currently selected */
bool
-persp3d_has_all_boxes_in_selection (Persp3D *persp) {
+persp3d_has_all_boxes_in_selection (Persp3D *persp, Inkscape::Selection *selection) {
Persp3DImpl *persp_impl = persp->perspective_impl;
- std::list<SPBox3D *> selboxes = sp_desktop_selection(inkscape_active_desktop())->box3DList();
+ std::list<SPBox3D *> selboxes = selection->box3DList();
for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) {
if (std::find(selboxes.begin(), selboxes.end(), *i) == selboxes.end()) {
return true;
}
-/**
- * For each perspective having a box in \a selection, determine all its unselected boxes.
- */
-// TODO: Check where we can use pass-by-reference (or so) instead of recreating all the lists afresh.
-std::map<Persp3D *, std::list<SPBox3D *> >
-persp3d_unselected_boxes(Inkscape::Selection *selection) {
- std::list<Persp3D *> plist = selection->perspList();
- std::map<Persp3D *, std::list<SPBox3D *> > punsel;
-
- std::list<Persp3D *>::iterator i;
- std::vector<SPBox3D *>::iterator j;
- // for all perspectives in the list ...
- for (i = plist.begin(); i != plist.end(); ++i) {
- Persp3D *persp = *i;
- Persp3DImpl *persp_impl = persp->perspective_impl;
- // ... and each box associated to it ...
- for (j = persp_impl->boxes.begin(); j != persp_impl->boxes.end(); ++j) {
- SPBox3D *box = *j;
- // ... check whether it is unselected, and if so add it to the list
- if (persp_impl->boxes_transformed->find(box) == persp_impl->boxes_transformed->end()) {
- punsel[persp].push_back(box);
- }
- }
- }
- return punsel;
-}
-
-/**
- * Split all perspectives with a box in \a selection by moving their unselected boxes to newly
- * created perspectives.
- */
-void
-persp3d_split_perspectives_according_to_selection(Inkscape::Selection *selection) {
- std::map<Persp3D *, std::list<SPBox3D *> > punsel = persp3d_unselected_boxes(selection);
-
- std::map<Persp3D *, std::list<SPBox3D *> >::iterator i;
- std::list<SPBox3D *>::iterator j;
- // for all perspectives in the list ...
- for (i = punsel.begin(); i != punsel.end(); ++i) {
- Persp3D *persp = (*i).first;
- // ... if the perspective has unselected boxes ...
- if (!(*i).second.empty()) {
- // create a new perspective and move these boxes over
- SPDocument *document = SP_OBJECT_DOCUMENT(persp);
- Persp3D * new_persp = persp3d_create_xml_element (document, persp->perspective_impl);
- for (j = (*i).second.begin(); j != (*i).second.end(); ++j) {
- SPBox3D *box = *j;
- box3d_switch_perspectives(box, persp, new_persp);
- }
- }
- }
-}
-
/* some debugging stuff follows */
void
Persp3D *persp = SP_PERSP3D(*j);
Persp3DImpl *persp_impl = persp->perspective_impl;
g_print (" %s (%d): ", SP_OBJECT_REPR(persp)->attribute("id"), persp->perspective_impl->my_counter);
- for (std::map<SPBox3D *, bool>::iterator i = persp_impl->boxes_transformed->begin();
- i != persp_impl->boxes_transformed->end(); ++i) {
- g_print ("<%d,%d> ", (*i).first->my_counter, (*i).second);
+ for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin();
+ i != persp_impl->boxes.end(); ++i) {
+ g_print ("%d ", (*i)->my_counter);
}
g_print ("\n");
}
diff --git a/src/persp3d.h b/src/persp3d.h
index 31a6212c7a9a9b2e5bb4805992a464408dc3e580..62cc586ef15496c3fff523fc707e16e77ecedae8 100644 (file)
--- a/src/persp3d.h
+++ b/src/persp3d.h
class Persp3DImpl {
public:
Persp3DImpl();
- ~Persp3DImpl();
//private:
Proj::TransfMat3x4 tmat;
// Also write the list of boxes into the xml repr and vice versa link boxes to their persp3d?
std::vector<SPBox3D *> boxes;
- std::map<SPBox3D *, bool>* boxes_transformed; // TODO: eventually we should merge this with 'boxes'
- SPDocument *document; // should this rather be the SPDesktop?
+ SPDocument *document;
// for debugging only
int my_counter;
void persp3d_remove_box (Persp3D *persp, SPBox3D *box);
bool persp3d_has_box (Persp3D *persp, SPBox3D *box);
-void persp3d_add_box_transform (Persp3D *persp, SPBox3D *box);
-void persp3d_remove_box_transform (Persp3D *persp, SPBox3D *box);
-void persp3d_set_box_transformed (Persp3D *persp, SPBox3D *box, bool transformed = true);
-bool persp3d_was_transformed (Persp3D *persp);
-bool persp3d_all_transformed(Persp3D *persp);
-void persp3d_unset_transforms(Persp3D *persp);
-
void persp3d_update_box_displays (Persp3D *persp);
void persp3d_update_box_reprs (Persp3D *persp);
void persp3d_update_z_orders (Persp3D *persp);
Persp3D * persp3d_create_xml_element (SPDocument *document, Persp3DImpl *dup = NULL);
Persp3D * persp3d_document_first_persp (SPDocument *document);
-bool persp3d_has_all_boxes_in_selection (Persp3D *persp);
-std::map<Persp3D *, std::list<SPBox3D *> > persp3d_unselected_boxes(Inkscape::Selection *selection);
-void persp3d_split_perspectives_according_to_selection(Inkscape::Selection *selection);
+bool persp3d_has_all_boxes_in_selection (Persp3D *persp, Inkscape::Selection *selection);
void persp3d_print_debugging_info (Persp3D *persp);
void persp3d_print_debugging_info_all(SPDocument *doc);
void persp3d_print_all_selected();
-/* Internally used functions; maybe these should be made more private? */
-void persp3d_update_with_point (Persp3DImpl *persp_impl, Proj::Axis const axis, Proj::Pt2 const &new_image);
-gchar * persp3d_pt_to_str (Persp3DImpl *persp_impl, Proj::Axis const axis);
-
void print_current_persp3d(gchar *func_name, Persp3D *persp);
#endif /* __PERSP3D_H__ */
index e55bba2a5926079ef2e3a2fd99f300d7b8e791c2..31e899d8a34c703866ae9dbc40c6b51244fdb8dc 100644 (file)
#include "helper/units.h"
#include "sp-item.h"
#include "box3d.h"
+#include "persp3d.h"
#include "unit-constants.h"
#include "xml/simple-document.h"
#include "sp-filter-reference.h"
return clone_with_original;
}
-
/** Apply matrix to the selection. \a set_i2d is normally true, which means objects are in the
original transform, synced with their reprs, and need to jump to the new transform in one go. A
value of set_i2d==false is only used by seltrans when it's dragging objects live (not outlines); in
@@ -1183,6 +1183,29 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Matrix cons
if (selection->isEmpty())
return;
+ // For each perspective with a box in selection, check whether all boxes are selected and
+ // unlink all non-selected boxes.
+ Persp3D *persp;
+ Persp3D *transf_persp;
+ std::list<Persp3D *> plist = selection->perspList();
+ for (std::list<Persp3D *>::iterator i = plist.begin(); i != plist.end(); ++i) {
+ persp = (Persp3D *) (*i);
+
+ if (!persp3d_has_all_boxes_in_selection (persp, selection)) {
+ std::list<SPBox3D *> selboxes = selection->box3DList(persp);
+
+ // create a new perspective as a copy of the current one and link the selected boxes to it
+ transf_persp = persp3d_create_xml_element (SP_OBJECT_DOCUMENT(persp), persp->perspective_impl);
+
+ for (std::list<SPBox3D *>::iterator b = selboxes.begin(); b != selboxes.end(); ++b)
+ box3d_switch_perspectives(*b, persp, transf_persp);
+ } else {
+ transf_persp = persp;
+ }
+
+ persp3d_apply_affine_transformation(transf_persp, affine);
+ }
+
for (GSList const *l = selection->itemList(); l != NULL; l = l->next) {
SPItem *item = SP_ITEM(l->data);
diff --git a/src/selection.cpp b/src/selection.cpp
index ed8a9d57b86034dfcaf4c36915bace17a5ff3671..828a96968f6e1217f09335e96cfbe36894f5a829 100644 (file)
--- a/src/selection.cpp
+++ b/src/selection.cpp
@@ -162,24 +162,12 @@ void Selection::add(SPObject *obj, bool persist_selection_context/* = false */)
_emitChanged(persist_selection_context);
}
-void Selection::add_box_perspective(SPBox3D *box) {
- Persp3D *persp = box3d_get_perspective(box);
- std::map<Persp3D *, unsigned int>::iterator p = _persps.find(persp);
- if (p != _persps.end()) {
- (*p).second++;
- } else {
- _persps[persp] = 1;
- }
-}
-
void Selection::add_3D_boxes_recursively(SPObject *obj) {
std::list<SPBox3D *> boxes = box3d_extract_boxes(obj);
for (std::list<SPBox3D *>::iterator i = boxes.begin(); i != boxes.end(); ++i) {
SPBox3D *box = *i;
- box3d_add_to_selection(box);
_3dboxes.push_back(box);
- add_box_perspective(box);
}
}
_emitChanged();
}
-void Selection::remove_box_perspective(SPBox3D *box) {
- Persp3D *persp = box3d_get_perspective(box);
- std::map<Persp3D *, unsigned int>::iterator p = _persps.find(persp);
- if (p == _persps.end()) {
- //g_print ("Warning! Trying to remove unselected perspective from selection!\n");
- return;
- }
- if ((*p).second > 1) {
- _persps[persp]--;
- } else {
- _persps.erase(p);
- }
-}
-
void Selection::remove_3D_boxes_recursively(SPObject *obj) {
std::list<SPBox3D *> boxes = box3d_extract_boxes(obj);
for (std::list<SPBox3D *>::iterator i = boxes.begin(); i != boxes.end(); ++i) {
SPBox3D *box = *i;
- box3d_remove_from_selection(box);
std::list<SPBox3D *>::iterator b = std::find(_3dboxes.begin(), _3dboxes.end(), box);
if (b == _3dboxes.end()) {
g_print ("Warning! Trying to remove unselected box from selection.\n");
return;
}
_3dboxes.erase(b);
- remove_box_perspective(box);
}
}
std::list<Persp3D *> const Selection::perspList() {
std::list<Persp3D *> pl;
- for (std::map<Persp3D *, unsigned int>::iterator p = _persps.begin(); p != _persps.end(); ++p) {
- pl.push_back((*p).first);
+ for (std::list<SPBox3D *>::iterator i = _3dboxes.begin(); i != _3dboxes.end(); ++i) {
+ Persp3D *persp = box3d_get_perspective(*i);
+ if (std::find(pl.begin(), pl.end(), persp) == pl.end())
+ pl.push_back(persp);
}
return pl;
}
-std::list<SPBox3D *> const Selection::box3DList() {
- return _3dboxes;
+std::list<SPBox3D *> const Selection::box3DList(Persp3D *persp) {
+ std::list<SPBox3D *> boxes;
+ if (persp) {
+ SPBox3D *box;
+ for (std::list<SPBox3D *>::iterator i = _3dboxes.begin(); i != _3dboxes.end(); ++i) {
+ box = *i;
+ if (persp == box3d_get_perspective(box))
+ boxes.push_back(box);
+ }
+ } else {
+ boxes = _3dboxes;
+ }
+ return boxes;
}
SPObject *Selection::single() {
diff --git a/src/selection.h b/src/selection.h
index ecb1ef45e5399780cbe4812bf52a1bb18b6517ce..5e035fb60e3dde7cdc3c23cff953b9b549693b39 100644 (file)
--- a/src/selection.h
+++ b/src/selection.h
/// method for that
GSList const *reprList();
- /* list of all perspectives which have a 3D box in the current selection
+ /** @brief Returns a list of all perspectives which have a 3D box in the current selection
(these may also be nested in groups) */
std::list<Persp3D *> const perspList();
- std::list<SPBox3D *> const box3DList();
+ /** @brief Returns a list of all 3D boxes in the current selection which are associated to @c
+ persp. If @c pers is @c NULL, return all selected boxes.
+ */
+ std::list<SPBox3D *> const box3DList(Persp3D *persp = NULL);
/** @brief Returns the number of layers in which there are selected objects */
guint numberOfLayers();
void remove_box_perspective(SPBox3D *box);
void remove_3D_boxes_recursively(SPObject *obj);
- std::map<Persp3D *, unsigned int> _persps;
std::list<SPBox3D *> _3dboxes;
GC::soft_ptr<SPDesktop> _desktop;
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index 7ac7880a79d0e17a9653a6212d09aba2e84fa479..3845be23219b8ceb8e51a69cafa1f403e42dd6ff 100644 (file)
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
static void sp_group_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
static void sp_group_print (SPItem * item, SPPrintContext *ctx);
static gchar * sp_group_description (SPItem * item);
-static Geom::Matrix sp_group_set_transform(SPItem *item, Geom::Matrix const &xform);
static NRArenaItem *sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
static void sp_group_hide (SPItem * item, unsigned int key);
static void sp_group_snappoints (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
item_class->bbox = sp_group_bbox;
item_class->print = sp_group_print;
item_class->description = sp_group_description;
- item_class->set_transform = sp_group_set_transform;
item_class->show = sp_group_show;
item_class->hide = sp_group_hide;
item_class->snappoints = sp_group_snappoints;
return SP_GROUP(item)->group->getDescription();
}
-static Geom::Matrix
-sp_group_set_transform(SPItem *item, Geom::Matrix const &xform)
-{
- Inkscape::Selection *selection = sp_desktop_selection(inkscape_active_desktop());
- persp3d_split_perspectives_according_to_selection(selection);
-
- Geom::Matrix last_trans;
- sp_svg_transform_read(SP_OBJECT_REPR(item)->attribute("transform"), &last_trans);
- Geom::Matrix inc_trans = last_trans.inverse()*xform;
-
- std::list<Persp3D *> plist = selection->perspList();
- for (std::list<Persp3D *>::iterator i = plist.begin(); i != plist.end(); ++i) {
- persp3d_apply_affine_transformation(*i, inc_trans);
- }
-
- return xform;
-}
-
static void sp_group_set(SPObject *object, unsigned key, char const *value) {
SPGroup *group = SP_GROUP(object);
diff --git a/src/transf_mat_3x4.cpp b/src/transf_mat_3x4.cpp
index b7cd278d4febfdf28b665b89629655843bcdb180..6b49dc44aa70a8f6cdaf41a0156202721ae833bc 100644 (file)
--- a/src/transf_mat_3x4.cpp
+++ b/src/transf_mat_3x4.cpp
return g_strdup(os.str().c_str());
}
+/* Check for equality (with a small tolerance epsilon) */
bool
TransfMat3x4::operator==(const TransfMat3x4 &rhs) const
{
return true;
}
-/* multiply a projective matrix by an affine matrix */
+/* Multiply a projective matrix by an affine matrix (by only multiplying the 'affine part' of the
+ * projective matrix) */
TransfMat3x4
TransfMat3x4::operator*(Geom::Matrix const &A) const {
TransfMat3x4 ret;
- // Is it safe to always use the currently active document?
- double h = sp_document_height(inkscape_active_document());
-
- /*
- * Note: The strange multiplication involving the document height is due to the buggy
- * intertwining of SVG and document coordinates. Essentially, what we do is first
- * convert from "real-world" to SVG coordinates, then apply the transformation A
- * (by multiplying with the Geom::Matrix) and then convert back from SVG to real-world
- * coordinates. Maybe there is even a more Inkscape-ish way to achieve this?
- * Once Inkscape has gotton rid of the two different coordiate systems, we can change
- * this function to an ordinary matrix multiplication.
- */
for (int j = 0; j < 4; ++j) {
- ret.tmat[0][j] = A[0]*tmat[0][j] + A[2]*(h*tmat[2][j] - tmat[1][j]) + A[4]*tmat[2][j];
- ret.tmat[1][j] = A[1]*tmat[0][j] + A[3]*(h*tmat[2][j] - tmat[1][j]) + A[5]*tmat[2][j];
+ ret.tmat[0][j] = A[0]*tmat[0][j] + A[2]*tmat[1][j] + A[4]*tmat[2][j];
+ ret.tmat[1][j] = A[1]*tmat[0][j] + A[3]*tmat[1][j] + A[5]*tmat[2][j];
ret.tmat[2][j] = tmat[2][j];
-
- ret.tmat[1][j] = h*ret.tmat[2][j] - ret.tmat[1][j]; // switch back from SVG to desktop coordinates
}
return ret;