summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorsu_v <suv-sf@users.sourceforge.net>2015-11-15 08:31:53 +0000
committer~suv <suv-sf@users.sourceforge.net>2015-11-15 08:31:53 +0000
commitac8b388ada4e781b29570276ed9f95fd6f4dafff (patch)
tree268308a8a304debb7cf2f84e1255d5633dee5eef /src/ui
parentExtensions. Fix view center for Render extensions applied in transformed laye... (diff)
parentTranslations. Italian translation update. (diff)
downloadinkscape-ac8b388ada4e781b29570276ed9f95fd6f4dafff.tar.gz
inkscape-ac8b388ada4e781b29570276ed9f95fd6f4dafff.zip
merge from trunk (r14473)
(bzr r14425.1.3)
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/clipboard.cpp10
-rw-r--r--src/ui/dialog/clonetiler.cpp32
-rw-r--r--src/ui/dialog/clonetiler.h4
-rw-r--r--src/ui/dialog/export.cpp6
-rw-r--r--src/ui/dialog/filter-effects-dialog.cpp6
-rw-r--r--src/ui/dialog/find.cpp16
-rw-r--r--src/ui/dialog/font-substitution.cpp2
-rw-r--r--src/ui/dialog/glyphs.cpp4
-rw-r--r--src/ui/dialog/grid-arrange-tab.cpp6
-rw-r--r--src/ui/dialog/icon-preview.cpp2
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp4
-rw-r--r--src/ui/dialog/objects.cpp12
-rw-r--r--src/ui/dialog/pixelartdialog.cpp2
-rw-r--r--src/ui/dialog/polar-arrange-tab.cpp4
-rw-r--r--src/ui/dialog/tags.cpp4
-rw-r--r--src/ui/dialog/text-edit.cpp20
-rw-r--r--src/ui/dialog/transformation.cpp8
-rw-r--r--src/ui/tools/connector-tool.cpp2
-rw-r--r--src/ui/tools/eraser-tool.cpp8
-rw-r--r--src/ui/tools/gradient-tool.cpp4
-rw-r--r--src/ui/tools/lpe-tool.cpp2
-rw-r--r--src/ui/tools/measure-tool.cpp1444
-rw-r--r--src/ui/tools/measure-tool.h68
-rw-r--r--src/ui/tools/spray-tool.cpp759
-rw-r--r--src/ui/tools/spray-tool.h29
-rw-r--r--src/ui/tools/tweak-tool.cpp2
-rw-r--r--src/ui/widget/font-variants.cpp70
27 files changed, 1922 insertions, 608 deletions
diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp
index 0792fb9c5..354fa45dc 100644
--- a/src/ui/clipboard.cpp
+++ b/src/ui/clipboard.cpp
@@ -525,7 +525,7 @@ bool ClipboardManagerImpl::pasteSize(SPDesktop *desktop, bool separately, bool a
// resize each object in the selection
if (separately) {
std::vector<SPItem*> itemlist=selection->itemList();
- for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){
SPItem *item = *i;
if (item) {
Geom::OptRect obj_size = item->desktopVisualBounds();
@@ -581,7 +581,7 @@ bool ClipboardManagerImpl::pastePathEffect(SPDesktop *desktop)
// make sure all selected items are converted to paths first (i.e. rectangles)
sp_selected_to_lpeitems(desktop);
std::vector<SPItem*> itemlist=selection->itemList();
- for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){
SPItem *item = *i;
_applyPathEffect(item, effectstack);
}
@@ -665,7 +665,7 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection)
// copy the defs used by all items
std::vector<SPItem*> itemlist=selection->itemList();
cloned_elements.clear();
- for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){
SPItem *item = *i;
if (item) {
_copyUsedDefs(item);
@@ -676,7 +676,7 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection)
// copy the representation of the items
std::vector<SPObject*> sorted_items;
- for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++)
+ for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i)
sorted_items.push_back(*i);
sort(sorted_items.begin(),sorted_items.end(),sp_object_compare_position_bool);
@@ -692,7 +692,7 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection)
sorted_items.insert(sorted_items.end(),cloned_elements.begin(),cloned_elements.end());
- for(std::vector<SPObject*>::const_iterator i=sorted_items.begin();i!=sorted_items.end();i++){
+ for(std::vector<SPObject*>::const_iterator i=sorted_items.begin();i!=sorted_items.end();++i){
SPItem *item = dynamic_cast<SPItem*>(*i);
if (item) {
Inkscape::XML::Node *obj = item->getRepr();
diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp
index da1c6d9fb..fbd050f8e 100644
--- a/src/ui/dialog/clonetiler.cpp
+++ b/src/ui/dialog/clonetiler.cpp
@@ -85,7 +85,7 @@ CloneTiler::CloneTiler () :
{
Gtk::Box *contents = _getContents();
contents->set_spacing(0);
-
+
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -101,7 +101,7 @@ CloneTiler::CloneTiler () :
contents->pack_start (*Gtk::manage(Glib::wrap(mainbox)), true, true, 0);
- GtkWidget *nb = gtk_notebook_new ();
+ nb = gtk_notebook_new ();
gtk_box_pack_start (GTK_BOX (mainbox), nb, FALSE, FALSE, 0);
@@ -662,7 +662,7 @@ CloneTiler::CloneTiler () :
gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0);
guint32 rgba = 0x000000ff | sp_svg_read_color (prefs->getString(prefs_path + "initial_color").data(), 0x000000ff);
- color_picker = new Inkscape::UI::Widget::ColorPicker (*new Glib::ustring(_("Initial color of tiled clones")), *new Glib::ustring(_("Initial color for clones (works only if the original has unset fill or stroke)")), rgba, false);
+ color_picker = new Inkscape::UI::Widget::ColorPicker (*new Glib::ustring(_("Initial color of tiled clones")), *new Glib::ustring(_("Initial color for clones (works only if the original has unset fill or stroke or on spray tool in copy mode)")), rgba, false);
color_changed_connection = color_picker->connectChanged (sigc::ptr_fun(on_picker_color_changed));
gtk_box_pack_start (GTK_BOX (hb), reinterpret_cast<GtkWidget*>(color_picker->gobj()), FALSE, FALSE, 0);
@@ -776,8 +776,6 @@ CloneTiler::CloneTiler () :
// Trace
{
GtkWidget *vb = clonetiler_new_tab (nb, _("_Trace"));
-
-
{
#if GTK_CHECK_VERSION(3,0,0)
GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, VB_MARGIN);
@@ -787,11 +785,11 @@ CloneTiler::CloneTiler () :
#endif
gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0);
- GtkWidget *b = gtk_check_button_new_with_label (_("Trace the drawing under the tiles"));
+ b = gtk_check_button_new_with_label (_("Trace the drawing under the clones/sprayed items"));
g_object_set_data (G_OBJECT(b), "uncheckable", GINT_TO_POINTER(TRUE));
bool old = prefs->getBool(prefs_path + "dotrace");
gtk_toggle_button_set_active ((GtkToggleButton *) b, old);
- gtk_widget_set_tooltip_text (b, _("For each clone, pick a value from the drawing in that clone's location and apply it to the clone"));
+ gtk_widget_set_tooltip_text (b, _("For each clone/sprayed item, pick a value from the drawing in its location and apply it"));
gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0);
g_signal_connect(G_OBJECT(b), "toggled",
@@ -1001,6 +999,18 @@ CloneTiler::CloneTiler () :
}
}
+ {
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, VB_MARGIN);
+ gtk_box_set_homogeneous(GTK_BOX(hb), FALSE);
+#else
+ GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN);
+#endif
+ gtk_box_pack_start (GTK_BOX (mainbox), hb, FALSE, FALSE, 0);
+ GtkWidget *l = gtk_label_new(_(""));
+ gtk_label_set_markup (GTK_LABEL(l), _("Apply to tiled clones:"));
+ gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0);
+ }
// Rows/columns, width/height
{
#if GTK_CHECK_VERSION(3,0,0)
@@ -1289,7 +1299,6 @@ CloneTiler::CloneTiler () :
}
gtk_widget_show_all (mainbox);
-
}
show_all();
@@ -3005,6 +3014,13 @@ void CloneTiler::clonetiler_do_pick_toggled(GtkToggleButton *tb, GtkWidget *dlg)
}
}
+void CloneTiler::show_page_trace()
+{
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(nb),6);
+ gtk_toggle_button_set_active ((GtkToggleButton *) b, false);
+}
+
+
}
}
}
diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h
index e5f5638b2..a8f1df0a0 100644
--- a/src/ui/dialog/clonetiler.h
+++ b/src/ui/dialog/clonetiler.h
@@ -31,7 +31,7 @@ public:
virtual ~CloneTiler();
static CloneTiler &getInstance() { return *new CloneTiler(); }
-
+ void show_page_trace();
protected:
GtkWidget * clonetiler_new_tab(GtkWidget *nb, const gchar *label);
@@ -113,6 +113,8 @@ private:
CloneTiler& operator=(CloneTiler const &d);
GtkWidget *dlg;
+ GtkWidget *nb;
+ GtkWidget *b;
SPDesktop *desktop;
DesktopTracker deskTrack;
Inkscape::UI::Widget::ColorPicker *color_picker;
diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp
index 59fab7771..2fb5f9e3b 100644
--- a/src/ui/dialog/export.cpp
+++ b/src/ui/dialog/export.cpp
@@ -821,7 +821,7 @@ void Export::onAreaToggled ()
if (filename.empty()) {
const gchar * id = "object";
const std::vector<XML::Node*> reprlst = SP_ACTIVE_DESKTOP->getSelection()->reprList();
- for(std::vector<XML::Node*>::const_iterator i=reprlst.begin(); reprlst.end() != i; i++) {
+ for(std::vector<XML::Node*>::const_iterator i=reprlst.begin(); reprlst.end() != i; ++i) {
Inkscape::XML::Node * repr = *i;
if (repr->attribute("id")) {
id = repr->attribute("id");
@@ -1030,7 +1030,7 @@ void Export::onExport ()
gint export_count = 0;
std::vector<SPItem*> itemlist=desktop->getSelection()->itemList();
- for(std::vector<SPItem*>::const_iterator i = itemlist.begin();i!=itemlist.end() && !interrupted ;i++){
+ for(std::vector<SPItem*>::const_iterator i = itemlist.begin();i!=itemlist.end() && !interrupted ;++i){
SPItem *item = *i;
prog_dlg->set_data("current", GINT_TO_POINTER(n));
@@ -1239,7 +1239,7 @@ void Export::onExport ()
DocumentUndo::setUndoSensitive(doc, false);
reprlst = desktop->getSelection()->reprList();
- for(std::vector<Inkscape::XML::Node*>::const_iterator i=reprlst.begin(); reprlst.end() != i; i++) {
+ for(std::vector<Inkscape::XML::Node*>::const_iterator i=reprlst.begin(); reprlst.end() != i; ++i) {
Inkscape::XML::Node * repr = *i;
const gchar * temp_string;
Glib::ustring dir = Glib::path_get_dirname(filename.c_str());
diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp
index 22c8c76f2..08a58291d 100644
--- a/src/ui/dialog/filter-effects-dialog.cpp
+++ b/src/ui/dialog/filter-effects-dialog.cpp
@@ -1474,7 +1474,7 @@ void FilterEffectsDialog::FilterModifier::update_selection(Selection *sel)
std::set<SPObject*> used;
std::vector<SPItem*> itemlist=sel->itemList();
- for(std::vector<SPItem*>::const_iterator i=itemlist.begin(); itemlist.end() != i; i++) {
+ for(std::vector<SPItem*>::const_iterator i=itemlist.begin(); itemlist.end() != i; ++i) {
SPObject *obj = *i;
SPStyle *style = obj->style;
if (!style || !SP_IS_ITEM(obj)) {
@@ -1555,7 +1555,7 @@ void FilterEffectsDialog::FilterModifier::on_selection_toggled(const Glib::ustri
filter = 0;
std::vector<SPItem*> itemlist=sel->itemList();
- for(std::vector<SPItem*>::const_iterator i=itemlist.begin(); itemlist.end() != i; i++) {
+ for(std::vector<SPItem*>::const_iterator i=itemlist.begin(); itemlist.end() != i; ++i) {
SPItem * item = *i;
SPStyle *style = item->style;
g_assert(style != NULL);
@@ -1669,7 +1669,7 @@ void FilterEffectsDialog::FilterModifier::remove_filter()
// Delete all references to this filter
std::vector<SPItem*> x,y;
std::vector<SPItem*> all = get_all_items(x, _desktop->currentRoot(), _desktop, false, false, true, y);
- for(std::vector<SPItem*>::const_iterator i=all.begin(); all.end() != i; i++) {
+ for(std::vector<SPItem*>::const_iterator i=all.begin(); all.end() != i; ++i) {
if (!SP_IS_ITEM(*i)) {
continue;
}
diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp
index a8ac42a1b..0f368c5ac 100644
--- a/src/ui/dialog/find.cpp
+++ b/src/ui/dialog/find.cpp
@@ -561,7 +561,7 @@ std::vector<SPItem*> Find::filter_fields (std::vector<SPItem*> &l, bool exact, b
std::vector<SPItem*> out;
if (check_searchin_text.get_active()) {
- for(std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; i++) {
+ for(std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
SPObject *obj = *i;
SPItem *item = dynamic_cast<SPItem *>(obj);
g_assert(item != NULL);
@@ -584,7 +584,7 @@ std::vector<SPItem*> Find::filter_fields (std::vector<SPItem*> &l, bool exact, b
bool attrvalue = check_attributevalue.get_active();
if (ids) {
- for(std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; i++) {
+ for(std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
SPObject *obj = *i;
SPItem *item = dynamic_cast<SPItem *>(obj);
if (item_id_match(item, text, exact, casematch)) {
@@ -600,7 +600,7 @@ std::vector<SPItem*> Find::filter_fields (std::vector<SPItem*> &l, bool exact, b
if (style) {
- for(std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; i++) {
+ for(std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
SPObject *obj = *i;
SPItem *item = dynamic_cast<SPItem *>(obj);
g_assert(item != NULL);
@@ -617,7 +617,7 @@ std::vector<SPItem*> Find::filter_fields (std::vector<SPItem*> &l, bool exact, b
if (attrname) {
- for(std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; i++) {
+ for(std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
SPObject *obj = *i;
SPItem *item = dynamic_cast<SPItem *>(obj);
g_assert(item != NULL);
@@ -634,7 +634,7 @@ std::vector<SPItem*> Find::filter_fields (std::vector<SPItem*> &l, bool exact, b
if (attrvalue) {
- for(std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; i++) {
+ for(std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
SPObject *obj = *i;
SPItem *item = dynamic_cast<SPItem *>(obj);
g_assert(item != NULL);
@@ -651,7 +651,7 @@ std::vector<SPItem*> Find::filter_fields (std::vector<SPItem*> &l, bool exact, b
if (font) {
- for(std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; i++) {
+ for(std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
SPObject *obj = *i;
SPItem *item = dynamic_cast<SPItem *>(obj);
g_assert(item != NULL);
@@ -718,7 +718,7 @@ bool Find::item_type_match (SPItem *item)
std::vector<SPItem*> Find::filter_types (std::vector<SPItem*> &l)
{
std::vector<SPItem*> n;
- for(std::vector<SPItem*>::const_reverse_iterator i=l.rbegin(); l.rend() != i; i++) {
+ for(std::vector<SPItem*>::const_reverse_iterator i=l.rbegin(); l.rend() != i; ++i) {
SPObject *obj = *i;
SPItem *item = dynamic_cast<SPItem *>(obj);
g_assert(item != NULL);
@@ -762,7 +762,7 @@ std::vector<SPItem*> &Find::all_items (SPObject *r, std::vector<SPItem*> &l, boo
std::vector<SPItem*> &Find::all_selection_items (Inkscape::Selection *s, std::vector<SPItem*> &l, SPObject *ancestor, bool hidden, bool locked)
{
std::vector<SPItem*> itemlist=s->itemList();
- for(std::vector<SPItem*>::const_reverse_iterator i=itemlist.rbegin(); itemlist.rend() != i; i++) {
+ for(std::vector<SPItem*>::const_reverse_iterator i=itemlist.rbegin(); itemlist.rend() != i; ++i) {
SPObject *obj = *i;
SPItem *item = dynamic_cast<SPItem *>(obj);
g_assert(item != NULL);
diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp
index 19506c6a3..f219f3db6 100644
--- a/src/ui/dialog/font-substitution.cpp
+++ b/src/ui/dialog/font-substitution.cpp
@@ -154,7 +154,7 @@ std::vector<SPItem*> FontSubstitution::getFontReplacedItems(SPDocument* doc, Gli
std::map<SPItem *, Glib::ustring> mapFontStyles;
allList = get_all_items(x, doc->getRoot(), desktop, false, false, true, y);
- for(std::vector<SPItem*>::const_iterator i = allList.begin();i!=allList.end();i++){
+ for(std::vector<SPItem*>::const_iterator i = allList.begin();i!=allList.end();++i){
SPItem *item = *i;
SPStyle *style = item->style;
Glib::ustring family = "";
diff --git a/src/ui/dialog/glyphs.cpp b/src/ui/dialog/glyphs.cpp
index 7ca277ea2..56b001291 100644
--- a/src/ui/dialog/glyphs.cpp
+++ b/src/ui/dialog/glyphs.cpp
@@ -579,7 +579,7 @@ void GlyphsPanel::insertText()
{
SPItem *textItem = 0;
std::vector<SPItem*> itemlist=targetDesktop->selection->itemList();
- for(std::vector<SPItem*>::const_iterator i=itemlist.begin(); itemlist.end() != i; i++) {
+ for(std::vector<SPItem*>::const_iterator i=itemlist.begin(); itemlist.end() != i; ++i) {
if (SP_IS_TEXT(*i) || SP_IS_FLOWTEXT(*i)) {
textItem = *i;
break;
@@ -689,7 +689,7 @@ void GlyphsPanel::calcCanInsert()
{
int items = 0;
std::vector<SPItem*> itemlist=targetDesktop->selection->itemList();
- for(std::vector<SPItem*>::const_iterator i=itemlist.begin(); itemlist.end() != i; i++) {
+ for(std::vector<SPItem*>::const_iterator i=itemlist.begin(); itemlist.end() != i; ++i) {
if (SP_IS_TEXT(*i) || SP_IS_FLOWTEXT(*i)) {
++items;
}
diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp
index 086cbe45f..53c25c3d5 100644
--- a/src/ui/dialog/grid-arrange-tab.cpp
+++ b/src/ui/dialog/grid-arrange-tab.cpp
@@ -164,7 +164,7 @@ void GridArrangeTab::arrange()
Inkscape::Selection *selection = desktop->getSelection();
const std::vector<SPItem*> items = selection ? selection->itemList() : std::vector<SPItem*>();
- for(std::vector<SPItem*>::const_iterator i = items.begin();i!=items.end();i++){
+ for(std::vector<SPItem*>::const_iterator i = items.begin();i!=items.end(); ++i){
SPItem *item = *i;
Geom::OptRect b = item->documentVisualBounds();
if (!b) {
@@ -202,7 +202,7 @@ void GridArrangeTab::arrange()
cnt=0;
const std::vector<SPItem*> sizes(sorted);
- for (std::vector<SPItem*>::const_iterator i = sizes.begin();i!=sizes.end();i++) {
+ for (std::vector<SPItem*>::const_iterator i = sizes.begin();i!=sizes.end(); ++i) {
SPItem *item = *i;
Geom::OptRect b = item->documentVisualBounds();
if (b) {
@@ -301,7 +301,7 @@ g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_h
cnt=0;
std::vector<SPItem*>::iterator it = sorted.begin();
- for (row_cnt=0; ((it != sorted.end()) && (row_cnt<NoOfRows)); row_cnt++) {
+ for (row_cnt=0; ((it != sorted.end()) && (row_cnt<NoOfRows)); ++row_cnt) {
GSList *current_row = NULL;
col_cnt = 0;
diff --git a/src/ui/dialog/icon-preview.cpp b/src/ui/dialog/icon-preview.cpp
index 77f120e1a..83656a1f2 100644
--- a/src/ui/dialog/icon-preview.cpp
+++ b/src/ui/dialog/icon-preview.cpp
@@ -363,7 +363,7 @@ void IconPreviewPanel::refreshPreview()
//g_message("found a selection to play with");
std::vector<SPItem*> const items = sel->itemList();
- for(std::vector<SPItem*>::const_iterator i=items.begin();!target && i!=items.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=items.begin();!target && i!=items.end();++i){
SPItem* item = *i;
gchar const *id = item->getId();
if ( id ) {
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index 14eaa65aa..fec49d484 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -601,7 +601,7 @@ void InkscapePreferences::initPageUI()
_("Set the language for menus and number formats"), false);
{
- Glib::ustring sizeLabels[] = {_("Large"), _("Small"), _("Smaller")};
+ Glib::ustring sizeLabels[] = {C_("Icon size", "Large"), C_("Icon size", "Small"), C_("Icon size", "Smaller")};
int sizeValues[] = {0, 1, 2};
_misc_small_tools.init( "/toolbox/tools/small", sizeLabels, sizeValues, G_N_ELEMENTS(sizeLabels), 0 );
@@ -686,7 +686,7 @@ void InkscapePreferences::initPageUI()
_win_ontop_agressive.init ( _("Aggressive"), "/options/transientpolicy/value", 2, false, &_win_ontop_none);
{
- Glib::ustring defaultSizeLabels[] = {_("Small"), _("Large"), _("Maximized")};
+ Glib::ustring defaultSizeLabels[] = {C_("Window size", "Small"), C_("Window size", "Large"), C_("Window size", "Maximized")};
int defaultSizeValues[] = {0, 1, 2};
_win_default_size.init( "/options/defaultwindowsize/value", defaultSizeLabels, defaultSizeValues, G_N_ELEMENTS(defaultSizeLabels), 1 );
diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp
index 835ecf35b..726df9a61 100644
--- a/src/ui/dialog/objects.cpp
+++ b/src/ui/dialog/objects.cpp
@@ -479,7 +479,7 @@ void ObjectsPanel::_objectsSelected( Selection *sel ) {
_tree.get_selection()->unselect_all();
SPItem *item = NULL;
std::vector<SPItem*> const items = sel->itemList();
- for(std::vector<SPItem*>::const_iterator i=items.begin(); i!=items.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=items.begin(); i!=items.end(); ++i){
item = *i;
if (setOpacity)
{
@@ -1614,11 +1614,11 @@ ObjectsPanel::ObjectsPanel() :
_pending(0),
_toggleEvent(0),
_defer_target(),
- _visibleHeader(_("V")),
- _lockHeader(_("L")),
- _typeHeader(_("T")),
- _clipmaskHeader(_("CM")),
- _highlightHeader(_("HL")),
+ _visibleHeader(C_("Visibility", "V")),
+ _lockHeader(C_("Lock", "L")),
+ _typeHeader(C_("Type", "T")),
+ _clipmaskHeader(C_("Clip and mask", "CM")),
+ _highlightHeader(C_("Highlight", "HL")),
_nameHeader(_("Label")),
_composite_vbox(false, 0),
_opacity_vbox(false, 0),
diff --git a/src/ui/dialog/pixelartdialog.cpp b/src/ui/dialog/pixelartdialog.cpp
index 760391df6..f557ff0fc 100644
--- a/src/ui/dialog/pixelartdialog.cpp
+++ b/src/ui/dialog/pixelartdialog.cpp
@@ -373,7 +373,7 @@ void PixelArtDialogImpl::vectorize()
}
std::vector<SPItem*> const items = desktop->selection->itemList();
- for(std::vector<SPItem*>::const_iterator i=items.begin(); i!=items.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=items.begin(); i!=items.end();++i){
if ( !SP_IS_IMAGE(*i) )
continue;
diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp
index af1386e27..5ec1285c1 100644
--- a/src/ui/dialog/polar-arrange-tab.cpp
+++ b/src/ui/dialog/polar-arrange-tab.cpp
@@ -304,7 +304,7 @@ void PolarArrangeTab::arrange()
bool arrangeOnFirstEllipse = arrangeOnEllipse && arrangeOnFirstCircleRadio.get_active();
int count = 0;
- for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();i++)
+ for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();++i)
{
if(arrangeOnEllipse)
{
@@ -373,7 +373,7 @@ void PolarArrangeTab::arrange()
Geom::Point realCenter = Geom::Point(cx, cy) * transformation;
int i = 0;
- for(std::vector<SPItem*>::const_iterator it=tmp.begin();it!=tmp.end();it++)
+ for(std::vector<SPItem*>::const_iterator it=tmp.begin();it!=tmp.end(); ++it)
{
SPItem *item = *it;
diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp
index f36e3f18d..9b6f3219f 100644
--- a/src/ui/dialog/tags.cpp
+++ b/src/ui/dialog/tags.cpp
@@ -353,7 +353,7 @@ void TagsPanel::_objectsSelected( Selection *sel ) {
_selectedConnection.block();
_tree.get_selection()->unselect_all();
std::vector<SPObject*> tmp=sel->list();
- for(std::vector<SPObject*>::const_iterator i=tmp.begin();i!=tmp.end();i++)
+ for(std::vector<SPObject*>::const_iterator i=tmp.begin();i!=tmp.end();++i)
{
SPObject *obj = *i;
_store->foreach(sigc::bind<SPObject *>( sigc::mem_fun(*this, &TagsPanel::_checkForSelected), obj));
@@ -651,7 +651,7 @@ bool TagsPanel::_handleButtonEvent(GdkEventButton* event)
if (SP_IS_TAG(obj)) {
bool wasadded = false;
std::vector<SPItem*> items=_desktop->selection->itemList();
- for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){
SPObject *newobj = *i;
bool addchild = true;
for ( SPObject *child = obj->children; child != NULL; child = child->next) {
diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp
index 7575cc854..05cf3a388 100644
--- a/src/ui/dialog/text-edit.cpp
+++ b/src/ui/dialog/text-edit.cpp
@@ -175,6 +175,19 @@ TextEdit::TextEdit()
gtk_text_view_set_wrap_mode ((GtkTextView *) text_view, GTK_WRAP_WORD);
#ifdef WITH_GTKSPELL
+#ifdef WITH_GTKMM_3_0
+/*
+ TODO: Use computed xml:lang attribute of relevant element, if present, to specify the
+ language (either as 2nd arg of gtkspell_new_attach, or with explicit
+ gtkspell_set_language call in; see advanced.c example in gtkspell docs).
+ onReadSelection looks like a suitable place.
+*/
+ GtkSpellChecker * speller = gtk_spell_checker_new();
+
+ if (! gtk_spell_checker_attach(speller, GTK_TEXT_VIEW(text_view))) {
+ g_print("gtkspell error:\n");
+ }
+#else
GError *error = NULL;
/*
@@ -188,6 +201,7 @@ TextEdit::TextEdit()
g_error_free(error);
}
#endif
+#endif
gtk_widget_set_size_request (text_view, -1, 64);
gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), TRUE);
@@ -430,7 +444,7 @@ SPItem *TextEdit::getSelectedTextItem (void)
return NULL;
std::vector<SPItem*> tmp=SP_ACTIVE_DESKTOP->getSelection()->itemList();
- for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();i++)
+ for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();++i)
{
if (SP_IS_TEXT(*i) || SP_IS_FLOWTEXT(*i))
return *i;
@@ -448,7 +462,7 @@ unsigned TextEdit::getSelectedTextCount (void)
unsigned int items = 0;
std::vector<SPItem*> tmp=SP_ACTIVE_DESKTOP->getSelection()->itemList();
- for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();i++)
+ for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();++i)
{
if (SP_IS_TEXT(*i) || SP_IS_FLOWTEXT(*i))
++items;
@@ -558,7 +572,7 @@ void TextEdit::onApply()
SPCSSAttr *css = fillTextStyle ();
sp_desktop_set_style(desktop, css, true);
- for(std::vector<SPItem*>::const_iterator i=item_list.begin();i!=item_list.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=item_list.begin();i!=item_list.end();++i){
// apply style to the reprs of all text objects in the selection
if (SP_IS_TEXT (*i)) {
diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp
index 6049368f5..ae972bbbd 100644
--- a/src/ui/dialog/transformation.cpp
+++ b/src/ui/dialog/transformation.cpp
@@ -812,7 +812,7 @@ void Transformation::applyPageScale(Inkscape::Selection *selection)
bool preserve = prefs->getBool("/options/preservetransform/value", false);
if (prefs->getBool("/dialogs/transformation/applyseparately")) {
std::vector<SPItem*> tmp=selection->itemList();
- for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();++i){
SPItem *item = *i;
Geom::OptRect bbox_pref = item->desktopPreferredBounds();
Geom::OptRect bbox_geom = item->desktopGeometricBounds();
@@ -876,7 +876,7 @@ void Transformation::applyPageRotate(Inkscape::Selection *selection)
if (prefs->getBool("/dialogs/transformation/applyseparately")) {
std::vector<SPItem*> tmp=selection->itemList();
- for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();++i){
SPItem *item = *i;
sp_item_rotate_rel(item, Geom::Rotate (angle*M_PI/180.0));
}
@@ -896,7 +896,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection)
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (prefs->getBool("/dialogs/transformation/applyseparately")) {
std::vector<SPItem*> items=selection->itemList();
- for(std::vector<SPItem*>::const_iterator i = items.begin();i!=items.end();i++){
+ for(std::vector<SPItem*>::const_iterator i = items.begin();i!=items.end();++i){
SPItem *item = *i;
if (!_units_skew.isAbsolute()) { // percentage
@@ -998,7 +998,7 @@ void Transformation::applyPageTransform(Inkscape::Selection *selection)
if (_check_replace_matrix.get_active()) {
std::vector<SPItem*> tmp=selection->itemList();
- for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();++i){
SPItem *item = *i;
item->set_item_transform(displayed);
item->updateRepr();
diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp
index 0a36877ff..b84d16686 100644
--- a/src/ui/tools/connector-tool.cpp
+++ b/src/ui/tools/connector-tool.cpp
@@ -1307,7 +1307,7 @@ void cc_selection_set_avoid(bool const set_avoid)
int changes = 0;
std::vector<SPItem*> l = selection->itemList();
- for(std::vector<SPItem*>::const_iterator i=l.begin();i!=l.end();i++) {
+ for(std::vector<SPItem*>::const_iterator i=l.begin();i!=l.end(); ++i) {
SPItem *item = *i;
char const *value = (set_avoid) ? "true" : NULL;
diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp
index e416fd7ef..83ecf7a0a 100644
--- a/src/ui/tools/eraser-tool.cpp
+++ b/src/ui/tools/eraser-tool.cpp
@@ -682,7 +682,7 @@ void EraserTool::set_to_accumulated() {
if ( !toWorkOn.empty() ) {
if ( eraserMode ) {
- for (std::vector<SPItem*>::const_iterator i = toWorkOn.begin(); i != toWorkOn.end(); i++){
+ for (std::vector<SPItem*>::const_iterator i = toWorkOn.begin(); i != toWorkOn.end(); ++i){
SPItem *item = *i;
if ( eraserMode ) {
@@ -701,7 +701,7 @@ void EraserTool::set_to_accumulated() {
if ( !selection->isEmpty() ) {
// If the item was not completely erased, track the new remainder.
std::vector<SPItem*> nowSel(selection->itemList());
- for (std::vector<SPItem*>::const_iterator i2 = nowSel.begin();i2!=nowSel.end();i2++) {
+ for (std::vector<SPItem*>::const_iterator i2 = nowSel.begin();i2!=nowSel.end();++i2) {
remainingItems.push_back(*i2);
}
}
@@ -711,11 +711,11 @@ void EraserTool::set_to_accumulated() {
}
}
} else {
- for (std::vector<SPItem*> ::const_iterator i = toWorkOn.begin();i!=toWorkOn.end();i++) {
+ for (std::vector<SPItem*> ::const_iterator i = toWorkOn.begin();i!=toWorkOn.end();++i) {
sp_object_ref( *i, 0 );
}
- for (std::vector<SPItem*>::const_iterator i = toWorkOn.begin();i!=toWorkOn.end();i++) {
+ for (std::vector<SPItem*>::const_iterator i = toWorkOn.begin();i!=toWorkOn.end();++i) {
SPItem *item = *i;
item->deleteObject(true);
sp_object_unref(item);
diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp
index 603458983..bcb0b12b7 100644
--- a/src/ui/tools/gradient-tool.cpp
+++ b/src/ui/tools/gradient-tool.cpp
@@ -495,7 +495,7 @@ bool GradientTool::root_handler(GdkEvent* event) {
sp_gradient_context_add_stop_near_point(this, SP_ITEM(selection->itemList().front()), this->mousepoint_doc, event->button.time);
} else {
std::vector<SPItem*> items=selection->itemList();
- for (std::vector<SPItem*>::const_iterator i = items.begin();i!=items.end();i++) {
+ for (std::vector<SPItem*>::const_iterator i = items.begin();i!=items.end();++i) {
SPItem *item = *i;
SPGradientType new_type = (SPGradientType) prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR);
Inkscape::PaintTarget fsmode = (prefs->getInt("/tools/gradient/newfillorstroke", 1) != 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE;
@@ -910,7 +910,7 @@ static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint /*sta
sp_repr_css_set_property(css, "fill-opacity", "1.0");
std::vector<SPItem*> itemlist = selection->itemList();
- for (std::vector<SPItem*>::const_iterator i = itemlist.begin();i!=itemlist.end();i++) {
+ for (std::vector<SPItem*>::const_iterator i = itemlist.begin();i!=itemlist.end();++i) {
//FIXME: see above
sp_repr_css_change_recursive((*i)->getRepr(), css, "style");
diff --git a/src/ui/tools/lpe-tool.cpp b/src/ui/tools/lpe-tool.cpp
index 13e47f3a6..9bbc1ac20 100644
--- a/src/ui/tools/lpe-tool.cpp
+++ b/src/ui/tools/lpe-tool.cpp
@@ -397,7 +397,7 @@ lpetool_create_measuring_items(LpeTool *lc, Inkscape::Selection *selection)
gchar *arc_length;
double lengthval;
std::vector<SPItem*> items=selection->itemList();
- for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){
if (SP_IS_PATH(*i)) {
path = SP_PATH(*i);
curve = path->getCurve();
diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp
index 570f3e796..06f32ba5c 100644
--- a/src/ui/tools/measure-tool.cpp
+++ b/src/ui/tools/measure-tool.cpp
@@ -4,6 +4,7 @@
* Authors:
* Felipe Correa da Silva Sanches <juca@members.fsf.org>
* Jon A. Cruz <jon@joncruz.org>
+ * Jabiertxo Arraiza <jabier.arraiza@marker.es>
*
* Copyright (C) 2011 Authors
*
@@ -14,40 +15,57 @@
#include <gdk/gdkkeysyms.h>
#include <boost/none_t.hpp>
#include "util/units.h"
-#include "macros.h"
#include "display/curve.h"
-#include "sp-shape.h"
-#include "sp-text.h"
-#include "sp-flowtext.h"
-#include "text-editing.h"
-#include "display/sp-ctrlline.h"
#include "display/sodipodi-ctrl.h"
+#include "display/sp-ctrlline.h"
+#include "display/sp-canvas.h"
#include "display/sp-canvas-item.h"
#include "display/sp-canvas-util.h"
-#include "desktop.h"
-#include "document.h"
-#include "pixmaps/cursor-measure.xpm"
-#include "preferences.h"
-#include "inkscape.h"
-
+#include "svg/svg.h"
+#include "svg/svg-color.h"
#include "ui/tools/measure-tool.h"
#include "ui/tools/freehand-base.h"
-#include "display/canvas-text.h"
-#include "path-chemistry.h"
-#include "2geom/line.h"
+#include <2geom/line.h>
#include <2geom/path-intersection.h>
#include <2geom/pathvector.h>
#include <2geom/crossing.h>
#include <2geom/angle.h>
-#include "snap.h"
+#include <2geom/transforms.h>
#include "sp-namedview.h"
+#include "sp-shape.h"
+#include "sp-text.h"
+#include "sp-flowtext.h"
+#include "sp-defs.h"
+#include "sp-item.h"
+#include "sp-root.h"
+#include "macros.h"
+#include "svg/stringstream.h"
+#include "rubberband.h"
+#include "path-chemistry.h"
+#include "desktop.h"
+#include "document.h"
+#include "document-undo.h"
+#include "viewbox.h"
+#include "snap.h"
+#include "text-editing.h"
+#include "pixmaps/cursor-measure.xpm"
+#include "preferences.h"
+#include "inkscape.h"
+#include "knot.h"
#include "enums.h"
-#include "ui/control-manager.h"
#include "knot-enums.h"
+#include "desktop-style.h"
+#include "verbs.h"
+#include <glibmm/i18n.h>
using Inkscape::ControlManager;
using Inkscape::CTLINE_SECONDARY;
using Inkscape::Util::unit_table;
+using Inkscape::DocumentUndo;
+
+#define MT_KNOT_COLOR_NORMAL 0xffffff00
+#define MT_KNOT_COLOR_MOUSEOVER 0xff000000
+
namespace Inkscape {
namespace UI {
@@ -55,16 +73,14 @@ namespace Tools {
std::vector<Inkscape::Display::TemporaryItem*> measure_tmp_items;
-const std::string& MeasureTool::getPrefsPath() {
- return MeasureTool::prefsPath;
+const std::string& MeasureTool::getPrefsPath()
+{
+ return MeasureTool::prefsPath;
}
const std::string MeasureTool::prefsPath = "/tools/measure";
-namespace
-{
-
-gint const DIMENSION_OFFSET = 35;
+namespace {
/**
* Simple class to use for removing label overlap.
@@ -87,14 +103,16 @@ bool SortLabelPlacement(LabelPlacement const &first, LabelPlacement const &secon
}
}
-void repositionOverlappingLabels(std::vector<LabelPlacement> &placements, SPDesktop *desktop, Geom::Point const &normal, double fontsize)
+//precision is for give the number of decimal positions
+//of the label to calculate label width
+void repositionOverlappingLabels(std::vector<LabelPlacement> &placements, SPDesktop *desktop, Geom::Point const &normal, double fontsize, int precision)
{
std::sort(placements.begin(), placements.end(), SortLabelPlacement);
double border = 3;
Geom::Rect box;
{
- Geom::Point tmp(fontsize * 8 + (border * 2), fontsize + (border * 2));
+ Geom::Point tmp(fontsize * (6 + precision) + (border * 2), fontsize + (border * 2));
tmp = desktop->w2d(tmp);
box = Geom::Rect(-tmp[Geom::X] / 2, -tmp[Geom::Y] / 2, tmp[Geom::X] / 2, tmp[Geom::Y] / 2);
}
@@ -175,6 +193,76 @@ Geom::Point calcAngleDisplayAnchor(SPDesktop *desktop, double angle, double base
}
/**
+ * Create a measure iten in current document.
+ *
+ * @param pathv the path to create.
+ * @param markers, if the path resuts get markers.
+ * @param color of the stroke.
+ * @param measure_repr container element.
+ */
+void setMeasureItem(Geom::PathVector pathv, bool is_curve, bool markers, guint32 color, Inkscape::XML::Node *measure_repr)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if(!desktop) {
+ return;
+ }
+ SPDocument *doc = desktop->getDocument();
+ Inkscape::XML::Document *xml_doc = doc->getReprDoc();
+ Inkscape::XML::Node *repr;
+ repr = xml_doc->createElement("svg:path");
+ gchar *str = sp_svg_write_path(pathv);
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ Geom::Coord strokewidth = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse().expansionX();
+ std::stringstream stroke_width;
+ stroke_width.imbue(std::locale::classic());
+ if(measure_repr) {
+ stroke_width << strokewidth / desktop->current_zoom();
+ } else {
+ stroke_width << strokewidth;
+ }
+ sp_repr_css_set_property (css, "stroke-width", stroke_width.str().c_str());
+ sp_repr_css_set_property (css, "fill", "none");
+ if(color) {
+ gchar color_line[64];
+ sp_svg_write_color (color_line, sizeof(color_line), color);
+ sp_repr_css_set_property (css, "stroke", color_line);
+ } else {
+ sp_repr_css_set_property (css, "stroke", "#ff0000");
+ }
+ char const * stroke_linecap = is_curve ? "butt" : "square";
+ sp_repr_css_set_property (css, "stroke-linecap", stroke_linecap);
+ sp_repr_css_set_property (css, "stroke-linejoin", "miter");
+ sp_repr_css_set_property (css, "stroke-miterlimit", "4");
+ sp_repr_css_set_property (css, "stroke-dasharray", "none");
+ if(measure_repr) {
+ sp_repr_css_set_property (css, "stroke-opacity", "0.5");
+ } else {
+ sp_repr_css_set_property (css, "stroke-opacity", "1");
+ }
+ if(markers) {
+ sp_repr_css_set_property (css, "marker-start", "url(#Arrow2Sstart)");
+ sp_repr_css_set_property (css, "marker-end", "url(#Arrow2Send)");
+ }
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ repr->setAttribute("style", css_str.c_str());
+ sp_repr_css_attr_unref (css);
+ g_assert( str != NULL );
+ repr->setAttribute("d", str);
+ g_free(str);
+ if(measure_repr) {
+ measure_repr->addChild(repr, NULL);
+ Inkscape::GC::release(repr);
+ } else {
+ SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr));
+ Inkscape::GC::release(repr);
+ item->updateRepr();
+ desktop->getSelection()->clear();
+ desktop->getSelection()->add(item);
+ }
+}
+
+/**
* Given an angle, the arc center and edge point, draw an arc segment centered around that edge point.
*
* @param desktop the desktop that is being used.
@@ -182,8 +270,9 @@ Geom::Point calcAngleDisplayAnchor(SPDesktop *desktop, double angle, double base
* @param end the point that ends at the edge of the arc segment.
* @param anchor the anchor point for displaying the text label.
* @param angle the angle of the arc segment to draw.
+ * @param measure_rpr the container of the curve if converted to items.
*/
-void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const &center, Geom::Point const &end, Geom::Point const &anchor, double angle)
+void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const &center, Geom::Point const &end, Geom::Point const &anchor, double angle, Inkscape::XML::Node *measure_repr = NULL)
{
// Given that we have a point on the arc's edge and the angle of the arc, we need to get the two endpoints.
@@ -191,7 +280,7 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const &center, Geom
double sideLen = std::abs((end - center).length());
if (sideLen > 0.0) {
double factor = std::min(1.0, textLen / sideLen);
-
+
// arc start
Geom::Point p1 = end * (Geom::Affine(Geom::Translate(-center))
* Geom::Affine(Geom::Scale(factor))
@@ -221,22 +310,186 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const &center, Geom
SPCtrlCurve *curve = ControlManager::getManager().createControlCurve(desktop->getTempGroup(), p1, p2, p3, p4, CTLINE_SECONDARY);
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(SP_CANVAS_ITEM(curve), 0, true));
+ if(measure_repr) {
+ Geom::PathVector pathv;
+ Geom::Path path;
+ path.start(desktop->doc2dt(p1));
+ path.appendNew<Geom::CubicBezier>(desktop->doc2dt(p2),desktop->doc2dt(p3),desktop->doc2dt(p4));
+ pathv.push_back(path);
+ pathv *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ if(!pathv.empty()) {
+ setMeasureItem(pathv, true, false, 0xff00007f, measure_repr);
+ }
+ }
}
}
} // namespace
-
MeasureTool::MeasureTool()
: ToolBase(cursor_measure_xpm, 4, 4)
, grabbed(NULL)
{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ start_p = readMeasurePoint(true);
+ end_p = readMeasurePoint(false);
+ dimension_offset = 35;
+ // create the knots
+ this->knot_start = new SPKnot(desktop, N_("Measure start"));
+ this->knot_start->setMode(SP_KNOT_MODE_XOR);
+ this->knot_start->setFill(MT_KNOT_COLOR_NORMAL, MT_KNOT_COLOR_MOUSEOVER, MT_KNOT_COLOR_MOUSEOVER);
+ this->knot_start->setStroke(0x0000007f, 0x0000007f, 0x0000007f);
+ this->knot_start->setShape(SP_KNOT_SHAPE_CIRCLE);
+ this->knot_start->updateCtrl();
+ this->knot_end = new SPKnot(desktop, N_("Measure end"));
+ this->knot_end->setMode(SP_KNOT_MODE_XOR);
+ this->knot_end->setFill(MT_KNOT_COLOR_NORMAL, MT_KNOT_COLOR_MOUSEOVER, MT_KNOT_COLOR_MOUSEOVER);
+ this->knot_end->setStroke(0x0000007f, 0x0000007f, 0x0000007f);
+ this->knot_end->setShape(SP_KNOT_SHAPE_CIRCLE);
+ this->knot_end->updateCtrl();
+ Geom::Rect display_area = desktop->get_display_area();
+ if(display_area.interiorContains(start_p) && display_area.interiorContains(end_p) && end_p != Geom::Point()) {
+ this->knot_start->moveto(start_p);
+ this->knot_start->show();
+ this->knot_end->moveto(end_p);
+ this->knot_end->show();
+ showCanvasItems();
+ } else {
+ start_p = Geom::Point(0,0);
+ end_p = Geom::Point(0,0);
+ writeMeasurePoint(start_p, true);
+ writeMeasurePoint(end_p, false);
+ }
+
+ this->_knot_start_moved_connection = this->knot_start->moved_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotStartMovedHandler));
+ this->_knot_start_ungrabbed_connection = this->knot_start->ungrabbed_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotUngrabbedHandler));
+ this->_knot_end_moved_connection = this->knot_end->moved_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotEndMovedHandler));
+ this->_knot_end_ungrabbed_connection = this->knot_end->ungrabbed_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotUngrabbedHandler));
+
}
-MeasureTool::~MeasureTool() {
+MeasureTool::~MeasureTool()
+{
+ this->_knot_start_moved_connection.disconnect();
+ this->_knot_start_ungrabbed_connection.disconnect();
+ this->_knot_end_moved_connection.disconnect();
+ this->_knot_end_ungrabbed_connection.disconnect();
+
+ /* unref should call destroy */
+ knot_unref(this->knot_start);
+ knot_unref(this->knot_end);
+ for (size_t idx = 0; idx < measure_tmp_items.size(); ++idx) {
+ desktop->remove_temporary_canvasitem(measure_tmp_items[idx]);
+ }
+ measure_tmp_items.clear();
}
-void MeasureTool::finish() {
+Geom::Point MeasureTool::readMeasurePoint(bool is_start) {
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPNamedView *namedview = desktop->namedview;
+ if(!namedview) {
+ return Geom::Point(Geom::infinity(),Geom::infinity());
+ }
+ char const * measure_point = is_start ? "inkscape:measure-start" : "inkscape:measure-end";
+ char const * measure_point_data = namedview->getAttribute (measure_point);
+ if(!measure_point_data) {
+ measure_point_data = "0,0";
+ namedview->setAttribute (measure_point, measure_point_data);
+ }
+ gchar ** strarray = g_strsplit(measure_point_data, ",", 2);
+ double newx, newy;
+ unsigned int success = sp_svg_number_read_d(strarray[0], &newx);
+ success += sp_svg_number_read_d(strarray[1], &newy);
+ g_strfreev (strarray);
+ if (success == 2) {
+ Geom::Point point_data(newx, newy);
+ return point_data;
+ }
+ return Geom::Point(Geom::infinity(),Geom::infinity());
+
+}
+
+void MeasureTool::writeMeasurePoint(Geom::Point point, bool is_start) {
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPNamedView *namedview = desktop->namedview;
+ if(!namedview) {
+ return;
+ }
+ std::stringstream meassure_point_str;
+ meassure_point_str.imbue(std::locale::classic());
+ meassure_point_str << point[Geom::X] << "," << point[Geom::Y];
+ gchar const *measure_point = is_start ? "inkscape:measure-start" : "inkscape:measure-end";
+ namedview->setAttribute (measure_point, meassure_point_str.str().c_str());
+}
+
+//This function is used to reverse the Measure, I do it in two steps because when move the knot the
+//start_ or the end_p are overwrite so I need the original values.
+void MeasureTool::reverseKnots()
+{
+ Geom::Point start = start_p;
+ Geom::Point end = end_p;
+ this->knot_start->moveto(end);
+ this->knot_start->show();
+ this->knot_end->moveto(start);
+ this->knot_end->show();
+ start_p = end;
+ end_p = start;
+ this->showCanvasItems();
+}
+
+void MeasureTool::knotStartMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state)
+{
+ Geom::Point point = this->knot_start->position();
+ if (state & GDK_CONTROL_MASK) {
+ spdc_endpoint_snap_rotation(this, point, end_p, state);
+ } else if (!(state & GDK_SHIFT_MASK)) {
+ SnapManager &snap_manager = desktop->namedview->snap_manager;
+ snap_manager.setup(desktop);
+ Inkscape::SnapCandidatePoint scp(point, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ scp.addOrigin(this->knot_end->position());
+ Inkscape::SnappedPoint sp = snap_manager.freeSnap(scp);
+ point = sp.getPoint();
+ snap_manager.unSetup();
+ }
+ if(start_p != point) {
+ start_p = point;
+ this->knot_start->moveto(start_p);
+ }
+ showCanvasItems();
+}
+
+void MeasureTool::knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state)
+{
+ Geom::Point point = this->knot_end->position();
+ if (state & GDK_CONTROL_MASK) {
+ spdc_endpoint_snap_rotation(this, point, start_p, state);
+ } else if (!(state & GDK_SHIFT_MASK)) {
+ SnapManager &snap_manager = desktop->namedview->snap_manager;
+ snap_manager.setup(desktop);
+ Inkscape::SnapCandidatePoint scp(point, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ scp.addOrigin(this->knot_start->position());
+ Inkscape::SnappedPoint sp = snap_manager.freeSnap(scp);
+ point = sp.getPoint();
+ snap_manager.unSetup();
+ }
+ if(end_p != point) {
+ end_p = point;
+ this->knot_end->moveto(end_p);
+ }
+ showCanvasItems();
+}
+
+void MeasureTool::knotUngrabbedHandler(SPKnot */*knot*/, unsigned int state)
+{
+ this->knot_start->moveto(start_p);
+ this->knot_end->moveto(end_p);
+ showCanvasItems();
+}
+
+
+
+void MeasureTool::finish()
+{
this->enableGrDrag(false);
if (this->grabbed) {
@@ -247,498 +500,773 @@ void MeasureTool::finish() {
ToolBase::finish();
}
-//void MeasureTool::setup() {
-// ToolBase* ec = this;
-//
-//// if (SP_EVENT_CONTEXT_CLASS(sp_measure_context_parent_class)->setup) {
-//// SP_EVENT_CONTEXT_CLASS(sp_measure_context_parent_class)->setup(ec);
-//// }
-// ToolBase::setup();
-//}
-
-//gint MeasureTool::item_handler(SPItem* item, GdkEvent* event) {
-// gint ret = FALSE;
-//
-//// if (SP_EVENT_CONTEXT_CLASS(sp_measure_context_parent_class)->item_handler) {
-//// ret = SP_EVENT_CONTEXT_CLASS(sp_measure_context_parent_class)->item_handler(event_context, item, event);
-//// }
-// ret = ToolBase::item_handler(item, event);
-//
-// return ret;
-//}
-
static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom::PathVector const &lineseg, SPCurve *curve, std::vector<double> &intersections)
{
-
curve->transform(item->i2doc_affine());
// Find all intersections of the control-line with this shape
Geom::CrossingSet cs = Geom::crossings(lineseg, curve->get_pathvector());
Geom::delete_duplicates(cs[0]);
// Reconstruct and store the points of intersection
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool only_visible = prefs->getBool("/tools/measure/only_visible", false);
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
for (Geom::Crossings::const_iterator m = cs[0].begin(); m != cs[0].end(); ++m) {
-#if 0
-//TODO: consider only visible intersections
- Geom::Point intersection = lineseg[0].pointAt((*m).ta);
- double eps = 0.0001;
- SPDocument* doc = desktop->getDocument();
- if (((*m).ta > eps &&
- item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta - eps), false, NULL)) ||
+ if(only_visible) {
+ double eps = 0.0001;
+ if (((*m).ta > eps &&
+ item == desktop->getItemAtPoint(desktop->d2w(desktop->dt2doc(lineseg[0].pointAt((*m).ta - eps))), true, NULL)) ||
((*m).ta + eps < 1 &&
- item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta + eps), false, NULL)) ) {
+ item == desktop->getItemAtPoint(desktop->d2w(desktop->dt2doc(lineseg[0].pointAt((*m).ta + eps))), true, NULL))) {
+ intersections.push_back((*m).ta);
+ }
+ } else {
intersections.push_back((*m).ta);
}
-#else
- intersections.push_back((*m).ta);
-
-#endif
}
}
-bool MeasureTool::root_handler(GdkEvent* event) {
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
-
+bool MeasureTool::root_handler(GdkEvent* event)
+{
gint ret = FALSE;
switch (event->type) {
- case GDK_BUTTON_PRESS: {
- Geom::Point const button_w(event->button.x, event->button.y);
- explicitBase = boost::none;
- lastEnd = boost::none;
- start_point = desktop->w2d(button_w);
-
- if (event->button.button == 1 && !this->space_panning) {
- // save drag origin
- xp = static_cast<gint>(event->button.x);
- yp = static_cast<gint>(event->button.y);
- within_tolerance = true;
-
- ret = TRUE;
- }
+ case GDK_BUTTON_PRESS: {
+ this->knot_start->hide();
+ this->knot_end->hide();
+ Geom::Point const button_w(event->button.x, event->button.y);
+ explicitBase = boost::none;
+ last_end = boost::none;
+ start_p = desktop->w2d(button_w);
+
+ if (event->button.button == 1 && !this->space_panning) {
+ // save drag origin
+ start_p = desktop->w2d(Geom::Point(event->button.x, event->button.y));
+ within_tolerance = true;
+
+ ret = TRUE;
+ }
- SnapManager &m = desktop->namedview->snap_manager;
- m.setup(desktop);
- m.freeSnapReturnByRef(start_point, Inkscape::SNAPSOURCE_OTHER_HANDLE);
- m.unSetup();
+ SnapManager &snap_manager = desktop->namedview->snap_manager;
+ snap_manager.setup(desktop);
+ snap_manager.freeSnapReturnByRef(start_p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ snap_manager.unSetup();
- sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
- GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK,
- NULL, event->button.time);
- this->grabbed = SP_CANVAS_ITEM(desktop->acetate);
- break;
- }
- case GDK_KEY_PRESS: {
- if ((event->key.keyval == GDK_KEY_Shift_L) || (event->key.keyval == GDK_KEY_Shift_R)) {
- if (lastEnd) {
- explicitBase = lastEnd;
- }
- }
- break;
+ sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
+ GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK,
+ NULL, event->button.time);
+ this->grabbed = SP_CANVAS_ITEM(desktop->acetate);
+ break;
+ }
+ case GDK_KEY_PRESS: {
+ if ((event->key.keyval == GDK_KEY_Shift_L) || (event->key.keyval == GDK_KEY_Shift_R)) {
+ explicitBase = end_p;
}
- case GDK_MOTION_NOTIFY: {
- if (!((event->motion.state & GDK_BUTTON1_MASK) && !this->space_panning)) {
- if (!(event->motion.state & GDK_SHIFT_MASK)) {
- Geom::Point const motion_w(event->motion.x, event->motion.y);
- Geom::Point const motion_dt(desktop->w2d(motion_w));
-
- SnapManager &m = desktop->namedview->snap_manager;
- m.setup(desktop);
+ break;
+ }
+ case GDK_MOTION_NOTIFY: {
+ if (!(event->motion.state & GDK_BUTTON1_MASK)) {
+ if(!(event->motion.state & GDK_SHIFT_MASK)) {
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point const motion_dt(desktop->w2d(motion_w));
- Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE);
- scp.addOrigin(start_point);
+ SnapManager &snap_manager = desktop->namedview->snap_manager;
+ snap_manager.setup(desktop);
- m.preSnap(scp);
- m.unSetup();
- }
- } else {
- ret = TRUE;
+ Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ scp.addOrigin(start_p);
- if ( within_tolerance
- && ( abs( static_cast<gint>(event->motion.x) - xp ) < tolerance )
- && ( abs( static_cast<gint>(event->motion.y) - yp ) < tolerance ) ) {
- break; // do not drag if we're within tolerance from origin
- }
- // Once the user has moved farther than tolerance from the original location
- // (indicating they intend to move the object, not click), then always process the
- // motion notify coordinates as given (no snapping back to origin)
- within_tolerance = false;
-
- //clear previous temporary canvas items, we'll draw new ones
- for (size_t idx = 0; idx < measure_tmp_items.size(); ++idx) {
- desktop->remove_temporary_canvasitem(measure_tmp_items[idx]);
+ snap_manager.preSnap(scp);
+ snap_manager.unSetup();
+ }
+ } else {
+ ret = TRUE;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ if ( within_tolerance) {
+ if ( Geom::LInfty( motion_w - start_p ) < tolerance) {
+ return FALSE; // Do not drag if we're within tolerance from origin.
}
-
- measure_tmp_items.clear();
-
+ }
+ // Once the user has moved farther than tolerance from the original location
+ // (indicating they intend to move the object, not click), then always process the
+ // motion notify coordinates as given (no snapping back to origin)
+ within_tolerance = false;
+ if(event->motion.time == 0 || !last_end || Geom::LInfty( motion_w - *last_end ) > (tolerance/4.0)) {
Geom::Point const motion_w(event->motion.x, event->motion.y);
Geom::Point const motion_dt(desktop->w2d(motion_w));
- Geom::Point end_point = motion_dt;
+ end_p = motion_dt;
if (event->motion.state & GDK_CONTROL_MASK) {
- spdc_endpoint_snap_rotation(this, end_point, start_point, event->motion.state);
- } else {
- if (!(event->motion.state & GDK_SHIFT_MASK)) {
- SnapManager &m = desktop->namedview->snap_manager;
- m.setup(desktop);
- Inkscape::SnapCandidatePoint scp(end_point, Inkscape::SNAPSOURCE_OTHER_HANDLE);
- scp.addOrigin(start_point);
- Inkscape::SnappedPoint sp = m.freeSnap(scp);
- end_point = sp.getPoint();
- m.unSetup();
- }
- }
-
- Geom::PathVector lineseg;
- Geom::Path p;
- p.start(desktop->dt2doc(start_point));
- p.appendNew<Geom::LineSegment>(desktop->dt2doc(end_point));
- lineseg.push_back(p);
-
- double deltax = end_point[Geom::X] - start_point[Geom::X];
- double deltay = end_point[Geom::Y] - start_point[Geom::Y];
- double angle = atan2(deltay, deltax);
- double baseAngle = 0;
-
- if (explicitBase) {
- double deltax2 = explicitBase.get()[Geom::X] - start_point[Geom::X];
- double deltay2 = explicitBase.get()[Geom::Y] - start_point[Geom::Y];
-
- baseAngle = atan2(deltay2, deltax2);
- angle -= baseAngle;
-
- if (angle < -M_PI) {
- angle += 2 * M_PI;
- } else if (angle > M_PI) {
- angle -= 2 * M_PI;
- }
+ spdc_endpoint_snap_rotation(this, end_p, start_p, event->motion.state);
+ } else if (!(event->motion.state & GDK_SHIFT_MASK)) {
+ SnapManager &snap_manager = desktop->namedview->snap_manager;
+ snap_manager.setup(desktop);
+ Inkscape::SnapCandidatePoint scp(end_p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ scp.addOrigin(start_p);
+ Inkscape::SnappedPoint sp = snap_manager.freeSnap(scp);
+ end_p = sp.getPoint();
+ snap_manager.unSetup();
}
+ showCanvasItems();
+ last_end = motion_w ;
+ }
+ gobble_motion_events(GDK_BUTTON1_MASK);
+ }
+ break;
+ }
+ case GDK_BUTTON_RELEASE: {
+ this->knot_start->moveto(start_p);
+ this->knot_start->show();
+ if(last_end) {
+ end_p = desktop->w2d(*last_end);
+ if (event->button.state & GDK_CONTROL_MASK) {
+ spdc_endpoint_snap_rotation(this, end_p, start_p, event->motion.state);
+ } else if (!(event->button.state & GDK_SHIFT_MASK)) {
+ SnapManager &snap_manager = desktop->namedview->snap_manager;
+ snap_manager.setup(desktop);
+ Inkscape::SnapCandidatePoint scp(end_p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ scp.addOrigin(start_p);
+ Inkscape::SnappedPoint sp = snap_manager.freeSnap(scp);
+ end_p = sp.getPoint();
+ snap_manager.unSetup();
+ }
+ }
+ this->knot_end->moveto(end_p);
+ this->knot_end->show();
+ showCanvasItems();
-//TODO: calculate NPOINTS
-//800 seems to be a good value for 800x600 resolution
-#define NPOINTS 800
+ if (this->grabbed) {
+ sp_canvas_item_ungrab(this->grabbed, event->button.time);
+ this->grabbed = NULL;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ if (!ret) {
+ ret = ToolBase::root_handler(event);
+ }
- std::vector<Geom::Point> points;
+ return ret;
+}
- for (double i = 0; i < NPOINTS; i++) {
- points.push_back(desktop->d2w(start_point + (i / NPOINTS) * (end_point - start_point)));
- }
+void MeasureTool::setMarkers()
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPDocument *doc = desktop->getDocument();
+ SPObject *arrowStart = doc->getObjectById("Arrow2Sstart");
+ SPObject *arrowEnd = doc->getObjectById("Arrow2Send");
+ if (!arrowStart) {
+ setMarker(true);
+ }
+ if(!arrowEnd) {
+ setMarker(false);
+ }
+}
+void MeasureTool::setMarker(bool isStart)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPDocument *doc = desktop->getDocument();
+ SPDefs *defs = doc->getDefs();
+ Inkscape::XML::Node *rmarker;
+ Inkscape::XML::Document *xml_doc = doc->getReprDoc();
+ rmarker = xml_doc->createElement("svg:marker");
+ rmarker->setAttribute("id", isStart ? "Arrow2Sstart" : "Arrow2Send");
+ rmarker->setAttribute("inkscape:isstock", "true");
+ rmarker->setAttribute("inkscape:stockid", isStart ? "Arrow2Sstart" : "Arrow2Send");
+ rmarker->setAttribute("orient", "auto");
+ rmarker->setAttribute("refX", "0.0");
+ rmarker->setAttribute("refY", "0.0");
+ rmarker->setAttribute("style", "overflow:visible;");
+ SPItem *marker = SP_ITEM(defs->appendChildRepr(rmarker));
+ Inkscape::GC::release(rmarker);
+ marker->updateRepr();
+ Inkscape::XML::Node *rpath;
+ rpath = xml_doc->createElement("svg:path");
+ rpath->setAttribute("d", "M 8.72,4.03 L -2.21,0.02 L 8.72,-4.00 C 6.97,-1.63 6.98,1.62 8.72,4.03 z");
+ rpath->setAttribute("id", isStart ? "Arrow2SstartPath" : "Arrow2SendPath");
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ sp_repr_css_set_property (css, "stroke", "none");
+ sp_repr_css_set_property (css, "fill", "#000000");
+ sp_repr_css_set_property (css, "fill-opacity", "1");
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ rpath->setAttribute("style", css_str.c_str());
+ sp_repr_css_attr_unref (css);
+ rpath->setAttribute("transform", isStart ? "scale(0.3) translate(-2.3,0)" : "scale(0.3) rotate(180) translate(-2.3,0)");
+ SPItem *path = SP_ITEM(marker->appendChildRepr(rpath));
+ Inkscape::GC::release(rpath);
+ path->updateRepr();
+}
- // TODO: Felipe, why don't you simply iterate over all items, and test whether their bounding boxes intersect
- // with the measurement line, instead of interpolating over 800 points? E.g. bbox_of_measurement_line.intersects(*bbox_of_item).
- // That's also how the object-snapper works, see _findCandidates() in object-snapper.cpp.
-
- // TODO switch to a different variable name. The single letter 'l' is easy to misread.
-
- //select elements crossed by line segment:
- std::vector<SPItem*> items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, points);
- std::vector<double> intersection_times;
- for (std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++) {
- SPItem *item = *i;
-
- if (SP_IS_SHAPE(item)) {
- calculate_intersections(desktop, item, lineseg, SP_SHAPE(item)->getCurve(), intersection_times);
- } else {
- if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) {
- Inkscape::Text::Layout::iterator iter = te_get_layout(item)->begin();
- do {
- Inkscape::Text::Layout::iterator iter_next = iter;
- iter_next.nextGlyph(); // iter_next is one glyph ahead from iter
- if (iter == iter_next) {
- break;
- }
-
- // get path from iter to iter_next:
- SPCurve *curve = te_get_layout(item)->convertToCurves(iter, iter_next);
- iter = iter_next; // shift to next glyph
- if (!curve) {
- continue; // error converting this glyph
- }
- if (curve->is_empty()) { // whitespace glyph?
- curve->unref();
- continue;
- }
-
- curve->transform(item->i2doc_affine());
-
- calculate_intersections(desktop, item, lineseg, curve, intersection_times);
-
- if (iter == te_get_layout(item)->end()) {
- break;
- }
- } while (true);
- }
- }
- }
+void MeasureTool::toGuides()
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if(!desktop || !start_p.isFinite() || !end_p.isFinite() || start_p == end_p) {
+ return;
+ }
+ SPDocument *doc = desktop->getDocument();
+ Geom::Point start = desktop->doc2dt(start_p) * desktop->doc2dt();
+ Geom::Point end = desktop->doc2dt(end_p) * desktop->doc2dt();
+ Geom::Ray ray(start,end);
+ SPNamedView *namedview = desktop->namedview;
+ if(!namedview) {
+ return;
+ }
+ setGuide(start,ray.angle(), _("Measure"));
+ if(explicitBase) {
+ explicitBase = *explicitBase * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ ray.setPoints(start, *explicitBase);
+ if(ray.angle() != 0) {
+ setGuide(start,ray.angle(), _("Base"));
+ }
+ }
+ setGuide(start,0,"");
+ setGuide(start,Geom::deg_to_rad(90),_("Start"));
+ setGuide(end,0,_("End"));
+ setGuide(end,Geom::deg_to_rad(90),"");
+ showCanvasItems(true);
+ doc->ensureUpToDate();
+ DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add guides from measure tool"));
+}
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true)) {
- intersection_times.push_back(0);
- intersection_times.push_back(1);
- }
+void MeasureTool::toItem()
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if(!desktop || !start_p.isFinite() || !end_p.isFinite() || start_p == end_p) {
+ return;
+ }
+ SPDocument *doc = desktop->getDocument();
+ Geom::Ray ray(start_p,end_p);
+ guint32 line_color_primary = 0x0000ff7f;
+ Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
+ Inkscape::XML::Node *rgroup = xml_doc->createElement("svg:g");
+ showCanvasItems(false, true, rgroup);
+ setLine(start_p,end_p, false, line_color_primary, rgroup);
+ SPItem *measure_item = SP_ITEM(desktop->currentLayer()->appendChildRepr(rgroup));
+ Inkscape::GC::release(rgroup);
+ measure_item->updateRepr();
+ doc->ensureUpToDate();
+ DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Convert measure to items"));
+ reset();
+}
- Glib::ustring unit_name = prefs->getString("/tools/measure/unit");
- if (!unit_name.compare("")) {
- unit_name = "px";
- }
+void MeasureTool::toMarkDimension()
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if(!desktop || !start_p.isFinite() || !end_p.isFinite() || start_p == end_p) {
+ return;
+ }
+ SPDocument *doc = desktop->getDocument();
+ setMarkers();
+ Geom::Ray ray(start_p,end_p);
+ Geom::Point start = start_p + Geom::Point::polar(ray.angle(), 5);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ dimension_offset = prefs->getDouble("/tools/measure/offset", 5.0);
+ start = start + Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -dimension_offset);
+ Geom::Point end = end_p + Geom::Point::polar(ray.angle(), -5);
+ end = end+ Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -dimension_offset);
+ guint32 color = 0x000000ff;
+ setLine(start, end, true, color);
+ Glib::ustring unit_name = prefs->getString("/tools/measure/unit");
+ if (!unit_name.compare("")) {
+ unit_name = "px";
+ }
+ double fontsize = prefs->getDouble("/tools/measure/fontsize", 10.0);
+ int precision = prefs->getInt("/tools/measure/precision", 2);
+ std::stringstream precision_str;
+ precision_str.imbue(std::locale::classic());
+ precision_str << "%." << precision << "f %s";
+ Geom::Point middle = Geom::middle_point(start, end);
+ double totallengthval = (end_p - start_p).length();
+ totallengthval = Inkscape::Util::Quantity::convert(totallengthval, "px", unit_name);
+ double scale = prefs->getDouble("/tools/measure/scale", 100.0) / 100.0;
+ gchar *totallength_str = g_strdup_printf(precision_str.str().c_str(), totallengthval * scale, unit_name.c_str());
+ setLabelText(totallength_str, middle, fontsize, Geom::deg_to_rad(180) - ray.angle(), color);
+ g_free(totallength_str);
+ doc->ensureUpToDate();
+ DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add global measure line"));
+}
- double fontsize = prefs->getInt("/tools/measure/fontsize");
+void MeasureTool::setGuide(Geom::Point origin,double angle, const char *label)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPDocument *doc = desktop->getDocument();
+ Inkscape::XML::Document *xml_doc = doc->getReprDoc();
+ SPRoot const *root = doc->getRoot();
+ Geom::Affine affine(Geom::identity());
+ if(root) {
+ affine *= root->c2p.inverse();
+ }
+ SPNamedView *namedview = desktop->namedview;
+ if(!namedview) {
+ return;
+ }
+ origin *= affine;
+ //measure angle
+ Inkscape::XML::Node *guide;
+ guide = xml_doc->createElement("sodipodi:guide");
+ std::stringstream position;
+ position.imbue(std::locale::classic());
+ position << origin[Geom::X] << "," << origin[Geom::Y];
+ guide->setAttribute("position", position.str().c_str() );
+ guide->setAttribute("inkscape:color", "rgb(167,0,255)");
+ guide->setAttribute("inkscape:label", label);
+ Geom::Point unit_vector = Geom::rot90(origin.polar(angle));
+ std::stringstream angle_str;
+ angle_str.imbue(std::locale::classic());
+ angle_str << unit_vector[Geom::X] << "," << unit_vector[Geom::Y];
+ guide->setAttribute("orientation", angle_str.str().c_str());
+ namedview->appendChild(guide);
+ Inkscape::GC::release(guide);
+}
- // Normal will be used for lines and text
- Geom::Point windowNormal = Geom::unit_vector(Geom::rot90(desktop->d2w(end_point - start_point)));
- Geom::Point normal = desktop->w2d(windowNormal);
+void MeasureTool::setLine(Geom::Point start_point,Geom::Point end_point, bool markers, guint32 color, Inkscape::XML::Node *measure_repr)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if(!desktop || !start_p.isFinite() || !end_p.isFinite()) {
+ return;
+ }
+ Geom::PathVector pathv;
+ Geom::Path path;
+ path.start(desktop->doc2dt(start_point));
+ path.appendNew<Geom::LineSegment>(desktop->doc2dt(end_point));
+ pathv.push_back(path);
+ pathv *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ if(!pathv.empty()) {
+ setMeasureItem(pathv, false, markers, color, measure_repr);
+ }
+}
- std::vector<Geom::Point> intersections;
- std::sort(intersection_times.begin(), intersection_times.end());
- for (std::vector<double>::iterator iter_t = intersection_times.begin(); iter_t != intersection_times.end(); iter_t++) {
- intersections.push_back(lineseg[0].pointAt(*iter_t));
- }
+void MeasureTool::setPoint(Geom::Point origin, Inkscape::XML::Node *measure_repr)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if(!desktop || !origin.isFinite()) {
+ return;
+ }
+ char const * svgd;
+ svgd = "m 0.707,0.707 6.586,6.586 m 0,-6.586 -6.586,6.586";
+ Geom::PathVector pathv = sp_svg_read_pathv(svgd);
+ Geom::Scale scale = Geom::Scale(desktop->current_zoom()).inverse();
+ pathv *= Geom::Translate(Geom::Point(-3.5,-3.5));
+ pathv *= scale;
+ pathv *= Geom::Translate(Geom::Point() - (scale.vector() * 0.5));
+ pathv *= Geom::Translate(desktop->doc2dt(origin));
+ pathv *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ if (!pathv.empty()) {
+ guint32 line_color_secondary = 0xff0000ff;
+ setMeasureItem(pathv, false, false, line_color_secondary, measure_repr);
+ }
+}
- std::vector<LabelPlacement> placements;
- for (size_t idx = 1; idx < intersections.size(); ++idx) {
- LabelPlacement placement;
- placement.lengthVal = (intersections[idx] - intersections[idx - 1]).length();
- placement.lengthVal = Inkscape::Util::Quantity::convert(placement.lengthVal, "px", unit_name);
- placement.offset = DIMENSION_OFFSET;
- placement.start = desktop->doc2dt( (intersections[idx - 1] + intersections[idx]) / 2 );
- placement.end = placement.start - (normal * placement.offset);
+void MeasureTool::setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle, guint32 background, Inkscape::XML::Node *measure_repr, CanvasTextAnchorPositionEnum text_anchor)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
+ /* Create <text> */
+ pos = desktop->doc2dt(pos);
+ Inkscape::XML::Node *rtext = xml_doc->createElement("svg:text");
+ rtext->setAttribute("xml:space", "preserve");
+
+
+ /* Set style */
+ sp_desktop_apply_style_tool(desktop, rtext, "/tools/text", true);
+ if(measure_repr) {
+ sp_repr_set_svg_double(rtext, "x", 2);
+ sp_repr_set_svg_double(rtext, "y", 2);
+ } else {
+ sp_repr_set_svg_double(rtext, "x", 0);
+ sp_repr_set_svg_double(rtext, "y", 0);
+ }
- placements.push_back(placement);
- }
+ /* Create <tspan> */
+ Inkscape::XML::Node *rtspan = xml_doc->createElement("svg:tspan");
+ rtspan->setAttribute("sodipodi:role", "line");
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ std::stringstream font_size;
+ font_size.imbue(std::locale::classic());
+ if(measure_repr) {
+ font_size << fontsize;
+ } else {
+ font_size << fontsize << "pt";
+ }
+ sp_repr_css_set_property (css, "font-size", font_size.str().c_str());
+ sp_repr_css_set_property (css, "font-style", "normal");
+ sp_repr_css_set_property (css, "font-weight", "normal");
+ sp_repr_css_set_property (css, "line-height", "125%");
+ sp_repr_css_set_property (css, "letter-spacing", "0");
+ sp_repr_css_set_property (css, "word-spacing", "0");
+ sp_repr_css_set_property (css, "text-align", "center");
+ sp_repr_css_set_property (css, "text-anchor", "middle");
+ if(measure_repr) {
+ sp_repr_css_set_property (css, "fill", "#FFFFFF");
+ } else {
+ sp_repr_css_set_property (css, "fill", "#000000");
+ }
+ sp_repr_css_set_property (css, "fill-opacity", "1");
+ sp_repr_css_set_property (css, "stroke", "none");
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ rtspan->setAttribute("style", css_str.c_str());
+ sp_repr_css_attr_unref (css);
+ rtext->addChild(rtspan, NULL);
+ Inkscape::GC::release(rtspan);
+ /* Create TEXT */
+ Inkscape::XML::Node *rstring = xml_doc->createTextNode(value);
+ rtspan->addChild(rstring, NULL);
+ Inkscape::GC::release(rstring);
+ SPItem *text_item = SP_ITEM(desktop->currentLayer()->appendChildRepr(rtext));
+ Inkscape::GC::release(rtext);
+ text_item->updateRepr();
+ Geom::OptRect bbox = text_item->geometricBounds();
+ if (!measure_repr && bbox) {
+ Geom::Point center = bbox->midpoint();
+ text_item->transform *= Geom::Translate(center).inverse();
+ pos += Geom::Point::polar(angle+ Geom::deg_to_rad(90), -bbox->height());
+ }
+ if(measure_repr) {
+ /* Create <group> */
+ Inkscape::XML::Node *rgroup = xml_doc->createElement("svg:g");
+ /* Create <rect> */
+ Inkscape::XML::Node *rrect = xml_doc->createElement("svg:rect");
+ SPCSSAttr *css = sp_repr_css_attr_new ();
+ gchar color_line[64];
+ sp_svg_write_color (color_line, sizeof(color_line), background);
+ sp_repr_css_set_property (css, "fill", color_line);
+ sp_repr_css_set_property (css, "fill-opacity", "0.5");
+ sp_repr_css_set_property (css, "stroke-width", "0");
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ rrect->setAttribute("style", css_str.c_str());
+ sp_repr_css_attr_unref (css);
+ sp_repr_set_svg_double(rgroup, "x", 0);
+ sp_repr_set_svg_double(rgroup, "y", 0);
+ sp_repr_set_svg_double(rrect, "x", -bbox->width()/2.0);
+ sp_repr_set_svg_double(rrect, "y", -bbox->height());
+ sp_repr_set_svg_double(rrect, "width", bbox->width() + 6);
+ sp_repr_set_svg_double(rrect, "height", bbox->height() + 6);
+ Inkscape::XML::Node *rtextitem = text_item->getRepr();
+ text_item->deleteObject();
+ rgroup->addChild(rtextitem, NULL);
+ Inkscape::GC::release(rtextitem);
+ rgroup->addChild(rrect, NULL);
+ Inkscape::GC::release(rrect);
+ SPItem *text_item_box = SP_ITEM(desktop->currentLayer()->appendChildRepr(rgroup));
+ Geom::Scale scale = Geom::Scale(desktop->current_zoom()).inverse();
+ if(bbox && text_anchor == TEXT_ANCHOR_CENTER) {
+ text_item_box->transform *= Geom::Translate(bbox->midpoint() - Geom::Point(1.0,1.0)).inverse();
+ }
+ text_item_box->transform *= scale;
+ text_item_box->transform *= Geom::Translate(Geom::Point() - (scale.vector() * 0.5));
+ text_item_box->transform *= Geom::Translate(pos);
+ text_item_box->transform *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ text_item_box->updateRepr();
+ text_item_box->doWriteTransform(text_item_box->getRepr(), text_item_box->transform, NULL, true);
+ Inkscape::XML::Node *rlabel = text_item_box->getRepr();
+ text_item_box->deleteObject();
+ measure_repr->addChild(rlabel, NULL);
+ Inkscape::GC::release(rlabel);
+ } else {
+ text_item->transform *= Geom::Rotate(angle);
+ text_item->transform *= Geom::Translate(pos);
+ text_item->transform *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ text_item->doWriteTransform(text_item->getRepr(), text_item->transform, NULL, true);
+ }
+}
- // Adjust positions
- repositionOverlappingLabels(placements, desktop, windowNormal, fontsize);
-
- for (std::vector<LabelPlacement>::iterator it = placements.begin(); it != placements.end(); ++it)
- {
- LabelPlacement &place = *it;
-
- // TODO cleanup memory, Glib::ustring, etc.:
- gchar *measure_str = g_strdup_printf("%.2f %s", place.lengthVal, unit_name.c_str());
- SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(),
- desktop,
- place.end,
- measure_str);
- sp_canvastext_set_fontsize(canvas_tooltip, fontsize);
- canvas_tooltip->rgba = 0xffffffff;
- canvas_tooltip->rgba_background = 0x0000007f;
- canvas_tooltip->outline = false;
- canvas_tooltip->background = true;
- canvas_tooltip->anchor_position = TEXT_ANCHOR_CENTER;
-
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0));
- g_free(measure_str);
- }
+void MeasureTool::reset()
+{
+ this->knot_start->hide();
+ this->knot_end->hide();
+ for (size_t idx = 0; idx < measure_tmp_items.size(); ++idx) {
+ desktop->remove_temporary_canvasitem(measure_tmp_items[idx]);
+ }
+ measure_tmp_items.clear();
+}
- Geom::Point angleDisplayPt = calcAngleDisplayAnchor(desktop, angle, baseAngle,
- start_point, end_point,
- fontsize);
-
- {
- // TODO cleanup memory, Glib::ustring, etc.:
- gchar *angle_str = g_strdup_printf("%.2f °", angle * 180/M_PI);
-
- SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(),
- desktop,
- angleDisplayPt,
- angle_str);
- sp_canvastext_set_fontsize(canvas_tooltip, fontsize);
- canvas_tooltip->rgba = 0xffffffff;
- canvas_tooltip->rgba_background = 0x337f337f;
- canvas_tooltip->outline = false;
- canvas_tooltip->background = true;
- canvas_tooltip->anchor_position = TEXT_ANCHOR_CENTER;
-
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0));
- g_free(angle_str);
- }
+void MeasureTool::setMeasureCanvasText(bool is_angle, double precision, double amount, double fontsize, Glib::ustring unit_name, Geom::Point position, guint32 background, CanvasTextAnchorPositionEnum text_anchor, bool to_item, Inkscape::XML::Node *measure_repr)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ std::stringstream precision_str;
+ precision_str.imbue(std::locale::classic());
+ if(is_angle){
+ precision_str << "%." << precision << "f °";
+ } else {
+ precision_str << "%." << precision << "f %s";
+ }
+ gchar *measure_str = g_strdup_printf(precision_str.str().c_str(), amount, unit_name.c_str());
+ SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(),
+ desktop,
+ position,
+ measure_str);
+ sp_canvastext_set_fontsize(canvas_tooltip, fontsize);
+ canvas_tooltip->rgba = 0xffffffff;
+ canvas_tooltip->rgba_background = background;
+ canvas_tooltip->outline = false;
+ canvas_tooltip->background = true;
+ canvas_tooltip->anchor_position = text_anchor;
+ measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0));
+ if(to_item) {
+ setLabelText(measure_str, position, fontsize, 0, background, measure_repr);
+ }
+ g_free(measure_str);
+}
- {
- double totallengthval = (end_point - start_point).length();
- totallengthval = Inkscape::Util::Quantity::convert(totallengthval, "px", unit_name);
-
- // TODO cleanup memory, Glib::ustring, etc.:
- gchar *totallength_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str());
- SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(),
- desktop,
- end_point + desktop->w2d(Geom::Point(3*fontsize, -fontsize)),
- totallength_str);
- sp_canvastext_set_fontsize(canvas_tooltip, fontsize);
- canvas_tooltip->rgba = 0xffffffff;
- canvas_tooltip->rgba_background = 0x3333337f;
- canvas_tooltip->outline = false;
- canvas_tooltip->background = true;
- canvas_tooltip->anchor_position = TEXT_ANCHOR_LEFT;
-
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0));
- g_free(totallength_str);
- }
+void MeasureTool::setMeasureCanvasItem(Geom::Point position, bool to_item, Inkscape::XML::Node *measure_repr){
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(),
+ SP_TYPE_CTRL,
+ "anchor", SP_ANCHOR_CENTER,
+ "size", 8.0,
+ "stroked", TRUE,
+ "stroke_color", 0xff0000ff,
+ "mode", SP_KNOT_MODE_XOR,
+ "shape", SP_KNOT_SHAPE_CROSS,
+ NULL );
+
+ SP_CTRL(canvasitem)->moveto(position);
+ measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvasitem, 0));
+ if(to_item) {
+ setPoint(position, measure_repr);
+ }
+}
- if (intersections.size() > 2) {
- double totallengthval = (intersections[intersections.size()-1] - intersections[0]).length();
- totallengthval = Inkscape::Util::Quantity::convert(totallengthval, "px", unit_name);
-
- // TODO cleanup memory, Glib::ustring, etc.:
- gchar *total_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str());
- SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(),
- desktop,
- desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * 60,
- total_str);
- sp_canvastext_set_fontsize(canvas_tooltip, fontsize);
- canvas_tooltip->rgba = 0xffffffff;
- canvas_tooltip->rgba_background = 0x33337f7f;
- canvas_tooltip->outline = false;
- canvas_tooltip->background = true;
- canvas_tooltip->anchor_position = TEXT_ANCHOR_CENTER;
-
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0));
- g_free(total_str);
- }
+void MeasureTool::setMeasureCanvasControlLine(Geom::Point start, Geom::Point end, bool to_item, Inkscape::CtrlLineType ctrl_line_type, Inkscape::XML::Node *measure_repr){
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPCtrlLine *control_line = ControlManager::getManager().createControlLine(desktop->getTempGroup(),
+ start,
+ end,
+ ctrl_line_type);
+ measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
+ gint32 color = ctrl_line_type == CTLINE_PRIMARY ? 0x0000ff7f : 0xff00007f;
+ if(to_item) {
+ setLine(start,
+ end,
+ false,
+ color,
+ measure_repr);
+ }
+}
- // Now that text has been added, we can add lines and controls so that they go underneath
-
- for (size_t idx = 0; idx < intersections.size(); ++idx) {
- // Display the intersection indicator (i.e. the cross)
- SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(),
- SP_TYPE_CTRL,
- "anchor", SP_ANCHOR_CENTER,
- "size", 8.0,
- "stroked", TRUE,
- "stroke_color", 0xff0000ff,
- "mode", SP_KNOT_MODE_XOR,
- "shape", SP_KNOT_SHAPE_CROSS,
- NULL );
-
- SP_CTRL(canvasitem)->moveto(desktop->doc2dt(intersections[idx]));
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvasitem, 0));
- }
+void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::Node *measure_repr)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if(!desktop || !start_p.isFinite() || !end_p.isFinite() || start_p == end_p) {
+ return;
+ }
+ writeMeasurePoint(start_p, true);
+ writeMeasurePoint(end_p, false);
+ //clear previous temporary canvas items, we'll draw new ones
+ for (size_t idx = 0; idx < measure_tmp_items.size(); ++idx) {
+ desktop->remove_temporary_canvasitem(measure_tmp_items[idx]);
+ }
+ measure_tmp_items.clear();
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool show_in_between = prefs->getBool("/tools/measure/show_in_between", true);
+ bool all_layers = prefs->getBool("/tools/measure/all_layers", true);
+ dimension_offset = 70;
+ Geom::PathVector lineseg;
+ Geom::Path p;
+ p.start(desktop->dt2doc(start_p));
+ p.appendNew<Geom::LineSegment>(desktop->dt2doc(end_p));
+ lineseg.push_back(p);
+
+ double angle = atan2(end_p - start_p);
+ double baseAngle = 0;
+
+ if (explicitBase) {
+ baseAngle = atan2(explicitBase.get() - start_p);
+ angle -= baseAngle;
+ }
- // Since adding goes to the bottom, do all lines last.
-
- // draw main control line
- {
- SPCtrlLine *control_line = ControlManager::getManager().createControlLine(desktop->getTempGroup(),
- start_point,
- end_point);
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
-
- if ((end_point[Geom::X] != start_point[Geom::X]) && (end_point[Geom::Y] != start_point[Geom::Y])) {
- double length = std::abs((end_point - start_point).length());
- Geom::Point anchorEnd = start_point;
- anchorEnd[Geom::X] += length;
- if (explicitBase) {
- anchorEnd *= (Geom::Affine(Geom::Translate(-start_point))
- * Geom::Affine(Geom::Rotate(baseAngle))
- * Geom::Affine(Geom::Translate(start_point)));
- }
-
- SPCtrlLine *control_line = ControlManager::getManager().createControlLine(desktop->getTempGroup(),
- start_point,
- anchorEnd,
- CTLINE_SECONDARY);
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
-
- createAngleDisplayCurve(desktop, start_point, end_point, angleDisplayPt, angle);
+ std::vector<SPItem*> items;
+ Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop);
+ r->setMode(RUBBERBAND_MODE_TOUCHPATH);
+ if(!show_in_between) {
+ r->start(desktop,start_p);
+ r->move(end_p);
+ items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints(), all_layers, 2);
+ r->stop();
+ r->setMode(RUBBERBAND_MODE_TOUCHPATH);
+ r->start(desktop,end_p);
+ r->move(start_p);
+ std::vector<SPItem*> items_reverse = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints(), all_layers, 2);
+ r->stop();
+ if(items_reverse.size() == 2 && items_reverse[1] != items[0] && items_reverse[1] != items[1]) {
+ items.push_back(items_reverse[1]);
+ }
+ if(items_reverse.size() >= 1 && items_reverse[0] != items[1]) {
+ items.push_back(items_reverse[0]);
+ }
+ } else {
+ r->start(desktop,start_p);
+ r->move(end_p);
+ items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints(), all_layers);
+ r->stop();
+ }
+ std::vector<double> intersection_times;
+ for (std::vector<SPItem*>::const_iterator i=items.begin(); i!=items.end(); i++) {
+ SPItem *item = *i;
+ if (SP_IS_SHAPE(item)) {
+ calculate_intersections(desktop, item, lineseg, SP_SHAPE(item)->getCurve(), intersection_times);
+ } else {
+ if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) {
+ Inkscape::Text::Layout::iterator iter = te_get_layout(item)->begin();
+ do {
+ Inkscape::Text::Layout::iterator iter_next = iter;
+ iter_next.nextGlyph(); // iter_next is one glyph ahead from iter
+ if (iter == iter_next) {
+ break;
}
- }
-
- if (intersections.size() > 2) {
- ControlManager &mgr = ControlManager::getManager();
- SPCtrlLine *control_line = 0;
- control_line = mgr.createControlLine(desktop->getTempGroup(),
- desktop->doc2dt(intersections[0]) + normal * 60,
- desktop->doc2dt(intersections[intersections.size() - 1]) + normal * 60);
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
-
- control_line = mgr.createControlLine(desktop->getTempGroup(),
- desktop->doc2dt(intersections[0]),
- desktop->doc2dt(intersections[0]) + normal * 65);
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
-
- control_line = mgr.createControlLine(desktop->getTempGroup(),
- desktop->doc2dt(intersections[intersections.size() - 1]),
- desktop->doc2dt(intersections[intersections.size() - 1]) + normal * 65);
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
- }
- // call-out lines
- for (std::vector<LabelPlacement>::iterator it = placements.begin(); it != placements.end(); ++it)
- {
- LabelPlacement &place = *it;
-
- ControlManager &mgr = ControlManager::getManager();
- SPCtrlLine *control_line = mgr.createControlLine(desktop->getTempGroup(),
- place.start,
- place.end,
- CTLINE_SECONDARY);
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
- }
+ // get path from iter to iter_next:
+ SPCurve *curve = te_get_layout(item)->convertToCurves(iter, iter_next);
+ iter = iter_next; // shift to next glyph
+ if (!curve) {
+ continue; // error converting this glyph
+ }
+ if (curve->is_empty()) { // whitespace glyph?
+ curve->unref();
+ continue;
+ }
- {
- for (size_t idx = 1; idx < intersections.size(); ++idx) {
- Geom::Point measure_text_pos = (intersections[idx - 1] + intersections[idx]) / 2;
+ curve->transform(item->i2doc_affine());
- ControlManager &mgr = ControlManager::getManager();
- SPCtrlLine *control_line = mgr.createControlLine(desktop->getTempGroup(),
- desktop->doc2dt(measure_text_pos),
- desktop->doc2dt(measure_text_pos) - (normal * DIMENSION_OFFSET),
- CTLINE_SECONDARY);
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
+ calculate_intersections(desktop, item, lineseg, curve, intersection_times);
+ if (iter == te_get_layout(item)->end()) {
+ break;
}
- }
+ } while (true);
+ }
+ }
+ }
+ Glib::ustring unit_name = prefs->getString("/tools/measure/unit");
+ if (!unit_name.compare("")) {
+ unit_name = "px";
+ }
+ double scale = prefs->getDouble("/tools/measure/scale", 100.0) / 100.0;
+ double fontsize = prefs->getDouble("/tools/measure/fontsize", 10.0);
+ // Normal will be used for lines and text
+ Geom::Point windowNormal = Geom::unit_vector(Geom::rot90(desktop->d2w(end_p - start_p)));
+ Geom::Point normal = desktop->w2d(windowNormal);
+
+ std::vector<Geom::Point> intersections;
+ std::sort(intersection_times.begin(), intersection_times.end());
+ for (std::vector<double>::iterator iter_t = intersection_times.begin(); iter_t != intersection_times.end(); iter_t++) {
+ if(show_in_between) {
+ intersections.push_back(lineseg[0].pointAt(*iter_t));
+ }
+ }
+ if(!show_in_between && intersection_times.size() > 1) {
+ intersections.push_back(lineseg[0].pointAt(intersection_times[0]));
+ intersections.push_back(lineseg[0].pointAt(intersection_times[intersection_times.size()-1]));
+ }
+ if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true)) {
+ intersections.insert(intersections.begin(),lineseg[0].pointAt(0));
+ intersections.push_back(lineseg[0].pointAt(1));
+ }
+ std::vector<LabelPlacement> placements;
+ for (size_t idx = 1; idx < intersections.size(); ++idx) {
+ LabelPlacement placement;
+ placement.lengthVal = (intersections[idx] - intersections[idx - 1]).length();
+ placement.lengthVal = Inkscape::Util::Quantity::convert(placement.lengthVal, "px", unit_name);
+ placement.offset = dimension_offset / 2;
+ placement.start = desktop->doc2dt( (intersections[idx - 1] + intersections[idx]) / 2 );
+ placement.end = placement.start - (normal * placement.offset);
+
+ placements.push_back(placement);
+ }
+ int precision = prefs->getInt("/tools/measure/precision", 2);
+ // Adjust positions
+ repositionOverlappingLabels(placements, desktop, windowNormal, fontsize, precision);
+ for (std::vector<LabelPlacement>::iterator it = placements.begin(); it != placements.end(); ++it) {
+ LabelPlacement &place = *it;
+ setMeasureCanvasText(false, precision, place.lengthVal * scale, fontsize, unit_name, place.end, 0x0000007f, TEXT_ANCHOR_CENTER, to_item, measure_repr);
+ }
+ Geom::Point angleDisplayPt = calcAngleDisplayAnchor(desktop, angle, baseAngle,
+ start_p, end_p,
+ fontsize);
+ {
+ setMeasureCanvasText(true, precision, Geom::rad_to_deg(angle), fontsize, unit_name, angleDisplayPt, 0x337f337f, TEXT_ANCHOR_CENTER, to_item, measure_repr);
+ }
- // Initial point
- {
- SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(),
- SP_TYPE_CTRL,
- "anchor", SP_ANCHOR_CENTER,
- "size", 8.0,
- "stroked", TRUE,
- "stroke_color", 0xff0000ff,
- "mode", SP_KNOT_MODE_XOR,
- "shape", SP_KNOT_SHAPE_CROSS,
- NULL );
-
- SP_CTRL(canvasitem)->moveto(start_point);
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvasitem, 0));
- }
+ {
+ double totallengthval = (end_p - start_p).length();
+ totallengthval = Inkscape::Util::Quantity::convert(totallengthval, "px", unit_name);
+ Geom::Point origin = end_p + desktop->w2d(Geom::Point(3*fontsize, -fontsize));
+ setMeasureCanvasText(false, precision, totallengthval * scale, fontsize, unit_name, origin, 0x3333337f, TEXT_ANCHOR_LEFT, to_item, measure_repr);
+ }
- lastEnd = end_point; // track in case we get a anchoring key-press later
+ if (intersections.size() > 2) {
+ double totallengthval = (intersections[intersections.size()-1] - intersections[0]).length();
+ totallengthval = Inkscape::Util::Quantity::convert(totallengthval, "px", unit_name);
+ Geom::Point origin = desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * dimension_offset;
+ setMeasureCanvasText(false, precision, totallengthval * scale, fontsize, unit_name, origin, 0x33337f7f, TEXT_ANCHOR_CENTER, to_item, measure_repr);
+ }
+
+ // Initial point
+ {
+ setMeasureCanvasItem(start_p, false, measure_repr);
+ }
- gobble_motion_events(GDK_BUTTON1_MASK);
+ // Now that text has been added, we can add lines and controls so that they go underneath
+ for (size_t idx = 0; idx < intersections.size(); ++idx) {
+ setMeasureCanvasItem(desktop->doc2dt(intersections[idx]), to_item, measure_repr);
+ if(to_guides) {
+ gchar *cross_number;
+ if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true)) {
+ cross_number= g_strdup_printf(_("Crossing %d"), idx);
+ } else {
+ cross_number= g_strdup_printf(_("Crossing %d"), idx + 1);
}
- break;
- }
- case GDK_BUTTON_RELEASE: {
- sp_event_context_discard_delayed_snap_event(this);
- explicitBase = boost::none;
- lastEnd = boost::none;
-
- //clear all temporary canvas items related to the measurement tool.
- for (size_t idx = 0; idx < measure_tmp_items.size(); ++idx) {
- desktop->remove_temporary_canvasitem(measure_tmp_items[idx]);
+ if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true) && idx == 0) {
+ setGuide(desktop->doc2dt(intersections[idx]), angle + Geom::deg_to_rad(90), "");
+ } else {
+ setGuide(desktop->doc2dt(intersections[idx]), angle + Geom::deg_to_rad(90), cross_number);
}
+ g_free(cross_number);
+ }
+ }
+ // Since adding goes to the bottom, do all lines last.
- measure_tmp_items.clear();
+ // draw main control line
+ {
+ setMeasureCanvasControlLine(start_p, end_p, false, CTLINE_PRIMARY, measure_repr);
+ double length = std::abs((end_p - start_p).length());
+ Geom::Point anchorEnd = start_p;
+ anchorEnd[Geom::X] += length;
+ if (explicitBase) {
+ anchorEnd *= (Geom::Affine(Geom::Translate(-start_p))
+ * Geom::Affine(Geom::Rotate(baseAngle))
+ * Geom::Affine(Geom::Translate(start_p)));
+ }
+ setMeasureCanvasControlLine(start_p, anchorEnd, to_item, CTLINE_SECONDARY, measure_repr);
+ createAngleDisplayCurve(desktop, start_p, end_p, angleDisplayPt, angle, measure_repr);
+ }
- if (this->grabbed) {
- sp_canvas_item_ungrab(this->grabbed, event->button.time);
- this->grabbed = NULL;
- }
+ if (intersections.size() > 2) {
+ setMeasureCanvasControlLine(desktop->doc2dt(intersections[0]) + normal * dimension_offset, desktop->doc2dt(intersections[intersections.size() - 1]) + normal * dimension_offset, to_item, CTLINE_PRIMARY , measure_repr);
+
+ setMeasureCanvasControlLine(desktop->doc2dt(intersections[0]), desktop->doc2dt(intersections[0]) + normal * dimension_offset, to_item, CTLINE_PRIMARY , measure_repr);
- xp = 0;
- yp = 0;
- break;
- }
- default:
- break;
+ setMeasureCanvasControlLine(desktop->doc2dt(intersections[intersections.size() - 1]), desktop->doc2dt(intersections[intersections.size() - 1]) + normal * dimension_offset, to_item, CTLINE_PRIMARY , measure_repr);
}
- if (!ret) {
- ret = ToolBase::root_handler(event);
+ // call-out lines
+ for (std::vector<LabelPlacement>::iterator it = placements.begin(); it != placements.end(); ++it) {
+ LabelPlacement &place = *it;
+ setMeasureCanvasControlLine(place.start, place.end, to_item, CTLINE_SECONDARY, measure_repr);
}
- return ret;
+ {
+ for (size_t idx = 1; idx < intersections.size(); ++idx) {
+ Geom::Point measure_text_pos = (intersections[idx - 1] + intersections[idx]) / 2;
+ setMeasureCanvasControlLine(desktop->doc2dt(measure_text_pos), desktop->doc2dt(measure_text_pos) - (normal * dimension_offset / 2), to_item, CTLINE_SECONDARY, measure_repr);
+ }
+ }
}
}
diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h
index 9701ba6ea..3bdc9b9c4 100644
--- a/src/ui/tools/measure-tool.h
+++ b/src/ui/tools/measure-tool.h
@@ -6,41 +6,72 @@
*
* Authors:
* Felipe Correa da Silva Sanches <juca@members.fsf.org>
- *
+ * Jabiertxo Arraiza <jabier.arraiza@marker.es>
* Copyright (C) 2011 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-
+#include <stddef.h>
+#include <sigc++/sigc++.h>
#include "ui/tools/tool-base.h"
#include <2geom/point.h>
+#include "display/canvas-text.h"
+#include "ui/control-manager.h"
#include <boost/optional.hpp>
#define SP_MEASURE_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::MeasureTool*>((Inkscape::UI::Tools::ToolBase*)obj))
#define SP_IS_MEASURE_CONTEXT(obj) (dynamic_cast<const Inkscape::UI::Tools::MeasureTool*>((const Inkscape::UI::Tools::ToolBase*)obj) != NULL)
+class SPKnot;
+
namespace Inkscape {
namespace UI {
namespace Tools {
class MeasureTool : public ToolBase {
public:
- MeasureTool();
- virtual ~MeasureTool();
-
- static const std::string prefsPath;
+ MeasureTool();
+ virtual ~MeasureTool();
- virtual void finish();
- virtual bool root_handler(GdkEvent* event);
+ static const std::string prefsPath;
- virtual const std::string& getPrefsPath();
+ virtual void finish();
+ virtual bool root_handler(GdkEvent* event);
+ virtual void showCanvasItems(bool to_guides = false, bool to_item = false, Inkscape::XML::Node *measure_repr = NULL);
+ virtual void reverseKnots();
+ virtual void toGuides();
+ virtual void toMarkDimension();
+ virtual void toItem();
+ virtual void reset();
+ virtual void setMarkers();
+ virtual void setMarker(bool isStart);
+ virtual const std::string& getPrefsPath();
+ Geom::Point readMeasurePoint(bool is_start);
+ void writeMeasurePoint(Geom::Point point, bool is_start);
+ void setGuide(Geom::Point origin, double angle, const char *label);
+ void setPoint(Geom::Point origin, Inkscape::XML::Node *measure_repr);
+ void setLine(Geom::Point start_point,Geom::Point end_point, bool markers, guint32 color, Inkscape::XML::Node *measure_repr = NULL);
+ void setMeasureCanvasText(bool is_angle, double precision, double amount, double fontsize, Glib::ustring unit_name, Geom::Point position, guint32 background, CanvasTextAnchorPositionEnum text_anchor, bool to_item, Inkscape::XML::Node *measure_repr);
+ void setMeasureCanvasItem(Geom::Point position, bool to_item, Inkscape::XML::Node *measure_repr);
+ void setMeasureCanvasControlLine(Geom::Point start, Geom::Point end, bool to_item, Inkscape::CtrlLineType ctrl_line_type, Inkscape::XML::Node *measure_repr);
+ void setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle, guint32 background , Inkscape::XML::Node *measure_repr = NULL, CanvasTextAnchorPositionEnum text_anchor = TEXT_ANCHOR_CENTER );
+ void knotStartMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state);
+ void knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state);
+ void knotUngrabbedHandler(SPKnot */*knot*/, unsigned int /*state*/);
private:
- SPCanvasItem* grabbed;
-
- Geom::Point start_point;
+ SPCanvasItem* grabbed;
boost::optional<Geom::Point> explicitBase;
- boost::optional<Geom::Point> lastEnd;
+ boost::optional<Geom::Point> last_end;
+ SPKnot *knot_start;
+ SPKnot *knot_end;
+ gint dimension_offset;
+ Geom::Point start_p;
+ Geom::Point end_p;
+ sigc::connection _knot_start_moved_connection;
+ sigc::connection _knot_start_ungrabbed_connection;
+ sigc::connection _knot_end_moved_connection;
+ sigc::connection _knot_end_ungrabbed_connection;
};
}
@@ -48,3 +79,14 @@ private:
}
#endif // SEEN_SP_MEASURING_CONTEXT_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp
index e2be5ca4b..7de2a0b04 100644
--- a/src/ui/tools/spray-tool.cpp
+++ b/src/ui/tools/spray-tool.cpp
@@ -12,6 +12,7 @@
* Steren GIANNINI (steren.giannini@gmail.com)
* Jon A. Cruz <jon@joncruz.org>
* Abhishek Sharma
+ * Jabiertxo Arraiza <jabier.arraiza@marker.es>
*
* Copyright (C) 2009 authors
*
@@ -48,7 +49,15 @@
#include "sp-path.h"
#include "path-chemistry.h"
+// For color picking
+#include "display/drawing.h"
+#include "display/drawing-context.h"
+#include "display/cairo-utils.h"
+#include "desktop-style.h"
+#include "svg/svg-color.h"
+
#include "sp-text.h"
+#include "sp-root.h"
#include "sp-flowtext.h"
#include "display/sp-canvas.h"
#include "display/canvas-bpath.h"
@@ -88,6 +97,17 @@ namespace Inkscape {
namespace UI {
namespace Tools {
+enum {
+ PICK_COLOR,
+ PICK_OPACITY,
+ PICK_R,
+ PICK_G,
+ PICK_B,
+ PICK_H,
+ PICK_S,
+ PICK_L
+};
+
const std::string& SprayTool::getPrefsPath() {
return SprayTool::prefsPath;
}
@@ -133,7 +153,9 @@ SprayTool::SprayTool()
: ToolBase(cursor_spray_xpm, 4, 4, false)
, pressure(TC_DEFAULT_PRESSURE)
, dragging(false)
- , usepressure(false)
+ , usepressurewidth(false)
+ , usepressurepopulation(false)
+ , usepressurescale(false)
, usetilt(false)
, usetext(false)
, width(0.2)
@@ -151,6 +173,25 @@ SprayTool::SprayTool()
, is_dilating(false)
, has_dilated(false)
, dilate_area(NULL)
+ , no_overlap(false)
+ , picker(false)
+ , pick_center(true)
+ , pick_inverse_value(false)
+ , pick_fill(false)
+ , pick_stroke(false)
+ , pick_no_overlap(false)
+ , over_transparent(true)
+ , over_no_transparent(true)
+ , offset(0)
+ , pick(0)
+ , do_trace(false)
+ , pick_to_size(false)
+ , pick_to_presence(false)
+ , pick_to_color(false)
+ , pick_to_opacity(false)
+ , invert_picked(false)
+ , gamma_picked(0)
+ , rand_picked(0)
{
}
@@ -211,6 +252,15 @@ void SprayTool::setup() {
this->is_drawing = false;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setBool("/dialogs/clonetiler/dotrace", false);
+ if (prefs->getBool("/tools/spray/selcue")) {
+ this->enableSelectionCue();
+ }
+ if (prefs->getBool("/tools/spray/gradientdrag")) {
+ this->enableGrDrag();
+ }
+
sp_event_context_read(this, "distrib");
sp_event_context_read(this, "width");
sp_event_context_read(this, "ratio");
@@ -221,16 +271,33 @@ void SprayTool::setup() {
sp_event_context_read(this, "population");
sp_event_context_read(this, "mean");
sp_event_context_read(this, "standard_deviation");
- sp_event_context_read(this, "usepressure");
+ sp_event_context_read(this, "usepressurewidth");
+ sp_event_context_read(this, "usepressurepopulation");
+ sp_event_context_read(this, "usepressurescale");
sp_event_context_read(this, "Scale");
+ sp_event_context_read(this, "offset");
+ sp_event_context_read(this, "picker");
+ sp_event_context_read(this, "pick_center");
+ sp_event_context_read(this, "pick_inverse_value");
+ sp_event_context_read(this, "pick_fill");
+ sp_event_context_read(this, "pick_stroke");
+ sp_event_context_read(this, "pick_no_overlap");
+ sp_event_context_read(this, "over_no_transparent");
+ sp_event_context_read(this, "over_transparent");
+ sp_event_context_read(this, "no_overlap");
+}
+void SprayTool::setCloneTilerPrefs() {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- if (prefs->getBool("/tools/spray/selcue")) {
- this->enableSelectionCue();
- }
- if (prefs->getBool("/tools/spray/gradientdrag")) {
- this->enableGrDrag();
- }
+ this->do_trace = prefs->getBool("/dialogs/clonetiler/dotrace", false);
+ this->pick = prefs->getInt("/dialogs/clonetiler/pick");
+ this->pick_to_size = prefs->getBool("/dialogs/clonetiler/pick_to_size", false);
+ this->pick_to_presence = prefs->getBool("/dialogs/clonetiler/pick_to_presence", false);
+ this->pick_to_color = prefs->getBool("/dialogs/clonetiler/pick_to_color", false);
+ this->pick_to_opacity = prefs->getBool("/dialogs/clonetiler/pick_to_opacity", false);
+ this->rand_picked = 0.01 * prefs->getDoubleLimited("/dialogs/clonetiler/rand_picked", 0, 0, 100);
+ this->invert_picked = prefs->getBool("/dialogs/clonetiler/invert_picked", false);
+ this->gamma_picked = prefs->getDoubleLimited("/dialogs/clonetiler/gamma_picked", 0, -10, 10);
}
void SprayTool::set(const Inkscape::Preferences::Entry& val) {
@@ -241,8 +308,12 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) {
this->update_cursor(false);
} else if (path == "width") {
this->width = 0.01 * CLAMP(val.getInt(10), 1, 100);
- } else if (path == "usepressure") {
- this->usepressure = val.getBool();
+ } else if (path == "usepressurewidth") {
+ this->usepressurewidth = val.getBool();
+ } else if (path == "usepressurepopulation") {
+ this->usepressurepopulation = val.getBool();
+ } else if (path == "usepressurescale") {
+ this->usepressurescale = val.getBool();
} else if (path == "population") {
this->population = 0.01 * CLAMP(val.getInt(10), 1, 100);
} else if (path == "rotation_variation") {
@@ -260,6 +331,26 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) {
this->tilt = CLAMP(val.getDouble(0.1), 0, 1000.0);
} else if (path == "ratio") {
this->ratio = CLAMP(val.getDouble(), 0.0, 0.9);
+ } else if (path == "offset") {
+ this->offset = val.getDoubleLimited(100.0, 0, 1000.0);
+ } else if (path == "pick_center") {
+ this->pick_center = val.getBool(true);
+ } else if (path == "pick_inverse_value") {
+ this->pick_inverse_value = val.getBool(false);
+ } else if (path == "pick_fill") {
+ this->pick_fill = val.getBool(false);
+ } else if (path == "pick_stroke") {
+ this->pick_stroke = val.getBool(false);
+ } else if (path == "pick_no_overlap") {
+ this->pick_no_overlap = val.getBool(false);
+ } else if (path == "over_no_transparent") {
+ this->over_no_transparent = val.getBool(true);
+ } else if (path == "over_transparent") {
+ this->over_transparent = val.getBool(true);
+ } else if (path == "no_overlap") {
+ this->no_overlap = val.getBool(false);
+ } else if (path == "picker") {
+ this->picker = val.getBool(false);
}
}
@@ -272,9 +363,15 @@ static void sp_spray_extinput(SprayTool *tc, GdkEvent *event)
}
}
+static double get_width(SprayTool *tc)
+{
+ double pressure = (tc->usepressurewidth? tc->pressure / TC_DEFAULT_PRESSURE : 1);
+ return pressure * tc->width;
+}
+
static double get_dilate_radius(SprayTool *tc)
{
- return 250 * tc->width/SP_EVENT_CONTEXT(tc)->desktop->current_zoom();
+ return 250 * get_width(tc)/SP_EVENT_CONTEXT(tc)->desktop->current_zoom();
}
static double get_path_mean(SprayTool *tc)
@@ -289,11 +386,16 @@ static double get_path_standard_deviation(SprayTool *tc)
static double get_population(SprayTool *tc)
{
- double pressure = (tc->usepressure? tc->pressure / TC_DEFAULT_PRESSURE : 1);
- //g_warning("Pressure, population: %f, %f", pressure, pressure * tc->population);
+ double pressure = (tc->usepressurepopulation? tc->pressure / TC_DEFAULT_PRESSURE : 1);
return pressure * tc->population;
}
+static double get_pressure(SprayTool *tc)
+{
+ double pressure = tc->pressure / TC_DEFAULT_PRESSURE;
+ return pressure;
+}
+
static double get_move_mean(SprayTool *tc)
{
return tc->mean;
@@ -332,6 +434,435 @@ static void random_position(double &radius, double &angle, double &a, double &s,
}
+static void sp_spray_transform_path(SPItem * item, Geom::Path &path, Geom::Affine affine, Geom::Point center){
+ path *= i2anc_affine(static_cast<SPItem *>(item->parent), NULL).inverse();
+ path *= item->transform.inverse();
+ Geom::Affine dt2p;
+ if (item->parent) {
+ dt2p = static_cast<SPItem *>(item->parent)->i2dt_affine().inverse();
+ } else {
+ SPDesktop *dt = SP_ACTIVE_DESKTOP;
+ dt2p = dt->dt2doc();
+ }
+ Geom::Affine i2dt = item->i2dt_affine() * Geom::Translate(center).inverse() * affine * Geom::Translate(center);
+ path *= i2dt * dt2p;
+ path *= i2anc_affine(static_cast<SPItem *>(item->parent), NULL);
+}
+
+/**
+Randomizes \a val by \a rand, with 0 < val < 1 and all values (including 0, 1) having the same
+probability of being displaced.
+ */
+double randomize01(double val, double rand)
+{
+ double base = MIN (val - rand, 1 - 2*rand);
+ if (base < 0) {
+ base = 0;
+ }
+ val = base + g_random_double_range (0, MIN (2 * rand, 1 - base));
+ return CLAMP(val, 0, 1); // this should be unnecessary with the above provisions, but just in case...
+}
+
+guint32 getPickerData(Geom::IntRect area){
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ double R = 0, G = 0, B = 0, A = 0;
+ cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, area.width(), area.height());
+ sp_canvas_arena_render_surface(SP_CANVAS_ARENA(desktop->getDrawing()), s, area);
+ ink_cairo_surface_average_color(s, R, G, B, A);
+ cairo_surface_destroy(s);
+ //this can fix the bug #1511998 if confirmed
+ if( A == 0 || A < 1e-6){
+ R = 1;
+ G = 1;
+ B = 1;
+ }
+ return SP_RGBA32_F_COMPOSE(R, G, B, A);
+}
+
+static void showHidden(std::vector<SPItem *> items_down){
+ for (std::vector<SPItem *>::const_iterator k=items_down.begin(); k!=items_down.end(); ++k) {
+ SPItem *item_hidden = *k;
+ item_hidden->setHidden(false);
+ item_hidden->updateRepr();
+ }
+}
+//todo: maybe move same parameter to preferences
+static bool fit_item(SPDesktop *desktop,
+ SPItem *item,
+ Geom::OptRect bbox,
+ Geom::Point &move,
+ Geom::Point center,
+ gint mode,
+ double angle,
+ double &_scale,
+ double scale,
+ bool picker,
+ bool pick_center,
+ bool pick_inverse_value,
+ bool pick_fill,
+ bool pick_stroke,
+ bool pick_no_overlap,
+ bool over_no_transparent,
+ bool over_transparent,
+ bool no_overlap,
+ double offset,
+ SPCSSAttr *css,
+ bool trace_scale,
+ int pick,
+ bool do_trace,
+ bool pick_to_size,
+ bool pick_to_presence,
+ bool pick_to_color,
+ bool pick_to_opacity,
+ bool invert_picked,
+ double gamma_picked ,
+ double rand_picked)
+{
+ SPDocument *doc = item->document;
+ double width = bbox->width();
+ double height = bbox->height();
+ double offset_width = (offset * width)/100.0 - (width);
+ if(offset_width < 0 ){
+ offset_width = 0;
+ }
+ double offset_height = (offset * height)/100.0 - (height);
+ if(offset_height < 0 ){
+ offset_height = 0;
+ }
+ if(picker && pick_to_size && !trace_scale && do_trace){
+ _scale = 0.1;
+ }
+ Geom::OptRect bbox_procesed = Geom::Rect(Geom::Point(bbox->left() - offset_width, bbox->top() - offset_height),Geom::Point(bbox->right() + offset_width, bbox->bottom() + offset_height));
+ Geom::Path path;
+ path.start(Geom::Point(bbox_procesed->left(), bbox_procesed->top()));
+ path.appendNew<Geom::LineSegment>(Geom::Point(bbox_procesed->right(), bbox_procesed->top()));
+ path.appendNew<Geom::LineSegment>(Geom::Point(bbox_procesed->right(), bbox_procesed->bottom()));
+ path.appendNew<Geom::LineSegment>(Geom::Point(bbox_procesed->left(), bbox_procesed->bottom()));
+ path.close(true);
+ sp_spray_transform_path(item, path, Geom::Scale(_scale), center);
+ sp_spray_transform_path(item, path, Geom::Scale(scale), center);
+ sp_spray_transform_path(item, path, Geom::Rotate(angle), center);
+ path *= Geom::Translate(move);
+ path *= desktop->doc2dt();
+ bbox_procesed = path.boundsFast();
+ double bbox_left_main = bbox_procesed->left();
+ double bbox_right_main = bbox_procesed->right();
+ double bbox_top_main = bbox_procesed->top();
+ double bbox_bottom_main = bbox_procesed->bottom();
+ double width_transformed = bbox_procesed->width();
+ double height_transformed = bbox_procesed->height();
+ Geom::Point mid_point = desktop->d2w(bbox_procesed->midpoint());
+ Geom::IntRect area = Geom::IntRect::from_xywh(floor(mid_point[Geom::X]), floor(mid_point[Geom::Y]), 1, 1);
+ guint32 rgba = getPickerData(area);
+ guint32 rgba2 = 0xffffff00;
+ Geom::Rect rect_sprayed(desktop->d2w(Geom::Point(bbox_left_main,bbox_top_main)), desktop->d2w(Geom::Point(bbox_right_main,bbox_bottom_main)));
+ if (!rect_sprayed.hasZeroArea()) {
+ rgba2 = getPickerData(rect_sprayed.roundOutwards());
+ }
+ if(pick_no_overlap) {
+ if(rgba != rgba2) {
+ if(mode != SPRAY_MODE_ERASER) {
+ return false;
+ }
+ }
+ }
+ if(!pick_center) {
+ rgba = rgba2;
+ }
+ if(!over_transparent && (SP_RGBA32_A_F(rgba) == 0 || SP_RGBA32_A_F(rgba) < 1e-6)) {
+ if(mode != SPRAY_MODE_ERASER) {
+ return false;
+ }
+ }
+ if(!over_no_transparent && SP_RGBA32_A_F(rgba) > 0) {
+ if(mode != SPRAY_MODE_ERASER) {
+ return false;
+ }
+ }
+ if(offset < 100 ) {
+ offset_width = ((99.0 - offset) * width_transformed)/100.0 - width_transformed;
+ offset_height = ((99.0 - offset) * height_transformed)/100.0 - height_transformed;
+ } else {
+ offset_width = 0;
+ offset_height = 0;
+ }
+ std::vector<SPItem*> items_down = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox_procesed);
+ Inkscape::Selection *selection = desktop->getSelection();
+ if (selection->isEmpty()) {
+ return false;
+ }
+ std::vector<SPItem*> const items_selected(selection->itemList());
+ std::vector<SPItem*> items_down_erased;
+ for (std::vector<SPItem*>::const_iterator i=items_down.begin(); i!=items_down.end(); i++) {
+ SPItem *item_down = *i;
+ Geom::OptRect bbox_down = item_down->documentVisualBounds();
+ width = bbox_down->width();
+ height = bbox_down->height();
+ double bbox_left = bbox_down->left();
+ double bbox_top = bbox_down->top();
+ gchar const * item_down_sharp = g_strdup_printf("#%s", item_down->getId());
+ items_down_erased.push_back(item_down);
+ for (std::vector<SPItem*>::const_iterator j=items_selected.begin(); j!=items_selected.end(); j++) {
+ SPItem *item_selected = *j;
+ gchar const * spray_origin;
+ if(!item_selected->getAttribute("inkscape:spray-origin")){
+ spray_origin = g_strdup_printf("#%s", item_selected->getId());
+ } else {
+ spray_origin = item_selected->getAttribute("inkscape:spray-origin");
+ }
+ if(strcmp(item_down_sharp, spray_origin) == 0 ||
+ (item_down->getAttribute("inkscape:spray-origin") &&
+ strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 ))
+ {
+ if(mode == SPRAY_MODE_ERASER) {
+ if(strcmp(item_down_sharp, spray_origin) != 0 && !selection->includes(item_down) ){
+ item_down->deleteObject();
+ items_down_erased.pop_back();
+ break;
+ }
+ } else if(no_overlap) {
+ if(!(offset_width < 0 && offset_height < 0 && std::abs(bbox_left - bbox_left_main) > std::abs(offset_width) &&
+ std::abs(bbox_top - bbox_top_main) > std::abs(offset_height))){
+ if(!no_overlap && (picker || over_transparent || over_no_transparent)){
+ showHidden(items_down);
+ }
+ return false;
+ }
+ } else if(picker || over_transparent || over_no_transparent) {
+ item_down->setHidden(true);
+ item_down->updateRepr();
+ }
+ }
+ }
+ }
+ if(mode == SPRAY_MODE_ERASER){
+ if(!no_overlap && (picker || over_transparent || over_no_transparent)){
+ showHidden(items_down_erased);
+ }
+ return false;
+ }
+ if(picker || over_transparent || over_no_transparent){
+ if(!no_overlap){
+ doc->ensureUpToDate();
+ rgba = getPickerData(area);
+ if (!rect_sprayed.hasZeroArea()) {
+ rgba2 = getPickerData(rect_sprayed.roundOutwards());
+ }
+ }
+ if(pick_no_overlap){
+ if(rgba != rgba2){
+ if(!no_overlap && (picker || over_transparent || over_no_transparent)){
+ showHidden(items_down);
+ }
+ return false;
+ }
+ }
+ if(!pick_center){
+ rgba = rgba2;
+ }
+ double opacity = 1.0;
+ gchar color_string[32]; *color_string = 0;
+ float r = SP_RGBA32_R_F(rgba);
+ float g = SP_RGBA32_G_F(rgba);
+ float b = SP_RGBA32_B_F(rgba);
+ float a = SP_RGBA32_A_F(rgba);
+ if(!over_transparent && (a == 0 || a < 1e-6)){
+ if(!no_overlap && (picker || over_transparent || over_no_transparent)){
+ showHidden(items_down);
+ }
+ return false;
+ }
+ if(!over_no_transparent && a > 0){
+ if(!no_overlap && (picker || over_transparent || over_no_transparent)){
+ showHidden(items_down);
+ }
+ return false;
+ }
+
+ if(picker && do_trace){
+ float hsl[3];
+ sp_color_rgb_to_hsl_floatv (hsl, r, g, b);
+
+ gdouble val = 0;
+ switch (pick) {
+ case PICK_COLOR:
+ val = 1 - hsl[2]; // inverse lightness; to match other picks where black = max
+ break;
+ case PICK_OPACITY:
+ val = a;
+ break;
+ case PICK_R:
+ val = r;
+ break;
+ case PICK_G:
+ val = g;
+ break;
+ case PICK_B:
+ val = b;
+ break;
+ case PICK_H:
+ val = hsl[0];
+ break;
+ case PICK_S:
+ val = hsl[1];
+ break;
+ case PICK_L:
+ val = 1 - hsl[2];
+ break;
+ default:
+ break;
+ }
+
+ if (rand_picked > 0) {
+ val = randomize01 (val, rand_picked);
+ r = randomize01 (r, rand_picked);
+ g = randomize01 (g, rand_picked);
+ b = randomize01 (b, rand_picked);
+ }
+
+ if (gamma_picked != 0) {
+ double power;
+ if (gamma_picked > 0)
+ power = 1/(1 + fabs(gamma_picked));
+ else
+ power = 1 + fabs(gamma_picked);
+
+ val = pow (val, power);
+ r = pow ((double)r, (double)power);
+ g = pow ((double)g, (double)power);
+ b = pow ((double)b, (double)power);
+ }
+
+ if (invert_picked) {
+ val = 1 - val;
+ r = 1 - r;
+ g = 1 - g;
+ b = 1 - b;
+ }
+
+ val = CLAMP (val, 0, 1);
+ r = CLAMP (r, 0, 1);
+ g = CLAMP (g, 0, 1);
+ b = CLAMP (b, 0, 1);
+
+ // recompose tweaked color
+ rgba = SP_RGBA32_F_COMPOSE(r, g, b, a);
+ if (pick_to_size) {
+ if(!trace_scale){
+ if(pick_inverse_value) {
+ _scale = 1.0 - val;
+ } else {
+ _scale = val;
+ }
+ if(_scale == 0.0) {
+ if(!no_overlap && (picker || over_transparent || over_no_transparent)){
+ showHidden(items_down);
+ }
+ return false;
+ }
+ if(!fit_item(desktop
+ , item
+ , bbox
+ , move
+ , center
+ , mode
+ , angle
+ , _scale
+ , scale
+ , picker
+ , pick_center
+ , pick_inverse_value
+ , pick_fill
+ , pick_stroke
+ , pick_no_overlap
+ , over_no_transparent
+ , over_transparent
+ , no_overlap
+ , offset
+ , css
+ , true
+ , pick
+ , do_trace
+ , pick_to_size
+ , pick_to_presence
+ , pick_to_color
+ , pick_to_opacity
+ , invert_picked
+ , gamma_picked
+ , rand_picked)
+ )
+ {
+ if(!no_overlap && (picker || over_transparent || over_no_transparent)){
+ showHidden(items_down);
+ }
+ return false;
+ }
+ }
+ }
+
+ if (pick_to_opacity) {
+ if(pick_inverse_value) {
+ opacity *= 1.0 - val;
+ } else {
+ opacity *= val;
+ }
+ std::stringstream opacity_str;
+ opacity_str.imbue(std::locale::classic());
+ opacity_str << opacity;
+ sp_repr_css_set_property(css, "opacity", opacity_str.str().c_str());
+ }
+ if (pick_to_presence) {
+ if (g_random_double_range (0, 1) > val) {
+ //Hidding the element is a way to retain original
+ //behaviour of tiled clones for presence option.
+ sp_repr_css_set_property(css, "opacity", "0");
+ }
+ }
+ if (pick_to_color) {
+ sp_svg_write_color(color_string, sizeof(color_string), rgba);
+ if(pick_fill){
+ sp_repr_css_set_property(css, "fill", color_string);
+ }
+ if(pick_stroke){
+ sp_repr_css_set_property(css, "stroke", color_string);
+ }
+ }
+ if (opacity < 1e-6) { // invisibly transparent, skip
+ if(!no_overlap && (picker || over_transparent || over_no_transparent)){
+ showHidden(items_down);
+ }
+ return false;
+ }
+ }
+ if(!do_trace){
+ if(!pick_center){
+ rgba = rgba2;
+ }
+ if (pick_inverse_value) {
+ r = 1 - SP_RGBA32_R_F(rgba);
+ g = 1 - SP_RGBA32_G_F(rgba);
+ b = 1 - SP_RGBA32_B_F(rgba);
+ } else {
+ r = SP_RGBA32_R_F(rgba);
+ g = SP_RGBA32_G_F(rgba);
+ b = SP_RGBA32_B_F(rgba);
+ }
+ rgba = SP_RGBA32_F_COMPOSE(r, g, b, a);
+ sp_svg_write_color(color_string, sizeof(color_string), rgba);
+ if(pick_fill){
+ sp_repr_css_set_property(css, "fill", color_string);
+ }
+ if(pick_stroke){
+ sp_repr_css_set_property(css, "stroke", color_string);
+ }
+ }
+ if(!no_overlap && (picker || over_transparent || over_no_transparent)){
+ showHidden(items_down);
+ }
+ }
+ return true;
+}
+
static bool sp_spray_recursive(SPDesktop *desktop,
Inkscape::Selection *selection,
SPItem *item,
@@ -348,7 +879,28 @@ static bool sp_spray_recursive(SPDesktop *desktop,
double ratio,
double tilt,
double rotation_variation,
- gint _distrib)
+ gint _distrib,
+ bool no_overlap,
+ bool picker,
+ bool pick_center,
+ bool pick_inverse_value,
+ bool pick_fill,
+ bool pick_stroke,
+ bool pick_no_overlap,
+ bool over_no_transparent,
+ bool over_transparent,
+ double offset,
+ bool usepressurescale,
+ double pressure,
+ int pick,
+ bool do_trace,
+ bool pick_to_size,
+ bool pick_to_presence,
+ bool pick_to_color,
+ bool pick_to_opacity,
+ bool invert_picked,
+ double gamma_picked ,
+ double rand_picked)
{
bool did = false;
@@ -364,34 +916,83 @@ static bool sp_spray_recursive(SPDesktop *desktop,
double _fid = g_random_double_range(0, 1);
double angle = g_random_double_range( - rotation_variation / 100.0 * M_PI , rotation_variation / 100.0 * M_PI );
double _scale = g_random_double_range( 1.0 - scale_variation / 100.0, 1.0 + scale_variation / 100.0 );
+ if(usepressurescale){
+ _scale = pressure;
+ }
double dr; double dp;
random_position( dr, dp, mean, standard_deviation, _distrib );
dr=dr*radius;
- if (mode == SPRAY_MODE_COPY) {
+ if (mode == SPRAY_MODE_COPY || mode == SPRAY_MODE_ERASER) {
Geom::OptRect a = item->documentVisualBounds();
if (a) {
- SPItem *item_copied;
if(_fid <= population)
{
- // Duplicate
SPDocument *doc = item->document;
+ gchar const * spray_origin;
+ if(!item->getAttribute("inkscape:spray-origin")){
+ spray_origin = g_strdup_printf("#%s", item->getId());
+ } else {
+ spray_origin = item->getAttribute("inkscape:spray-origin");
+ }
+ Geom::Point center = item->getCenter();
+ Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ if(no_overlap || picker || !over_transparent || !over_no_transparent){
+ if(!fit_item(desktop
+ , item
+ , a
+ , move
+ , center
+ , mode
+ , angle
+ , _scale
+ , scale
+ , picker
+ , pick_center
+ , pick_inverse_value
+ , pick_fill
+ , pick_stroke
+ , pick_no_overlap
+ , over_no_transparent
+ , over_transparent
+ , no_overlap
+ , offset
+ , css
+ , false
+ , pick
+ , do_trace
+ , pick_to_size
+ , pick_to_presence
+ , pick_to_color
+ , pick_to_opacity
+ , invert_picked
+ , gamma_picked
+ , rand_picked)){
+ return false;
+ }
+ }
+ SPItem *item_copied;
+ // Duplicate
Inkscape::XML::Document* xml_doc = doc->getReprDoc();
Inkscape::XML::Node *old_repr = item->getRepr();
Inkscape::XML::Node *parent = old_repr->parent();
Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc);
+ if(!copy->attribute("inkscape:spray-origin")){
+ copy->setAttribute("inkscape:spray-origin", spray_origin);
+ }
parent->appendChild(copy);
-
SPObject *new_obj = doc->getObjectByRepr(copy);
item_copied = dynamic_cast<SPItem *>(new_obj); // Conversion object->item
- Geom::Point center=item->getCenter();
- sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale,_scale));
- sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale,scale));
-
+ sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale));
+ sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale));
sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle));
// Move the cursor p
- Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
+ Inkscape::GC::release(copy);
+ if(picker){
+ sp_desktop_apply_css_recursive(item_copied, css, true);
+ }
did = true;
}
}
@@ -404,7 +1005,7 @@ static bool sp_spray_recursive(SPDesktop *desktop,
int i=1;
std::vector<SPItem*> items=selection->itemList();
- for(std::vector<SPItem*>::const_iterator it=items.begin();it!=items.end();it++){
+ for(std::vector<SPItem*>::const_iterator it=items.begin();it!=items.end(); ++it){
SPItem *item1 = *it;
if (i == 1) {
parent_item = item1;
@@ -425,6 +1026,13 @@ static bool sp_spray_recursive(SPDesktop *desktop,
if (_fid <= population) { // Rules the population of objects sprayed
// Duplicates the parent item
Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc);
+ gchar const * spray_origin;
+ if(!copy->attribute("inkscape:spray-origin")){
+ spray_origin = g_strdup_printf("#%s", old_repr->attribute("id"));
+ copy->setAttribute("inkscape:spray-origin", spray_origin);
+ } else {
+ spray_origin = copy->attribute("inkscape:spray-origin");
+ }
parent->appendChild(copy);
SPObject *new_obj = doc->getObjectByRepr(copy);
item_copied = dynamic_cast<SPItem *>(new_obj);
@@ -456,8 +1064,52 @@ static bool sp_spray_recursive(SPDesktop *desktop,
Geom::OptRect a = item->documentVisualBounds();
if (a) {
if(_fid <= population) {
- SPItem *item_copied;
SPDocument *doc = item->document;
+ gchar const * spray_origin;
+ if(!item->getAttribute("inkscape:spray-origin")){
+ spray_origin = g_strdup_printf("#%s", item->getId());
+ } else {
+ spray_origin = item->getAttribute("inkscape:spray-origin");
+ }
+ Geom::Point center=item->getCenter();
+ Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ if(no_overlap || picker || !over_transparent || !over_no_transparent){
+ if(!fit_item(desktop
+ , item
+ , a
+ , move
+ , center
+ , mode
+ , angle
+ , _scale
+ , scale
+ , picker
+ , pick_center
+ , pick_inverse_value
+ , pick_fill
+ , pick_stroke
+ , pick_no_overlap
+ , over_no_transparent
+ , over_transparent
+ , no_overlap
+ , offset
+ , css
+ , true
+ , pick
+ , do_trace
+ , pick_to_size
+ , pick_to_presence
+ , pick_to_color
+ , pick_to_opacity
+ , invert_picked
+ , gamma_picked
+ , rand_picked))
+ {
+ return false;
+ }
+ }
+ SPItem *item_copied;
Inkscape::XML::Document* xml_doc = doc->getReprDoc();
Inkscape::XML::Node *old_repr = item->getRepr();
Inkscape::XML::Node *parent = old_repr->parent();
@@ -467,6 +1119,9 @@ static bool sp_spray_recursive(SPDesktop *desktop,
// Ad the clone to the list of the parent's children
parent->appendChild(clone);
// Generates the link between parent and child attributes
+ if(!clone->attribute("inkscape:spray-origin")){
+ clone->setAttribute("inkscape:spray-origin", spray_origin);
+ }
gchar *href_str = g_strdup_printf("#%s", old_repr->attribute("id"));
clone->setAttribute("xlink:href", href_str, false);
g_free(href_str);
@@ -474,15 +1129,14 @@ static bool sp_spray_recursive(SPDesktop *desktop,
SPObject *clone_object = doc->getObjectByRepr(clone);
// Conversion object->item
item_copied = dynamic_cast<SPItem *>(clone_object);
- Geom::Point center = item->getCenter();
sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(_scale, _scale));
sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale, scale));
sp_spray_rotate_rel(center, desktop, item_copied, Geom::Rotate(angle));
- Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
-
+ if(picker){
+ sp_desktop_apply_css_recursive(item_copied, css, true);
+ }
Inkscape::GC::release(clone);
-
did = true;
}
}
@@ -520,22 +1174,57 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point
{
std::vector<SPItem*> const items(selection->itemList());
- for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end(); ++i){
SPItem *item = *i;
g_assert(item != NULL);
sp_object_ref(item);
}
- for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end(); ++i){
SPItem *item = *i;
g_assert(item != NULL);
-
- if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, population, tc->scale, tc->scale_variation, reverse, move_mean, move_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) {
+ if (sp_spray_recursive(desktop
+ , selection
+ , item
+ , p, vector
+ , tc->mode
+ , radius
+ , population
+ , tc->scale
+ , tc->scale_variation
+ , reverse
+ , move_mean
+ , move_standard_deviation
+ , tc->ratio
+ , tc->tilt
+ , tc->rotation_variation
+ , tc->distrib
+ , tc->no_overlap
+ , tc->picker
+ , tc->pick_center
+ , tc->pick_inverse_value
+ , tc->pick_fill
+ , tc->pick_stroke
+ , tc->pick_no_overlap
+ , tc->over_no_transparent
+ , tc->over_transparent
+ , tc->offset
+ , tc->usepressurescale
+ , get_pressure(tc)
+ , tc->pick
+ , tc->do_trace
+ , tc->pick_to_size
+ , tc->pick_to_presence
+ , tc->pick_to_color
+ , tc->pick_to_opacity
+ , tc->invert_picked
+ , tc->gamma_picked
+ , tc->rand_picked)) {
did = true;
}
}
- for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end(); ++i){
SPItem *item = *i;
g_assert(item != NULL);
sp_object_unref(item);
@@ -577,7 +1266,7 @@ bool SprayTool::root_handler(GdkEvent* event) {
if (Inkscape::have_viable_layer(desktop, this->message_context) == false) {
return TRUE;
}
-
+ this->setCloneTilerPrefs();
Geom::Point const motion_w(event->button.x, event->button.y);
Geom::Point const motion_dt(desktop->w2d(motion_w));
this->last_push = desktop->dt2doc(motion_dt);
diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h
index 8df730201..c81110b37 100644
--- a/src/ui/tools/spray-tool.h
+++ b/src/ui/tools/spray-tool.h
@@ -12,6 +12,7 @@
* BenoƮt LAVORATA
* Vincent MONTAGNE
* Pierre BARBRY-BLOT
+ * Jabiertxo ARRAIZA
*
* Copyright (C) 2009 authors
*
@@ -46,7 +47,8 @@ namespace Tools {
enum {
SPRAY_MODE_COPY,
SPRAY_MODE_CLONE,
- SPRAY_MODE_SINGLE_PATH,
+ SPRAY_MODE_SINGLE_PATH,
+ SPRAY_MODE_ERASER,
SPRAY_OPTION,
};
@@ -62,7 +64,9 @@ public:
/* attributes */
bool dragging; /* mouse state: mouse is dragging */
- bool usepressure;
+ bool usepressurewidth;
+ bool usepressurepopulation;
+ bool usepressurescale;
bool usetilt;
bool usetext;
@@ -86,13 +90,32 @@ public:
bool has_dilated;
Geom::Point last_push;
SPCanvasItem *dilate_area;
-
+ bool no_overlap;
+ bool picker;
+ bool pick_center;
+ bool pick_inverse_value;
+ bool pick_fill;
+ bool pick_stroke;
+ bool pick_no_overlap;
+ bool over_transparent;
+ bool over_no_transparent;
+ double offset;
+ int pick;
+ bool do_trace;
+ bool pick_to_size;
+ bool pick_to_presence;
+ bool pick_to_color;
+ bool pick_to_opacity;
+ bool invert_picked;
+ double gamma_picked;
+ double rand_picked;
sigc::connection style_set_connection;
static const std::string prefsPath;
virtual void setup();
virtual void set(const Inkscape::Preferences::Entry& val);
+ virtual void setCloneTilerPrefs();
virtual bool root_handler(GdkEvent* event);
virtual const std::string& getPrefsPath();
diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp
index 94f7aa135..39a7a3f0b 100644
--- a/src/ui/tools/tweak-tool.cpp
+++ b/src/ui/tools/tweak-tool.cpp
@@ -1077,7 +1077,7 @@ sp_tweak_dilate (TweakTool *tc, Geom::Point event_p, Geom::Point p, Geom::Point
double color_force = MIN(sqrt(path_force)/20.0, 1);
std::vector<SPItem*> items=selection->itemList();
- for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end(); ++i){
SPItem *item = *i;
if (is_color_mode (tc->mode)) {
diff --git a/src/ui/widget/font-variants.cpp b/src/ui/widget/font-variants.cpp
index 5d1e40971..62598dead 100644
--- a/src/ui/widget/font-variants.cpp
+++ b/src/ui/widget/font-variants.cpp
@@ -35,41 +35,41 @@ namespace Widget {
FontVariants::FontVariants () :
Gtk::VBox (),
- _ligatures_frame ( Glib::ustring(_("Ligatures" )) ),
- _ligatures_common ( Glib::ustring(_("Common" )) ),
- _ligatures_discretionary ( Glib::ustring(_("Discretionary")) ),
- _ligatures_historical ( Glib::ustring(_("Historical" )) ),
- _ligatures_contextual ( Glib::ustring(_("Contextual" )) ),
-
- _position_frame ( Glib::ustring(_("Position" )) ),
- _position_normal ( Glib::ustring(_("Normal" )) ),
- _position_sub ( Glib::ustring(_("Subscript" )) ),
- _position_super ( Glib::ustring(_("Superscript" )) ),
-
- _caps_frame ( Glib::ustring(_("Capitals" )) ),
- _caps_normal ( Glib::ustring(_("Normal" )) ),
- _caps_small ( Glib::ustring(_("Small" )) ),
- _caps_all_small ( Glib::ustring(_("All small" )) ),
- _caps_petite ( Glib::ustring(_("Petite" )) ),
- _caps_all_petite ( Glib::ustring(_("All petite" )) ),
- _caps_unicase ( Glib::ustring(_("Unicase" )) ),
- _caps_titling ( Glib::ustring(_("Titling" )) ),
-
- _numeric_frame ( Glib::ustring(_("Numeric" )) ),
- _numeric_lining ( Glib::ustring(_("Lining" )) ),
- _numeric_old_style ( Glib::ustring(_("Old Style" )) ),
- _numeric_default_style ( Glib::ustring(_("Default Style")) ),
- _numeric_proportional ( Glib::ustring(_("Proportional" )) ),
- _numeric_tabular ( Glib::ustring(_("Tabular" )) ),
- _numeric_default_width ( Glib::ustring(_("Default Width")) ),
- _numeric_diagonal ( Glib::ustring(_("Diagonal" )) ),
- _numeric_stacked ( Glib::ustring(_("Stacked" )) ),
- _numeric_default_fractions( Glib::ustring(_("Default Fractions")) ),
- _numeric_ordinal ( Glib::ustring(_("Ordinal" )) ),
- _numeric_slashed_zero ( Glib::ustring(_("Slashed Zero" )) ),
-
- _feature_frame ( Glib::ustring(_("Feature Settings")) ),
- _feature_label ( Glib::ustring(_("Selection has different Feature Settings!")) ),
+ _ligatures_frame ( Glib::ustring(C_("Font variant", "Ligatures" )) ),
+ _ligatures_common ( Glib::ustring(C_("Font variant", "Common" )) ),
+ _ligatures_discretionary ( Glib::ustring(C_("Font variant", "Discretionary")) ),
+ _ligatures_historical ( Glib::ustring(C_("Font variant", "Historical" )) ),
+ _ligatures_contextual ( Glib::ustring(C_("Font variant", "Contextual" )) ),
+
+ _position_frame ( Glib::ustring(C_("Font variant", "Position" )) ),
+ _position_normal ( Glib::ustring(C_("Font variant", "Normal" )) ),
+ _position_sub ( Glib::ustring(C_("Font variant", "Subscript" )) ),
+ _position_super ( Glib::ustring(C_("Font variant", "Superscript" )) ),
+
+ _caps_frame ( Glib::ustring(C_("Font variant", "Capitals" )) ),
+ _caps_normal ( Glib::ustring(C_("Font variant", "Normal" )) ),
+ _caps_small ( Glib::ustring(C_("Font variant", "Small" )) ),
+ _caps_all_small ( Glib::ustring(C_("Font variant", "All small" )) ),
+ _caps_petite ( Glib::ustring(C_("Font variant", "Petite" )) ),
+ _caps_all_petite ( Glib::ustring(C_("Font variant", "All petite" )) ),
+ _caps_unicase ( Glib::ustring(C_("Font variant", "Unicase" )) ),
+ _caps_titling ( Glib::ustring(C_("Font variant", "Titling" )) ),
+
+ _numeric_frame ( Glib::ustring(C_("Font variant", "Numeric" )) ),
+ _numeric_lining ( Glib::ustring(C_("Font variant", "Lining" )) ),
+ _numeric_old_style ( Glib::ustring(C_("Font variant", "Old Style" )) ),
+ _numeric_default_style ( Glib::ustring(C_("Font variant", "Default Style")) ),
+ _numeric_proportional ( Glib::ustring(C_("Font variant", "Proportional" )) ),
+ _numeric_tabular ( Glib::ustring(C_("Font variant", "Tabular" )) ),
+ _numeric_default_width ( Glib::ustring(C_("Font variant", "Default Width")) ),
+ _numeric_diagonal ( Glib::ustring(C_("Font variant", "Diagonal" )) ),
+ _numeric_stacked ( Glib::ustring(C_("Font variant", "Stacked" )) ),
+ _numeric_default_fractions( Glib::ustring(C_("Font variant", "Default Fractions")) ),
+ _numeric_ordinal ( Glib::ustring(C_("Font variant", "Ordinal" )) ),
+ _numeric_slashed_zero ( Glib::ustring(C_("Font variant", "Slashed Zero" )) ),
+
+ _feature_frame ( Glib::ustring(C_("Font variant", "Feature Settings")) ),
+ _feature_label ( Glib::ustring(C_("Font variant", "Selection has different Feature Settings!")) ),
_ligatures_changed( false ),
_position_changed( false ),