From 522cc95fa0ffa9483134df80e4b85e9c273c967e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 25 Sep 2013 02:14:24 +0200 Subject: First attemp for (bzr r12588.1.1) --- src/draw-context.cpp | 105 ++++++++++++++++++++++++++++++++++++++-- src/live_effects/lpe-bendpath.h | 2 +- src/widgets/pencil-toolbar.cpp | 2 + 3 files changed, 105 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 09366526a..8b0237c0f 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -20,6 +20,7 @@ # include "config.h" #endif +#include "live_effects/lpe-bendpath.h" #include "live_effects/lpe-patternalongpath.h" #include "display/canvas-bpath.h" #include "xml/repr.h" @@ -45,7 +46,7 @@ #include "style.h" #include "ui/control-manager.h" #include "draw-context.h" - +#include "ui/clipboard.h" #include using Inkscape::DocumentUndo; @@ -244,7 +245,10 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } + static Geom::PathVector pathv; + static SPItem *itemEnd; int shape = prefs->getInt(tool_name(dc) + "/shape", 0); + static int previous_shape; bool shape_applied = false; SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); const char *cstroke = sp_repr_css_property(css_item, "stroke", "none"); @@ -299,13 +303,108 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item Effect::createAndApply(PATTERN_ALONG_PATH, dc->desktop->doc(), item); Effect* lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)); static_cast(lpe)->pattern.on_paste_button_click(); - + Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); + Glib::ustring svgd = cm->getPathParameter(SP_ACTIVE_DESKTOP); + pathv = sp_svg_read_pathv(svgd.data()); shape_applied = true; break; } + case 5: + { + // take shape from clipboard; TODO: catch the case where clipboard is empty + Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); + if(cm->paste(SP_ACTIVE_DESKTOP,false) == true){ + Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); + sp_selection_group(selection, dc->desktop); + GSList *items = const_cast(selection->itemList()); + SPObject *obj = reinterpret_cast(g_slist_nth_data(items,0)); + itemEnd = SP_ITEM(obj); + Effect::createAndApply(BEND_PATH, dc->desktop->doc(), itemEnd); + Effect* lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(itemEnd)); + gchar const *svgd = item->getRepr()->attribute("d"); + static_cast(lpe)->bend_path.paste_param_path(svgd); + static_cast(lpe)->bend_path.param_editOncanvas(itemEnd, SP_ACTIVE_DESKTOP); + item->deleteObject(false,false); + //SPItem* item = itemEnd; + } + break; + } + case 6: + { + // "Last applied" + switch(previous_shape){ + case 0: + // don't apply any shape + break; + case 1: + { + // "triangle in" + std::vector points(1); + points[0] = Geom::Point(0., SHAPE_HEIGHT/2); + spdc_apply_powerstroke_shape(points, dc, item); + + shape_applied = true; + break; + } + case 2: + { + // "triangle out" + guint curve_length = curve->get_segment_count(); + std::vector points(1); + points[0] = Geom::Point((double)curve_length, SHAPE_HEIGHT/2); + spdc_apply_powerstroke_shape(points, dc, item); + + shape_applied = true; + break; + } + case 3: + { + // "ellipse" + SPCurve *c = new SPCurve(); + const double C1 = 0.552; + c->moveto(0, SHAPE_HEIGHT/2); + c->curveto(0, (1 - C1) * SHAPE_HEIGHT/2, (1 - C1) * SHAPE_LENGTH/2, 0, SHAPE_LENGTH/2, 0); + c->curveto((1 + C1) * SHAPE_LENGTH/2, 0, SHAPE_LENGTH, (1 - C1) * SHAPE_HEIGHT/2, SHAPE_LENGTH, SHAPE_HEIGHT/2); + c->curveto(SHAPE_LENGTH, (1 + C1) * SHAPE_HEIGHT/2, (1 + C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, SHAPE_LENGTH/2, SHAPE_HEIGHT); + c->curveto((1 - C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, 0, (1 + C1) * SHAPE_HEIGHT/2, 0, SHAPE_HEIGHT/2); + c->closepath(); + spdc_paste_curve_as_freehand_shape(c, dc, item); + c->unref(); + shape_applied = true; + break; + } + case 4: + { + if(pathv.size() != 0){ + SPCurve * c = new SPCurve(); + c->set_pathvector(pathv); + spdc_paste_curve_as_freehand_shape(c, dc, item); + c->unref(); + shape_applied = true; + } + break; + } + case 5: + { + // take shape from clipboard; TODO: catch the case where clipboard is empty + if(itemEnd != NULL){ + Effect::createAndApply(BEND_PATH, dc->desktop->doc(), itemEnd); + Effect* lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(itemEnd)); + gchar const *svgd = item->getRepr()->attribute("d"); + static_cast(lpe)->bend_path.paste_param_path(svgd); + static_cast(lpe)->bend_path.param_editOncanvas(itemEnd, SP_ACTIVE_DESKTOP); + item->deleteObject(false,false); + //SPItem* item = itemEnd; + } + break; + } + } + shape = previous_shape; + } default: break; } + previous_shape = shape; if (shape_applied) { // apply original stroke color as fill and unset stroke; then return SPCSSAttr *css = sp_repr_css_attr_new(); @@ -322,7 +421,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item } if (dc->waiting_LPE_type != INVALID_LPE) { - Effect::createAndApply(dc->waiting_LPE_type, dc->desktop->doc(), item); + if(shape != 5) Effect::createAndApply(dc->waiting_LPE_type, dc->desktop->doc(), item); dc->waiting_LPE_type = INVALID_LPE; if (SP_IS_LPETOOL_CONTEXT(dc)) { diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 16b8c6137..d3564bac4 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -39,9 +39,9 @@ public: virtual void resetDefaults(SPItem const* item); + PathParam bend_path; private: - PathParam bend_path; ScalarParam prop_scale; BoolParam scale_y_rel; BoolParam vertical_pattern; diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index f112a35fa..b16d55680 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -186,6 +186,8 @@ static GList * freehand_shape_dropdown_items_list() { glist = g_list_append (glist, _("Triangle out")); glist = g_list_append (glist, _("Ellipse")); glist = g_list_append (glist, _("From clipboard")); + glist = g_list_append (glist, _("Skeletal Stroke from clipboard")); + glist = g_list_append (glist, _("Last applied")); return glist; } -- cgit v1.2.3 From 4e687553f3955ef0988184c421a36ca19912c257 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 25 Sep 2013 02:39:56 +0200 Subject: Fix error in apply (bzr r12588.1.2) --- src/draw-context.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 8b0237c0f..ceb72cc71 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -235,6 +235,20 @@ static void spdc_apply_powerstroke_shape(const std::vector & points lpe->getRepr()->setAttribute("interpolator_beta", "0.2"); } +static void spdc_apply_bend_shape(gchar const *svgd, SPDrawContext *dc, SPItem *item) +{ + using namespace Inkscape::LivePathEffect; + + Effect::createAndApply(BEND_PATH, dc->desktop->doc(), item); + Effect* lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)); + + // write bend parameters: + lpe->getRepr()->setAttribute("bend_path", svgd); + lpe->getRepr()->setAttribute("prop_scale", "1"); + lpe->getRepr()->setAttribute("scale_y_rel", "false"); + lpe->getRepr()->setAttribute("vertical_pattern", "false"); +} + static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item, SPCurve *curve) { using namespace Inkscape::LivePathEffect; @@ -319,13 +333,9 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item GSList *items = const_cast(selection->itemList()); SPObject *obj = reinterpret_cast(g_slist_nth_data(items,0)); itemEnd = SP_ITEM(obj); - Effect::createAndApply(BEND_PATH, dc->desktop->doc(), itemEnd); - Effect* lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(itemEnd)); gchar const *svgd = item->getRepr()->attribute("d"); - static_cast(lpe)->bend_path.paste_param_path(svgd); - static_cast(lpe)->bend_path.param_editOncanvas(itemEnd, SP_ACTIVE_DESKTOP); - item->deleteObject(false,false); - //SPItem* item = itemEnd; + spdc_apply_bend_shape(svgd, dc, itemEnd); + item->deleteObject(); } break; } @@ -388,13 +398,9 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item { // take shape from clipboard; TODO: catch the case where clipboard is empty if(itemEnd != NULL){ - Effect::createAndApply(BEND_PATH, dc->desktop->doc(), itemEnd); - Effect* lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(itemEnd)); gchar const *svgd = item->getRepr()->attribute("d"); - static_cast(lpe)->bend_path.paste_param_path(svgd); - static_cast(lpe)->bend_path.param_editOncanvas(itemEnd, SP_ACTIVE_DESKTOP); - item->deleteObject(false,false); - //SPItem* item = itemEnd; + spdc_apply_bend_shape(svgd, dc, itemEnd); + item->deleteObject(); } break; } @@ -421,7 +427,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item } if (dc->waiting_LPE_type != INVALID_LPE) { - if(shape != 5) Effect::createAndApply(dc->waiting_LPE_type, dc->desktop->doc(), item); + Effect::createAndApply(dc->waiting_LPE_type, dc->desktop->doc(), item); dc->waiting_LPE_type = INVALID_LPE; if (SP_IS_LPETOOL_CONTEXT(dc)) { -- cgit v1.2.3 From af156edfd8f77cdffdd572ce9f2d76642e830a43 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 25 Sep 2013 02:46:32 +0200 Subject: Name of attributes in effect changed (bzr r12588.1.3) --- src/draw-context.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index ceb72cc71..66064949a 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -243,10 +243,10 @@ static void spdc_apply_bend_shape(gchar const *svgd, SPDrawContext *dc, SPItem * Effect* lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)); // write bend parameters: - lpe->getRepr()->setAttribute("bend_path", svgd); + lpe->getRepr()->setAttribute("bendpath", svgd); lpe->getRepr()->setAttribute("prop_scale", "1"); lpe->getRepr()->setAttribute("scale_y_rel", "false"); - lpe->getRepr()->setAttribute("vertical_pattern", "false"); + lpe->getRepr()->setAttribute("vertical", "false"); } static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item, SPCurve *curve) -- cgit v1.2.3 From b59da03d20018c9e5aad70b6a356db3e6015cfae Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 25 Sep 2013 03:20:01 +0200 Subject: Some Fix (bzr r12588.1.4) --- src/widgets/pencil-toolbar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index b16d55680..783d8dd4d 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -186,7 +186,7 @@ static GList * freehand_shape_dropdown_items_list() { glist = g_list_append (glist, _("Triangle out")); glist = g_list_append (glist, _("Ellipse")); glist = g_list_append (glist, _("From clipboard")); - glist = g_list_append (glist, _("Skeletal Stroke from clipboard")); + glist = g_list_append (glist, _("Bend from clipboard")); glist = g_list_append (glist, _("Last applied")); return glist; -- cgit v1.2.3 From e1c46795a24f7f7edb18424193b21314b31a138d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 26 Sep 2013 22:02:39 +0200 Subject: Fixing ending selection (bzr r12588.1.6) --- src/draw-context.cpp | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 051b54711..618a9c240 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -328,14 +328,22 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item // take shape from clipboard; TODO: catch the case where clipboard is empty Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if(cm->paste(SP_ACTIVE_DESKTOP,false) == true){ + gchar const *svgd = item->getRepr()->attribute("d"); + item->deleteObject(); + if(itemEnd != NULL && itemEnd->getRepr() != NULL) + itemEnd->deleteObject(); Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); sp_selection_group(selection, dc->desktop); GSList *items = const_cast(selection->itemList()); SPObject *obj = reinterpret_cast(g_slist_nth_data(items,0)); itemEnd = SP_ITEM(obj); - gchar const *svgd = item->getRepr()->attribute("d"); - spdc_apply_bend_shape(svgd, dc, itemEnd); - item->deleteObject(); + sp_selection_duplicate(dc->desktop); + itemEnd->setExplicitlyHidden(true); + items = const_cast(selection->itemList()); + obj = reinterpret_cast(g_slist_nth_data(items,0)); + spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); + SP_ITEM(obj)->setExplicitlyHidden(false); + selection->set(obj,true); } break; } @@ -397,25 +405,24 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item case 5: { // take shape from clipboard; TODO: catch the case where clipboard is empty - if(itemEnd != NULL){ + if(itemEnd != NULL && itemEnd->getRepr() != NULL){ + gchar const *svgd = item->getRepr()->attribute("d"); + item->deleteObject(); Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); - selection->clear(); - selection->add(itemEnd); + selection->add(SP_OBJECT(itemEnd)); sp_selection_duplicate(dc->desktop); + selection->remove(SP_OBJECT(itemEnd)); GSList *items = const_cast(selection->itemList()); SPObject *obj = reinterpret_cast(g_slist_nth_data(items,0)); - itemEnd = SP_ITEM(obj); - itemEnd->getRepr()->setAttribute("inkscape:path-effect", NULL); - gchar const *svgd = item->getRepr()->attribute("d"); - spdc_apply_bend_shape(svgd, dc, itemEnd); - selection->clear(); - selection->add(itemEnd); - item->deleteObject(); + SP_ITEM(obj)->getRepr()->setAttribute("inkscape:path-effect", NULL); + spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); + SP_ITEM(obj)->setExplicitlyHidden(false); + selection->set(obj,true); } break; } - } - shape = previous_shape; + } + shape = previous_shape; } default: break; -- cgit v1.2.3 From 2f4916861e76618e5a1767c3209d78a11e7eb24d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 15 Oct 2013 02:59:47 +0200 Subject: Fix errors on compile and in console detected by su_v, added selection of stroke used (bzr r12588.1.13) --- src/draw-context.cpp | 52 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 62e96a21c..c3cc65021 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -240,7 +240,7 @@ static void spdc_apply_bend_shape(gchar const *svgd, SPDrawContext *dc, SPItem * using namespace Inkscape::LivePathEffect; Effect::createAndApply(BEND_PATH, dc->desktop->doc(), item); - Effect* lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)); + Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); // write bend parameters: lpe->getRepr()->setAttribute("bendpath", svgd); @@ -258,7 +258,12 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - + //BSpline + //AƱadimos el modo BSpline a los efectos en espera + if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { + Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); + } + //BSPline End static Geom::PathVector pathv; static SPItem *itemEnd; int shape = prefs->getInt(tool_name(dc) + "/shape", 0); @@ -266,6 +271,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item bool shape_applied = false; SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); const char *cstroke = sp_repr_css_property(css_item, "stroke", "none"); + Inkscape::XML::Document *xml_doc = SP_ACTIVE_DESKTOP->doc()->getReprDoc(); #define SHAPE_LENGTH 10 #define SHAPE_HEIGHT 10 @@ -329,21 +335,26 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if(cm->paste(SP_ACTIVE_DESKTOP,false) == true){ gchar const *svgd = item->getRepr()->attribute("d"); - item->deleteObject(); - if(itemEnd != NULL && itemEnd->getRepr() != NULL) + //item->deleteObject(); + if(itemEnd != NULL && !itemEnd->getRepr()) itemEnd->deleteObject(); Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); sp_selection_group(selection, dc->desktop); GSList *items = const_cast(selection->itemList()); SPObject *obj = reinterpret_cast(g_slist_nth_data(items,0)); - itemEnd = SP_ITEM(obj); - sp_selection_duplicate(dc->desktop); - itemEnd->setExplicitlyHidden(true); - items = const_cast(selection->itemList()); - obj = reinterpret_cast(g_slist_nth_data(items,0)); - spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); - SP_ITEM(obj)->setExplicitlyHidden(false); - selection->set(obj,true); + if(SP_IS_OBJECT(obj)){ + itemEnd = SP_ITEM(obj); + sp_selection_duplicate(dc->desktop); + itemEnd->setExplicitlyHidden(true); + items = const_cast(selection->itemList()); + obj = reinterpret_cast(g_slist_nth_data(items,0)); + if(SP_IS_OBJECT(obj)){ + spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); + SP_ITEM(obj)->setExplicitlyHidden(false); + item->updateRepr(xml_doc,SP_ITEM(obj)->getRepr(),SP_OBJECT_WRITE_BUILD); + SP_ITEM(obj)->deleteObject(); + } + } } break; } @@ -405,19 +416,23 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item case 5: { // take shape from clipboard; TODO: catch the case where clipboard is empty - if(itemEnd != NULL && itemEnd->getRepr() != NULL){ + if(itemEnd != NULL && !itemEnd->getRepr()){ gchar const *svgd = item->getRepr()->attribute("d"); - item->deleteObject(); + //item->deleteObject(); Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); selection->add(SP_OBJECT(itemEnd)); sp_selection_duplicate(dc->desktop); selection->remove(SP_OBJECT(itemEnd)); GSList *items = const_cast(selection->itemList()); SPObject *obj = reinterpret_cast(g_slist_nth_data(items,0)); - SP_ITEM(obj)->getRepr()->setAttribute("inkscape:path-effect", NULL); - spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); - SP_ITEM(obj)->setExplicitlyHidden(false); - selection->set(obj,true); + if(SP_IS_OBJECT(obj)){ + SP_ITEM(obj)->getRepr()->setAttribute("inkscape:path-effect", NULL); + spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); + SP_ITEM(obj)->setExplicitlyHidden(false); + item = SP_ITEM(obj); + item->updateRepr(xml_doc,SP_ITEM(obj)->getRepr(),SP_OBJECT_WRITE_BUILD); + SP_ITEM(obj)->deleteObject(); + } } break; } @@ -442,6 +457,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item sp_repr_css_attr_unref(css); return; } + if(shape == 5 || (shape == 6 && previous_shape == 5))return; if (dc->waiting_LPE_type != INVALID_LPE) { Effect::createAndApply(dc->waiting_LPE_type, dc->desktop->doc(), item); -- cgit v1.2.3 From fa0850f0af674ce9f21378a9554fbe6c03b03603 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 15 Oct 2013 03:10:55 +0200 Subject: Fixing errors (bzr r12588.1.15) --- src/draw-context.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index c3cc65021..37c3c42c0 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -351,7 +351,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item if(SP_IS_OBJECT(obj)){ spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); SP_ITEM(obj)->setExplicitlyHidden(false); - item->updateRepr(xml_doc,SP_ITEM(obj)->getRepr(),SP_OBJECT_WRITE_BUILD); + item->updateRepr(xml_doc,SP_ITEM(obj)->getRepr(),SP_OBJECT_WRITE_ALL); SP_ITEM(obj)->deleteObject(); } } @@ -430,7 +430,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); SP_ITEM(obj)->setExplicitlyHidden(false); item = SP_ITEM(obj); - item->updateRepr(xml_doc,SP_ITEM(obj)->getRepr(),SP_OBJECT_WRITE_BUILD); + item->updateRepr(xml_doc,SP_ITEM(obj)->getRepr(),SP_OBJECT_WRITE_ALL); SP_ITEM(obj)->deleteObject(); } } -- cgit v1.2.3 From 227ceae5c30b8ec0c0eb81eff06a387ad18b6e99 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 16 Oct 2013 12:04:41 +0200 Subject: fixing bend warnings (bzr r12588.1.16) --- src/draw-context.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 37c3c42c0..df0e6be3b 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -249,6 +249,7 @@ static void spdc_apply_bend_shape(gchar const *svgd, SPDrawContext *dc, SPItem * lpe->getRepr()->setAttribute("vertical", "false"); } +static bool bend; static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item, SPCurve *curve) { using namespace Inkscape::LivePathEffect; @@ -264,6 +265,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } //BSPline End + bend = false; static Geom::PathVector pathv; static SPItem *itemEnd; int shape = prefs->getInt(tool_name(dc) + "/shape", 0); @@ -271,7 +273,6 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item bool shape_applied = false; SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); const char *cstroke = sp_repr_css_property(css_item, "stroke", "none"); - Inkscape::XML::Document *xml_doc = SP_ACTIVE_DESKTOP->doc()->getReprDoc(); #define SHAPE_LENGTH 10 #define SHAPE_HEIGHT 10 @@ -335,7 +336,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if(cm->paste(SP_ACTIVE_DESKTOP,false) == true){ gchar const *svgd = item->getRepr()->attribute("d"); - //item->deleteObject(); + item->deleteObject(); if(itemEnd != NULL && !itemEnd->getRepr()) itemEnd->deleteObject(); Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); @@ -351,8 +352,8 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item if(SP_IS_OBJECT(obj)){ spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); SP_ITEM(obj)->setExplicitlyHidden(false); - item->updateRepr(xml_doc,SP_ITEM(obj)->getRepr(),SP_OBJECT_WRITE_ALL); - SP_ITEM(obj)->deleteObject(); + bend = true; + selection->set(SP_ITEM(obj),true); } } } @@ -418,7 +419,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item // take shape from clipboard; TODO: catch the case where clipboard is empty if(itemEnd != NULL && !itemEnd->getRepr()){ gchar const *svgd = item->getRepr()->attribute("d"); - //item->deleteObject(); + item->deleteObject(); Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); selection->add(SP_OBJECT(itemEnd)); sp_selection_duplicate(dc->desktop); @@ -430,8 +431,9 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); SP_ITEM(obj)->setExplicitlyHidden(false); item = SP_ITEM(obj); - item->updateRepr(xml_doc,SP_ITEM(obj)->getRepr(),SP_OBJECT_WRITE_ALL); - SP_ITEM(obj)->deleteObject(); + SP_OBJECT(item)->setSuccessor(obj); + bend = true; + selection->set(SP_ITEM(obj),true); } } break; @@ -681,6 +683,8 @@ static void spdc_flush_white(SPDrawContext *dc, SPCurve *gc) { SPCurve *c; + if(bend) return; + if (dc->white_curves) { g_assert(dc->white_item); c = SPCurve::concat(dc->white_curves); -- cgit v1.2.3 From b4e5058110f8e4f5ed22eb9e9ba67129c6895413 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 16 Oct 2013 12:33:57 +0200 Subject: fixing bend warnings (bzr r12588.1.18) --- src/draw-context.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index df0e6be3b..7eafcabab 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -683,8 +683,6 @@ static void spdc_flush_white(SPDrawContext *dc, SPCurve *gc) { SPCurve *c; - if(bend) return; - if (dc->white_curves) { g_assert(dc->white_item); c = SPCurve::concat(dc->white_curves); @@ -738,11 +736,11 @@ static void spdc_flush_white(SPDrawContext *dc, SPCurve *gc) // we finished the path; now apply any waiting LPEs or freehand shapes spdc_check_for_and_apply_waiting_LPE(dc, item, c); - dc->selection->set(repr); + if(!bend) dc->selection->set(repr); Inkscape::GC::release(repr); - item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - item->doWriteTransform(item->getRepr(), item->transform, NULL, true); - item->updateRepr(); + if(!bend) item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + if(!bend) item->doWriteTransform(item->getRepr(), item->transform, NULL, true); + if(!bend) item->updateRepr(); } DocumentUndo::done(doc, SP_IS_PEN_CONTEXT(dc)? SP_VERB_CONTEXT_PEN : SP_VERB_CONTEXT_PENCIL, -- cgit v1.2.3 From 420a873bbc7ab29821174b31ab44f8dc78b50b9b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 16 Oct 2013 12:40:49 +0200 Subject: fixing bend warnings (bzr r12588.1.19) --- src/draw-context.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 7eafcabab..b2afb5095 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -430,8 +430,6 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item SP_ITEM(obj)->getRepr()->setAttribute("inkscape:path-effect", NULL); spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); SP_ITEM(obj)->setExplicitlyHidden(false); - item = SP_ITEM(obj); - SP_OBJECT(item)->setSuccessor(obj); bend = true; selection->set(SP_ITEM(obj),true); } -- cgit v1.2.3 From 2cb4bc14f2c2252ea5af6e0e5b857d8d5813ffcd Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 16 Oct 2013 12:51:38 +0200 Subject: fixing last applied bend (bzr r12588.1.20) --- src/draw-context.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index b2afb5095..3b89652b9 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -337,7 +337,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item if(cm->paste(SP_ACTIVE_DESKTOP,false) == true){ gchar const *svgd = item->getRepr()->attribute("d"); item->deleteObject(); - if(itemEnd != NULL && !itemEnd->getRepr()) + if(itemEnd != NULL && itemEnd->getRepr() != NULL) itemEnd->deleteObject(); Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); sp_selection_group(selection, dc->desktop); @@ -417,7 +417,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item case 5: { // take shape from clipboard; TODO: catch the case where clipboard is empty - if(itemEnd != NULL && !itemEnd->getRepr()){ + if(itemEnd != NULL && itemEnd->getRepr() != NULL){ gchar const *svgd = item->getRepr()->attribute("d"); item->deleteObject(); Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); -- cgit v1.2.3 From 6c7e1a4c27e6ce0d7b59c1512ea612e584b16fc0 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 16 Oct 2013 14:19:49 +0200 Subject: Make private bend parameter like original (bzr r12588.1.21) --- src/live_effects/lpe-bendpath.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index d3564bac4..38b1a1446 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -39,9 +39,8 @@ public: virtual void resetDefaults(SPItem const* item); - PathParam bend_path; - private: + PathParam bend_path; ScalarParam prop_scale; BoolParam scale_y_rel; BoolParam vertical_pattern; -- cgit v1.2.3 From bd1f2f185d4b1f4a849d07c4e57e9475f54821fd Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 16 Oct 2013 14:23:21 +0200 Subject: add empty line in bend parameter like original (bzr r12588.1.22) --- src/live_effects/lpe-bendpath.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 38b1a1446..16b8c6137 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -39,6 +39,7 @@ public: virtual void resetDefaults(SPItem const* item); + private: PathParam bend_path; ScalarParam prop_scale; -- cgit v1.2.3 From 474cbb61fee066dcfd84455820881dc50e97b1b7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 16 Oct 2013 14:32:21 +0200 Subject: Removed BSpline from tell by su_v (bzr r12588.1.23) --- src/draw-context.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 3b89652b9..dcddd683e 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -259,12 +259,6 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - //BSpline - //AƱadimos el modo BSpline a los efectos en espera - if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { - Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); - } - //BSPline End bend = false; static Geom::PathVector pathv; static SPItem *itemEnd; -- cgit v1.2.3 From 604d6fee79a94bd2a54078e1e4d3e70a1bfe56d4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 16 Nov 2013 22:22:08 +0100 Subject: fix error su_v tell to me (bzr r12588.1.27) --- src/ui/tools/freehand-base.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 6e3a04b59..510dfcf4d 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -240,7 +240,7 @@ static void spdc_apply_powerstroke_shape(const std::vector & points lpe->getRepr()->setAttribute("interpolator_beta", "0.2"); } -<<<<<<< TREE + static void spdc_apply_bend_shape(gchar const *svgd, SPDrawContext *dc, SPItem *item) { using namespace Inkscape::LivePathEffect; @@ -256,10 +256,8 @@ static void spdc_apply_bend_shape(gchar const *svgd, SPDrawContext *dc, SPItem * } static bool bend; -static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item, SPCurve *curve) -======= static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, SPCurve *curve) ->>>>>>> MERGE-SOURCE + { using namespace Inkscape::LivePathEffect; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); -- cgit v1.2.3 From c764ff004f76c5d7ac484c9392935bcc0b3ab731 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 16 Nov 2013 22:53:28 +0100 Subject: Fix repointed by su_v (bzr r12588.1.29) --- src/ui/tools/freehand-base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 510dfcf4d..b80a3a503 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -241,7 +241,7 @@ static void spdc_apply_powerstroke_shape(const std::vector & points } -static void spdc_apply_bend_shape(gchar const *svgd, SPDrawContext *dc, SPItem *item) +static void spdc_apply_bend_shape(gchar const *svgd, FreehandBase *dc, SPItem *item) { using namespace Inkscape::LivePathEffect; -- cgit v1.2.3 From 67818f7833a38c77fcbe2f7960816ce68505408a Mon Sep 17 00:00:00 2001 From: root Date: Wed, 2 Apr 2014 01:40:57 +0200 Subject: refactor from lastApplied (bzr r12588.1.33) --- src/ui/tools/freehand-base.cpp | 148 ++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 89 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index df2e6f517..4f2ec6c48 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -250,8 +250,7 @@ static void spdc_apply_bend_shape(gchar const *svgd, FreehandBase *dc, SPItem *i lpe->getRepr()->setAttribute("scale_y_rel", "false"); lpe->getRepr()->setAttribute("vertical", "false"); } - -static bool bend; +static int previous_shape_type = -1; static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, SPCurve *curve) { @@ -262,18 +261,32 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - bend = false; - static Geom::PathVector pathv; - static SPItem *itemEnd; + + //Store the clipboard path to apply in the future without the use of clipboard + static Geom::PathVector previous_shape_pathv; + //Last shape applied type "-1" means "no previous shape" int shape = prefs->getInt(tool_name(dc) + "/shape", 0); - static int previous_shape; bool shape_applied = false; SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); const char *cstroke = sp_repr_css_property(css_item, "stroke", "none"); + static SPItem *itemEnd; #define SHAPE_LENGTH 10 #define SHAPE_HEIGHT 10 + if(shape == 6){ + shape = previous_shape_type; + if(shape == 4){ + shape = 6; + } + if(shape == 5){ + shape = 7; + } + if(previous_shape_type == -1){ + shape = 0; + } + } + switch (shape) { case 0: // don't apply any shape @@ -312,6 +325,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, c->closepath(); spdc_paste_curve_as_freehand_shape(c, dc, item); c->unref(); + shape_applied = true; break; } @@ -323,7 +337,8 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, static_cast(lpe)->pattern.on_paste_button_click(); Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); Glib::ustring svgd = cm->getPathParameter(SP_ACTIVE_DESKTOP); - pathv = sp_svg_read_pathv(svgd.data()); + previous_shape_pathv = sp_svg_read_pathv(svgd.data()); + shape_applied = true; break; } @@ -349,7 +364,6 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if(SP_IS_OBJECT(obj)){ spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); SP_ITEM(obj)->setExplicitlyHidden(false); - bend = true; selection->set(SP_ITEM(obj),true); } } @@ -358,88 +372,44 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, } case 6: { - // "Last applied" - switch(previous_shape){ - case 0: - // don't apply any shape - break; - case 1: - { - // "triangle in" - std::vector points(1); - points[0] = Geom::Point(0., SHAPE_HEIGHT/2); - spdc_apply_powerstroke_shape(points, dc, item); - - shape_applied = true; - break; - } - case 2: - { - // "triangle out" - guint curve_length = curve->get_segment_count(); - std::vector points(1); - points[0] = Geom::Point((double)curve_length, SHAPE_HEIGHT/2); - spdc_apply_powerstroke_shape(points, dc, item); - - shape_applied = true; - break; - } - case 3: - { - // "ellipse" - SPCurve *c = new SPCurve(); - const double C1 = 0.552; - c->moveto(0, SHAPE_HEIGHT/2); - c->curveto(0, (1 - C1) * SHAPE_HEIGHT/2, (1 - C1) * SHAPE_LENGTH/2, 0, SHAPE_LENGTH/2, 0); - c->curveto((1 + C1) * SHAPE_LENGTH/2, 0, SHAPE_LENGTH, (1 - C1) * SHAPE_HEIGHT/2, SHAPE_LENGTH, SHAPE_HEIGHT/2); - c->curveto(SHAPE_LENGTH, (1 + C1) * SHAPE_HEIGHT/2, (1 + C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, SHAPE_LENGTH/2, SHAPE_HEIGHT); - c->curveto((1 - C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, 0, (1 + C1) * SHAPE_HEIGHT/2, 0, SHAPE_HEIGHT/2); - c->closepath(); - spdc_paste_curve_as_freehand_shape(c, dc, item); - c->unref(); - shape_applied = true; - break; - } - case 4: - { - if(pathv.size() != 0){ - SPCurve * c = new SPCurve(); - c->set_pathvector(pathv); - spdc_paste_curve_as_freehand_shape(c, dc, item); - c->unref(); - shape_applied = true; - } - break; - } - case 5: - { - // take shape from clipboard; TODO: catch the case where clipboard is empty - if(itemEnd != NULL && itemEnd->getRepr() != NULL){ - gchar const *svgd = item->getRepr()->attribute("d"); - item->deleteObject(); - Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); - selection->add(SP_OBJECT(itemEnd)); - sp_selection_duplicate(dc->desktop); - selection->remove(SP_OBJECT(itemEnd)); - GSList *items = const_cast(selection->itemList()); - SPObject *obj = reinterpret_cast(g_slist_nth_data(items,0)); - if(SP_IS_OBJECT(obj)){ - SP_ITEM(obj)->getRepr()->setAttribute("inkscape:path-effect", NULL); - spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); - SP_ITEM(obj)->setExplicitlyHidden(false); - bend = true; - selection->set(SP_ITEM(obj),true); - } - } - break; + if(previous_shape_pathv.size() != 0){ + SPCurve * c = new SPCurve(); + c->set_pathvector(previous_shape_pathv); + spdc_paste_curve_as_freehand_shape(c, dc, item); + c->unref(); + + shape_applied = true; + } + + shape = previous_shape_type; + break; + } + case 7: + { + // take shape from clipboard; TODO: catch the case where clipboard is empty + if(itemEnd != NULL && itemEnd->getRepr() != NULL){ + gchar const *svgd = item->getRepr()->attribute("d"); + item->deleteObject(); + Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); + selection->add(SP_OBJECT(itemEnd)); + sp_selection_duplicate(dc->desktop); + selection->remove(SP_OBJECT(itemEnd)); + GSList *items = const_cast(selection->itemList()); + SPObject *obj = reinterpret_cast(g_slist_nth_data(items,0)); + if(SP_IS_OBJECT(obj)){ + SP_ITEM(obj)->getRepr()->setAttribute("inkscape:path-effect", NULL); + spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); + SP_ITEM(obj)->setExplicitlyHidden(false); + selection->set(SP_ITEM(obj),true); } } - shape = previous_shape; + shape = previous_shape_type; + break; } default: break; } - previous_shape = shape; + previous_shape_type = shape; if (shape_applied) { // apply original stroke color as fill and unset stroke; then return SPCSSAttr *css = sp_repr_css_attr_new(); @@ -454,7 +424,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, sp_repr_css_attr_unref(css); return; } - if(shape == 5 || (shape == 6 && previous_shape == 5))return; + if(previous_shape_type == 5)return; if (dc->waiting_LPE_type != INVALID_LPE) { Effect::createAndApply(dc->waiting_LPE_type, dc->desktop->doc(), item); @@ -731,11 +701,11 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) // we finished the path; now apply any waiting LPEs or freehand shapes spdc_check_for_and_apply_waiting_LPE(dc, item, c); - if(!bend) dc->selection->set(repr); + if(previous_shape_type != 5) dc->selection->set(repr); Inkscape::GC::release(repr); - if(!bend) item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - if(!bend) item->doWriteTransform(item->getRepr(), item->transform, NULL, true); - if(!bend) item->updateRepr(); + if(previous_shape_type != 5) item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + if(previous_shape_type != 5) item->doWriteTransform(item->getRepr(), item->transform, NULL, true); + if(previous_shape_type != 5) item->updateRepr(); } DocumentUndo::done(doc, SP_IS_PEN_CONTEXT(dc)? SP_VERB_CONTEXT_PEN : SP_VERB_CONTEXT_PENCIL, -- cgit v1.2.3 From 63a8ebd9d68033c5ac23014ca325a8043f38733b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 24 Nov 2014 22:38:30 +0100 Subject: Fixing bend from clipboard to trunk 0.92 (bzr r12588.1.36) --- src/ui/tools/freehand-base.cpp | 48 ++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 68b57dc90..a452ae7c8 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -257,7 +257,7 @@ static void spdc_apply_powerstroke_shape(const std::vector & points std::ostringstream s; s.imbue(std::locale::classic()); - s << "0," << stroke_width / 2.; + s << points[0][Geom::X] << "," << stroke_width / 2.; // write powerstroke parameters: lpe->getRepr()->setAttribute("start_linecap_type", "zerowidth"); @@ -285,9 +285,11 @@ static void spdc_apply_bend_shape(gchar const *svgd, FreehandBase *dc, SPItem *i lpe->getRepr()->setAttribute("scale_y_rel", "false"); lpe->getRepr()->setAttribute("vertical", "false"); } -static int previous_shape_type = -1; -static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, SPCurve *curve) +enum shapeType { NONE, TRIANGLE_IN, TRIANGLE_OUT, ELLIPSE, CLIPBOARD, BEND_CLIPBOARD, LAST_APPLIED }; +static shapeType previous_shape_type = NONE; + +static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, SPCurve *curve) { using namespace Inkscape::LivePathEffect; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -304,8 +306,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, //Store the clipboard path to apply in the future without the use of clipboard static Geom::PathVector previous_shape_pathv; - enum shapeType { NONE, TRIANGLE_IN, TRIANGLE_OUT, ELLIPSE, CLIPBOARD, BEND_CLIPBOARD, LAST_APPLIED }; - static shapeType previous_shape_type = NONE; + shapeType shape = (shapeType)prefs->getInt(tool_name(dc) + "/shape", 0); @@ -385,14 +386,11 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if(cm->paste(SP_ACTIVE_DESKTOP,false) == true){ + item->transform = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2doc_affine().inverse(); gchar const *svgd = item->getRepr()->attribute("d"); - item->getRepr()->setAttribute("d", ""); bendItem = dc->selection->singleItem(); - item->setSuccessor(bendItem); - item = bendItem; - g_assert(item != NULL); - spdc_apply_bend_shape(svgd, dc, item); - dc->selection->set(item,true); + spdc_apply_bend_shape(svgd, dc, bendItem); + dc->selection->set(bendItem,true); } break; } @@ -407,30 +405,28 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, shape_applied = true; } + shape = CLIPBOARD; } else { if(bendItem != NULL && bendItem->getRepr() != NULL){ + item->transform = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2doc_affine().inverse(); gchar const *svgd = item->getRepr()->attribute("d"); - item->getRepr()->setAttribute("d", ""); Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); selection->add(SP_OBJECT(bendItem)); sp_selection_duplicate(dc->desktop); selection->remove(SP_OBJECT(bendItem)); bendItem = dc->selection->singleItem(); - item->setSuccessor(bendItem); - item = bendItem; - g_assert(item != NULL); - spdc_apply_bend_shape(svgd, dc, item); - dc->selection->set(item,true); + spdc_apply_bend_shape(svgd, dc, bendItem); + dc->selection->set(bendItem,true); } + shape = BEND_CLIPBOARD; } break; } default: break; } - if(shape != LAST_APPLIED){ - previous_shape_type = shape; - } + previous_shape_type = shape; + if (shape_applied) { // apply original stroke color as fill and unset stroke; then return SPCSSAttr *css = sp_repr_css_attr_new(); @@ -445,7 +441,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, sp_repr_css_attr_unref(css); return; } - if(previous_shape_type == 5 || previous_shape_type == 6 || previous_shape_type == 7){ + if(previous_shape_type == LAST_APPLIED){ return; } if (dc->waiting_LPE_type != INVALID_LPE) { @@ -754,19 +750,17 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) // Attach repr SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr)); - // we finished the path; now apply any waiting LPEs or freehand shapes spdc_check_for_and_apply_waiting_LPE(dc, item, c); - if(previous_shape_type == -1 || previous_shape_type == 5 || previous_shape_type == 6){ - return; - } - if(previous_shape_type != 7){ + if(previous_shape_type != BEND_CLIPBOARD){ dc->selection->set(repr); } - Inkscape::GC::release(repr); item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); item->updateRepr(); item->doWriteTransform(item->getRepr(), item->transform, NULL, true); + if(previous_shape_type == BEND_CLIPBOARD){ + repr->parent()->removeChild(repr); + } } DocumentUndo::done(doc, SP_IS_PEN_CONTEXT(dc)? SP_VERB_CONTEXT_PEN : SP_VERB_CONTEXT_PENCIL, -- cgit v1.2.3 From dde5cc0fe6c8f4c00711813baeca5ae1d0d671c6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 25 Nov 2014 00:16:06 +0100 Subject: updated code to work on 0.92 code (bzr r12588.1.38) --- src/ui/tools/freehand-base.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index a452ae7c8..2ef06df61 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -385,12 +385,16 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, case BEND_CLIPBOARD: { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); - if(cm->paste(SP_ACTIVE_DESKTOP,false) == true){ + if(cm->paste(SP_ACTIVE_DESKTOP,true) == true){ item->transform = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2doc_affine().inverse(); gchar const *svgd = item->getRepr()->attribute("d"); bendItem = dc->selection->singleItem(); + bendItem->moveTo(item,false); spdc_apply_bend_shape(svgd, dc, bendItem); - dc->selection->set(bendItem,true); + bendItem->transform = Geom::Affine(1,0,0,1,0,0); + dc->selection->add(SP_OBJECT(bendItem)); + } else { + shape = NONE; } break; } @@ -410,13 +414,14 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if(bendItem != NULL && bendItem->getRepr() != NULL){ item->transform = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2doc_affine().inverse(); gchar const *svgd = item->getRepr()->attribute("d"); - Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); - selection->add(SP_OBJECT(bendItem)); + dc->selection->add(SP_OBJECT(bendItem)); sp_selection_duplicate(dc->desktop); - selection->remove(SP_OBJECT(bendItem)); + dc->selection->remove(SP_OBJECT(bendItem)); bendItem = dc->selection->singleItem(); + bendItem->moveTo(item,false); spdc_apply_bend_shape(svgd, dc, bendItem); - dc->selection->set(bendItem,true); + bendItem->transform = Geom::Affine(1,0,0,1,0,0); + dc->selection->add(SP_OBJECT(bendItem)); } shape = BEND_CLIPBOARD; } @@ -441,9 +446,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, sp_repr_css_attr_unref(css); return; } - if(previous_shape_type == LAST_APPLIED){ - return; - } + if (dc->waiting_LPE_type != INVALID_LPE) { Effect::createAndApply(dc->waiting_LPE_type, dc->desktop->doc(), item); dc->waiting_LPE_type = INVALID_LPE; -- cgit v1.2.3 From e2d2279032ac0e7c1767551ac3d9bed7a94388bd Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 27 Jan 2015 23:09:47 +0100 Subject: Create a empty LPE (bzr r13879.1.1) --- src/live_effects/CMakeLists.txt | 2 ++ src/live_effects/Makefile_insert | 2 ++ src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 5 ++++ src/live_effects/lpe-transform_2pts.cpp | 47 +++++++++++++++++++++++++++++++ src/live_effects/lpe-transform_2pts.h | 49 +++++++++++++++++++++++++++++++++ 6 files changed, 106 insertions(+) create mode 100644 src/live_effects/lpe-transform_2pts.cpp create mode 100644 src/live_effects/lpe-transform_2pts.h (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index c8a02c810..5ab6d0ee4 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -7,6 +7,7 @@ set(live_effects_SRC lpe-boolops.cpp lpe-bounding-box.cpp lpe-circle_3pts.cpp + lpe-transform_2pts.cpp lpe-circle_with_radius.cpp lpe-clone-original.cpp lpe-constructgrid.cpp @@ -81,6 +82,7 @@ set(live_effects_SRC lpe-boolops.h lpe-bounding-box.h lpe-circle_3pts.h + lpe-transform_2pts.h lpe-circle_with_radius.h lpe-clone-original.h lpe-constructgrid.h diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 8f0a3ac57..fe85d28cf 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -76,6 +76,8 @@ ink_common_sources += \ live_effects/lpe-mirror_symmetry.h \ live_effects/lpe-circle_3pts.cpp \ live_effects/lpe-circle_3pts.h \ + live_effects/lpe-transform_2pts.cpp \ + live_effects/lpe-transform_2pts.h \ live_effects/lpe-angle_bisector.cpp \ live_effects/lpe-angle_bisector.h \ live_effects/lpe-parallel.cpp \ diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 383eec19e..eea26184c 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -38,6 +38,7 @@ enum EffectType { TANGENT_TO_CURVE, MIRROR_SYMMETRY, CIRCLE_3PTS, + TRANSFORM_2PTS, ANGLE_BISECTOR, PARALLEL, COPY_ROTATE, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 827f70749..48fc788fa 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -38,6 +38,7 @@ #include "live_effects/lpe-tangent_to_curve.h" #include "live_effects/lpe-mirror_symmetry.h" #include "live_effects/lpe-circle_3pts.h" +#include "live_effects/lpe-transform_2pts.h" #include "live_effects/lpe-angle_bisector.h" #include "live_effects/lpe-parallel.h" #include "live_effects/lpe-copy_rotate.h" @@ -153,6 +154,7 @@ const Util::EnumData LPETypeData[] = { {PERSPECTIVE_ENVELOPE, N_("Perspective/Envelope"), "perspective-envelope"}, {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet-chamfer"}, {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"}, + {TRANSFORM_2PTS, N_("Transform by 2 points"), "transform_2pts"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -321,6 +323,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case SHOW_HANDLES: neweffect = static_cast ( new LPEShowHandles(lpeobj) ); break; + case TRANSFORM_2PTS: + neweffect = static_cast ( new LPETransform2Pts(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp new file mode 100644 index 000000000..95555b80e --- /dev/null +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -0,0 +1,47 @@ +/** \file + * LPE "Transform through 2 points" implementation + */ + +/* + * Authors: + * + * + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-transform_2pts.h" + +namespace Inkscape { +namespace LivePathEffect { + +LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : + Effect(lpeobject) +{ +} + +LPETransform2Pts::~LPETransform2Pts() +{ +} + +std::vector +LPETransform2Pts::doEffect_path (std::vector const & path_in) +{ + return path_in; +} + +/* ######################## */ + +} //namespace LivePathEffect +} /* namespace Inkscape */ + +/* + 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 : diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h new file mode 100644 index 000000000..a1a20535a --- /dev/null +++ b/src/live_effects/lpe-transform_2pts.h @@ -0,0 +1,49 @@ +#ifndef INKSCAPE_LPE_TRANSFORM_2PTS_H +#define INKSCAPE_LPE_TRANSFORM_2PTS_H + +/** \file + * LPE "Transform through 2 points" implementation + */ + +/* + * Authors: + * + * + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/point.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPETransform2Pts : public Effect { +public: + LPETransform2Pts(LivePathEffectObject *lpeobject); + virtual ~LPETransform2Pts(); + + virtual std::vector doEffect_path (std::vector const & path_in); + +private: + LPETransform2Pts(const LPETransform2Pts&); + LPETransform2Pts& operator=(const LPETransform2Pts&); +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif + +/* + 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 : -- cgit v1.2.3 From c75f15ce27ce08091e85c1d23b0e3d9bbd9aa13c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 1 Feb 2015 20:37:22 +0100 Subject: adde parameter to select knot node position (bzr r13879.1.4) --- src/live_effects/lpe-transform_2pts.cpp | 108 +++++++++++++++++++++++++++++--- src/live_effects/lpe-transform_2pts.h | 15 ++++- 2 files changed, 112 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 142070578..bb126b2bb 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -33,11 +33,18 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : Effect(lpeobject), fromOriginalWidth(_("Use bounding box"), _("Use bounding box"), "fromOriginalWidth", &wr, this, false), start(_("Start"), _("Start point"), "start", &wr, this, "Start point"), - end(_("End"), _("End point"), "end", &wr, this, "End point") + end(_("End"), _("End point"), "end", &wr, this, "End point"), + firstKnot(_("First Knot"), _("First Knot"), "firstKnot", &wr, this, 1), + lastKnot(_("Last Knot"), _("Last Knot"), "lastKnot", &wr, this, 1) { - registerParameter(&fromOriginalWidth); registerParameter(&start); registerParameter(&end); + registerParameter(&firstKnot); + registerParameter(&lastKnot); + registerParameter(&fromOriginalWidth); + + firstKnot.param_make_integer(true); + lastKnot.param_make_integer(true); } LPETransform2Pts::~LPETransform2Pts() @@ -60,6 +67,8 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) if(!c->is_closed() && c->first_path() == c->last_path()){ A = *(c->first_point()); B = *(c->last_point()); + int nnodes = (int)c->nodes_in_path(); + lastKnot.param_set_value((int)c->nodes_in_path()); } } start.param_setValue(A); @@ -73,25 +82,93 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) original_bbox(lpeitem); SPLPEItem* item = const_cast(lpeitem); SPPath *path = dynamic_cast(item); - if(fromOriginalWidth || !path ){ - A = Point(boundingbox_X.min(), boundingbox_Y.middle()); - B = Point(boundingbox_X.max(), boundingbox_Y.middle()); - } + A = Point(boundingbox_X.min(), boundingbox_Y.middle()); + B = Point(boundingbox_X.max(), boundingbox_Y.middle()); if(path && !fromOriginalWidth){ SPCurve * c = NULL; c = path->get_original_curve(); - if(!c->is_closed()){ - A = *(c->first_point()); - B = *(c->last_point()); + if(!c->is_closed() && c->first_path() == c->last_path()){ + Geom::PathVector const originalPV = c->get_pathvector(); + A = originalPV[0][0].initialPoint(); + if((int)firstKnot > 1){ + A = originalPV[0][(int)firstKnot-2].finalPoint(); + } + B = originalPV[0][0].initialPoint(); + if((int)lastKnot > 1){ + B = originalPV[0][(int)lastKnot-2].finalPoint(); + } + int nnodes = (int)c->nodes_in_path(); + firstKnot.param_set_range(1, lastKnot-1); + lastKnot.param_set_range(firstKnot+1, nnodes); + } else { + firstKnot.param_set_value(1); + lastKnot.param_set_value(2); + firstKnot.param_set_range(1,1); + lastKnot.param_set_range(2,2); } + } else { + firstKnot.param_set_value(1); + lastKnot.param_set_value(2); + firstKnot.param_set_range(1,1); + lastKnot.param_set_range(2,2); } item->apply_to_clippath(item); item->apply_to_mask(item); } void -LPETransform2Pts::reset () +LPETransform2Pts::updateIndex() +{ + SPPath *path = dynamic_cast(sp_lpe_item); + if(path && !fromOriginalWidth){ + SPCurve * c = NULL; + c = path->get_original_curve(); + int nnodes = (int)c->nodes_in_path(); + if(!c->is_closed() && c->first_path() == c->last_path()){ + c->reset(); + c = path->getCurve(); + Geom::PathVector const originalPV = c->get_pathvector(); + Geom::Point C = originalPV[0][0].initialPoint(); + Geom::Point D = originalPV[0][0].initialPoint(); + if((int)firstKnot > 1){ + C = originalPV[0][(int)firstKnot-2].finalPoint(); + } + if((int)lastKnot > 1){ + D = originalPV[0][(int)lastKnot-2].finalPoint(); + } + start.param_update_default(C); + start.param_set_and_write_default(); + end.param_update_default(D); + end.param_set_and_write_default(); + start.param_update_default(A); + end.param_update_default(B); + start.param_set_and_write_default(); + end.param_set_and_write_default(); + SPDesktop * desktop = SP_ACTIVE_DESKTOP; + tools_switch(desktop, TOOLS_SELECT); + tools_switch(desktop, TOOLS_NODES); + } + } +} + +void +LPETransform2Pts::reset() { + SPPath *path = dynamic_cast(sp_lpe_item); + A = Geom::Point(boundingbox_X.min(), boundingbox_Y.middle()); + B = Geom::Point(boundingbox_X.max(), boundingbox_Y.middle()); + if(path && !fromOriginalWidth){ + SPCurve * c = NULL; + c = path->get_original_curve(); + int nnodes = (int)c->nodes_in_path(); + firstKnot.param_set_value(1); + lastKnot.param_set_value(nnodes); + A = *(c->first_point()); + B = *(c->last_point()); + } else { + firstKnot.param_set_value(1); + lastKnot.param_set_value(2); + } start.param_update_default(A); end.param_update_default(B); start.param_set_and_write_default(); @@ -118,6 +195,17 @@ Gtk::Widget *LPETransform2Pts::newWidget() Parameter *param = *it; Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); Glib::ustring *tip = param->param_getTooltip(); + if (param->param_key == "firstKnot" || param->param_key == "lastKnot") { + Inkscape::UI::Widget::Scalar *widgRegistered = Gtk::manage(dynamic_cast(widg)); + widgRegistered->signal_value_changed().connect(sigc::mem_fun(*this, &LPETransform2Pts::updateIndex)); + widg = widgRegistered; + if (widg) { + Gtk::HBox *scalarParameter = dynamic_cast(widg); + std::vector childList = scalarParameter->get_children(); + Gtk::Entry *entryWidg = dynamic_cast(childList[1]); + entryWidg->set_width_chars(3); + } + } if (widg) { vbox->pack_start(*widg, true, true, 2); if (tip) { diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index 271dec191..095f27472 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -13,6 +13,16 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#if defined(GLIBMM_DISABLE_DEPRECATED) && defined(HAVE_GLIBMM_THREADS_H) +# include +#endif + +#include "ui/widget/registered-widget.h" + #include "live_effects/effect.h" #include "live_effects/parameter/pointreseteable.h" #include "live_effects/lpegroupbbox.h" @@ -31,6 +41,8 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); + void updateIndex(); + virtual Gtk::Widget *newWidget(); virtual void reset(); @@ -42,7 +54,8 @@ private: BoolParam fromOriginalWidth; PointReseteableParam start; PointReseteableParam end; - + ScalarParam firstKnot; + ScalarParam lastKnot; Geom::Point A; Geom::Point B; -- cgit v1.2.3 From d9e84828804bef871c833e6b749a826f29c0e153 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 2 Feb 2015 22:59:36 +0100 Subject: Fix some problems pointed by su_v (bzr r13879.1.7) --- src/live_effects/lpe-transform_2pts.cpp | 35 +++++++++++++++++++++++++-------- src/live_effects/lpe-transform_2pts.h | 5 ++++- 2 files changed, 31 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index bb126b2bb..049212302 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -23,7 +23,7 @@ #include <2geom/path.h> #include "sp-path.h" #include "ui/tools-switch.h" - +#include "ui/icon-names.h" #include "inkscape.h" namespace Inkscape { @@ -31,7 +31,7 @@ namespace LivePathEffect { LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : Effect(lpeobject), - fromOriginalWidth(_("Use bounding box"), _("Use bounding box"), "fromOriginalWidth", &wr, this, false), + fromOriginalWidth(_("From original width"), _("From original width"), "fromOriginalWidth", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), start(_("Start"), _("Start point"), "start", &wr, this, "Start point"), end(_("End"), _("End point"), "end", &wr, this, "End point"), firstKnot(_("First Knot"), _("First Knot"), "firstKnot", &wr, this, 1), @@ -68,7 +68,7 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) A = *(c->first_point()); B = *(c->last_point()); int nnodes = (int)c->nodes_in_path(); - lastKnot.param_set_value((int)c->nodes_in_path()); + lastKnot.param_set_value(nnodes); } } start.param_setValue(A); @@ -79,6 +79,10 @@ void LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; + if(fromOriginalWidthToogler != fromOriginalWidth){ + fromOriginalWidthToogler = fromOriginalWidth; + reset(); + } original_bbox(lpeitem); SPLPEItem* item = const_cast(lpeitem); SPPath *path = dynamic_cast(item); @@ -100,17 +104,20 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) int nnodes = (int)c->nodes_in_path(); firstKnot.param_set_range(1, lastKnot-1); lastKnot.param_set_range(firstKnot+1, nnodes); + fromOriginalWidth.param_setValue(false); } else { firstKnot.param_set_value(1); lastKnot.param_set_value(2); firstKnot.param_set_range(1,1); lastKnot.param_set_range(2,2); + fromOriginalWidth.param_setValue(true); } } else { firstKnot.param_set_value(1); lastKnot.param_set_value(2); firstKnot.param_set_range(1,1); lastKnot.param_set_range(2,2); + fromOriginalWidth.param_setValue(true); } item->apply_to_clippath(item); item->apply_to_mask(item); @@ -123,7 +130,6 @@ LPETransform2Pts::updateIndex() if(path && !fromOriginalWidth){ SPCurve * c = NULL; c = path->get_original_curve(); - int nnodes = (int)c->nodes_in_path(); if(!c->is_closed() && c->first_path() == c->last_path()){ c->reset(); c = path->getCurve(); @@ -161,6 +167,8 @@ LPETransform2Pts::reset() SPCurve * c = NULL; c = path->get_original_curve(); int nnodes = (int)c->nodes_in_path(); + firstKnot.param_set_range(1, lastKnot-1); + lastKnot.param_set_range(firstKnot+1, nnodes); firstKnot.param_set_value(1); lastKnot.param_set_value(nnodes); A = *(c->first_point()); @@ -189,7 +197,7 @@ Gtk::Widget *LPETransform2Pts::newWidget() vbox->set_spacing(6); std::vector::iterator it = param_vector.begin(); - + Gtk::HBox * button = Gtk::manage(new Gtk::HBox(true,0)); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { Parameter *param = *it; @@ -206,6 +214,19 @@ Gtk::Widget *LPETransform2Pts::newWidget() entryWidg->set_width_chars(3); } } + if (param->param_key == "fromOriginalWidth") + { + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + button->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } if (widg) { vbox->pack_start(*widg, true, true, 2); if (tip) { @@ -219,11 +240,9 @@ Gtk::Widget *LPETransform2Pts::newWidget() ++it; } - Gtk::HBox * button = Gtk::manage(new Gtk::HBox(true,0)); Gtk::Button *reset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset")))); reset->signal_clicked().connect(sigc::mem_fun(*this, &LPETransform2Pts::reset)); - reset->set_size_request(140,45); - button->pack_start(*reset, false, false, 2); + button->pack_start(*reset, true, true, 2); vbox->pack_start(*button, true, true, 2); return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index 095f27472..5a29802be 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -24,6 +24,7 @@ #include "ui/widget/registered-widget.h" #include "live_effects/effect.h" +#include "live_effects/parameter/togglebutton.h" #include "live_effects/parameter/pointreseteable.h" #include "live_effects/lpegroupbbox.h" @@ -51,7 +52,7 @@ protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); private: - BoolParam fromOriginalWidth; + ToggleButtonParam fromOriginalWidth; PointReseteableParam start; PointReseteableParam end; ScalarParam firstKnot; @@ -59,6 +60,8 @@ private: Geom::Point A; Geom::Point B; + bool fromOriginalWidthToogler; + LPETransform2Pts(const LPETransform2Pts&); LPETransform2Pts& operator=(const LPETransform2Pts&); }; -- cgit v1.2.3 From dd7b327403513170b6ab3fb4413dd90b61d91157 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 5 Feb 2015 00:00:49 +0100 Subject: fixing bugs on reset function (bzr r13879.1.8) --- src/live_effects/lpe-transform_2pts.cpp | 139 ++++++++++++++++++-------------- src/live_effects/lpe-transform_2pts.h | 18 +---- 2 files changed, 81 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 049212302..cb5180f4d 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -10,14 +10,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include -#endif - #include #include "live_effects/lpe-transform_2pts.h" -#include #include "display/curve.h" #include <2geom/transforms.h> #include <2geom/path.h> @@ -26,6 +21,8 @@ #include "ui/icon-names.h" #include "inkscape.h" +#include + namespace Inkscape { namespace LivePathEffect { @@ -35,7 +32,10 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : start(_("Start"), _("Start point"), "start", &wr, this, "Start point"), end(_("End"), _("End point"), "end", &wr, this, "End point"), firstKnot(_("First Knot"), _("First Knot"), "firstKnot", &wr, this, 1), - lastKnot(_("Last Knot"), _("Last Knot"), "lastKnot", &wr, this, 1) + lastKnot(_("Last Knot"), _("Last Knot"), "lastKnot", &wr, this, 1), + fromOriginalWidthToogler(true), + A(Geom::Point(0,0)), + B(Geom::Point(0,0)) { registerParameter(&start); registerParameter(&end); @@ -59,38 +59,40 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) A = Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Point(boundingbox_X.max(), boundingbox_Y.middle()); - SPLPEItem* item = const_cast(lpeitem); - SPPath *path = dynamic_cast(item); + SPLPEItem * splpeitem = const_cast(lpeitem); + SPCurve * c = NULL; + SPPath *path = dynamic_cast(splpeitem); if (path) { - SPCurve * c = NULL; c = path->get_original_curve(); - if(!c->is_closed() && c->first_path() == c->last_path()){ - A = *(c->first_point()); - B = *(c->last_point()); - int nnodes = (int)c->nodes_in_path(); - lastKnot.param_set_value(nnodes); - } } - start.param_setValue(A); - end.param_setValue(B); + if(c && !c->is_closed() && c->first_path() == c->last_path()){ + A = *(c->first_point()); + B = *(c->last_point()); + int nnodes = (int)c->nodes_in_path(); + lastKnot.param_set_value(nnodes); + } + start.param_update_default(A); + start.param_set_and_write_default(); + end.param_update_default(B); + end.param_set_and_write_default(); } void LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - if(fromOriginalWidthToogler != fromOriginalWidth){ - fromOriginalWidthToogler = fromOriginalWidth; - reset(); - } + original_bbox(lpeitem); - SPLPEItem* item = const_cast(lpeitem); - SPPath *path = dynamic_cast(item); A = Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Point(boundingbox_X.max(), boundingbox_Y.middle()); - if(path && !fromOriginalWidth){ - SPCurve * c = NULL; + + SPLPEItem * splpeitem = const_cast(lpeitem); + SPCurve * c = NULL; + SPPath *path = dynamic_cast(splpeitem); + if (path) { c = path->get_original_curve(); + } + if(c && !fromOriginalWidth){ if(!c->is_closed() && c->first_path() == c->last_path()){ Geom::PathVector const originalPV = c->get_pathvector(); A = originalPV[0][0].initialPoint(); @@ -119,53 +121,62 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) lastKnot.param_set_range(2,2); fromOriginalWidth.param_setValue(true); } - item->apply_to_clippath(item); - item->apply_to_mask(item); + if(fromOriginalWidthToogler != fromOriginalWidth){ + fromOriginalWidthToogler = fromOriginalWidth; + reset(); + } + splpeitem->apply_to_clippath(splpeitem); + splpeitem->apply_to_mask(splpeitem); } void LPETransform2Pts::updateIndex() { - SPPath *path = dynamic_cast(sp_lpe_item); - if(path && !fromOriginalWidth){ - SPCurve * c = NULL; - c = path->get_original_curve(); - if(!c->is_closed() && c->first_path() == c->last_path()){ - c->reset(); - c = path->getCurve(); - Geom::PathVector const originalPV = c->get_pathvector(); - Geom::Point C = originalPV[0][0].initialPoint(); - Geom::Point D = originalPV[0][0].initialPoint(); - if((int)firstKnot > 1){ - C = originalPV[0][(int)firstKnot-2].finalPoint(); - } - if((int)lastKnot > 1){ - D = originalPV[0][(int)lastKnot-2].finalPoint(); - } - start.param_update_default(C); - start.param_set_and_write_default(); - end.param_update_default(D); - end.param_set_and_write_default(); - start.param_update_default(A); - end.param_update_default(B); - start.param_set_and_write_default(); - end.param_set_and_write_default(); - SPDesktop * desktop = SP_ACTIVE_DESKTOP; - tools_switch(desktop, TOOLS_SELECT); - tools_switch(desktop, TOOLS_NODES); + SPCurve * c = NULL; + SPCurve * c2 = NULL; + SPShape *shape = SP_SHAPE(sp_lpe_item); + if (shape) { + c = shape->getCurve(); + SPPath *path = dynamic_cast(shape); + if (path) { + c2 = path->get_original_curve(); + } + } + if(c && c2 && !fromOriginalWidth && !c2->is_closed() && c2->first_path() == c2->last_path()){ + Geom::PathVector const originalPV = c->get_pathvector(); + Geom::Point C = originalPV[0][0].initialPoint(); + Geom::Point D = originalPV[0][0].initialPoint(); + if((int)firstKnot > 1){ + C = originalPV[0][(int)firstKnot-2].finalPoint(); + } + if((int)lastKnot > 1){ + D = originalPV[0][(int)lastKnot-2].finalPoint(); } + start.param_update_default(C); + start.param_set_and_write_default(); + end.param_update_default(D); + end.param_set_and_write_default(); + start.param_update_default(A); + end.param_update_default(B); + start.param_set_and_write_default(); + end.param_set_and_write_default(); + SPDesktop * desktop = SP_ACTIVE_DESKTOP; + tools_switch(desktop, TOOLS_SELECT); + tools_switch(desktop, TOOLS_NODES); } } void LPETransform2Pts::reset() { - SPPath *path = dynamic_cast(sp_lpe_item); A = Geom::Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Geom::Point(boundingbox_X.max(), boundingbox_Y.middle()); - if(path && !fromOriginalWidth){ - SPCurve * c = NULL; + SPCurve * c = NULL; + SPPath *path = dynamic_cast(sp_lpe_item); + if (path) { c = path->get_original_curve(); + } + if(c && !fromOriginalWidth){ int nnodes = (int)c->nodes_in_path(); firstKnot.param_set_range(1, lastKnot-1); lastKnot.param_set_range(firstKnot+1, nnodes); @@ -212,10 +223,15 @@ Gtk::Widget *LPETransform2Pts::newWidget() std::vector childList = scalarParameter->get_children(); Gtk::Entry *entryWidg = dynamic_cast(childList[1]); entryWidg->set_width_chars(3); + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } } - } - if (param->param_key == "fromOriginalWidth") - { + } else if (param->param_key == "fromOriginalWidth"){ Glib::ustring * tip = param->param_getTooltip(); if (widg) { button->pack_start(*widg, true, true, 2); @@ -226,8 +242,7 @@ Gtk::Widget *LPETransform2Pts::newWidget() widg->set_has_tooltip(false); } } - } - if (widg) { + } else if (widg) { vbox->pack_start(*widg, true, true, 2); if (tip) { widg->set_tooltip_text(*tip); diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index 5a29802be..90fc572e0 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -13,20 +13,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#if defined(GLIBMM_DISABLE_DEPRECATED) && defined(HAVE_GLIBMM_THREADS_H) -# include -#endif - -#include "ui/widget/registered-widget.h" - #include "live_effects/effect.h" +#include "live_effects/lpegroupbbox.h" +#include "live_effects/parameter/parameter.h" #include "live_effects/parameter/togglebutton.h" #include "live_effects/parameter/pointreseteable.h" -#include "live_effects/lpegroupbbox.h" namespace Inkscape { namespace LivePathEffect { @@ -42,7 +33,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - void updateIndex(); + virtual void updateIndex(); virtual Gtk::Widget *newWidget(); @@ -57,11 +48,10 @@ private: PointReseteableParam end; ScalarParam firstKnot; ScalarParam lastKnot; + bool fromOriginalWidthToogler; Geom::Point A; Geom::Point B; - bool fromOriginalWidthToogler; - LPETransform2Pts(const LPETransform2Pts&); LPETransform2Pts& operator=(const LPETransform2Pts&); }; -- cgit v1.2.3 From 56acf863aae3ec2f54ef049698489e65f0356e22 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 5 Feb 2015 02:39:07 +0100 Subject: fixed bugs pointed by su_v (bzr r13879.1.9) --- src/live_effects/lpe-transform_2pts.cpp | 43 +++++++++++++++------------------ src/live_effects/lpe-transform_2pts.h | 7 +++--- 2 files changed, 23 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index cb5180f4d..5a7d1b16d 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -33,9 +33,11 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : end(_("End"), _("End point"), "end", &wr, this, "End point"), firstKnot(_("First Knot"), _("First Knot"), "firstKnot", &wr, this, 1), lastKnot(_("Last Knot"), _("Last Knot"), "lastKnot", &wr, this, 1), - fromOriginalWidthToogler(true), + fromOriginalWidthToogler(false), A(Geom::Point(0,0)), - B(Geom::Point(0,0)) + B(Geom::Point(0,0)), + c(NULL), + appandedPath(false) { registerParameter(&start); registerParameter(&end); @@ -60,7 +62,6 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) A = Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Point(boundingbox_X.max(), boundingbox_Y.middle()); SPLPEItem * splpeitem = const_cast(lpeitem); - SPCurve * c = NULL; SPPath *path = dynamic_cast(splpeitem); if (path) { c = path->get_original_curve(); @@ -81,19 +82,22 @@ void LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); A = Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Point(boundingbox_X.max(), boundingbox_Y.middle()); SPLPEItem * splpeitem = const_cast(lpeitem); - SPCurve * c = NULL; SPPath *path = dynamic_cast(splpeitem); if (path) { c = path->get_original_curve(); } + if(fromOriginalWidthToogler != fromOriginalWidth){ + fromOriginalWidthToogler = fromOriginalWidth; + reset(); + } if(c && !fromOriginalWidth){ if(!c->is_closed() && c->first_path() == c->last_path()){ + appandedPath = false; Geom::PathVector const originalPV = c->get_pathvector(); A = originalPV[0][0].initialPoint(); if((int)firstKnot > 1){ @@ -112,7 +116,11 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) lastKnot.param_set_value(2); firstKnot.param_set_range(1,1); lastKnot.param_set_range(2,2); - fromOriginalWidth.param_setValue(true); + if(appandedPath == false){ + appandedPath = true; + } else { + fromOriginalWidth.param_setValue(true); + } } } else { firstKnot.param_set_value(1); @@ -120,10 +128,7 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) firstKnot.param_set_range(1,1); lastKnot.param_set_range(2,2); fromOriginalWidth.param_setValue(true); - } - if(fromOriginalWidthToogler != fromOriginalWidth){ - fromOriginalWidthToogler = fromOriginalWidth; - reset(); + appandedPath = false; } splpeitem->apply_to_clippath(splpeitem); splpeitem->apply_to_mask(splpeitem); @@ -132,18 +137,13 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) void LPETransform2Pts::updateIndex() { - SPCurve * c = NULL; SPCurve * c2 = NULL; SPShape *shape = SP_SHAPE(sp_lpe_item); if (shape) { - c = shape->getCurve(); - SPPath *path = dynamic_cast(shape); - if (path) { - c2 = path->get_original_curve(); - } + c2 = shape->getCurve(); } - if(c && c2 && !fromOriginalWidth && !c2->is_closed() && c2->first_path() == c2->last_path()){ - Geom::PathVector const originalPV = c->get_pathvector(); + if(c2 && !fromOriginalWidth && !c->is_closed() && c->first_path() == c->last_path()){ + Geom::PathVector const originalPV = c2->get_pathvector(); Geom::Point C = originalPV[0][0].initialPoint(); Geom::Point D = originalPV[0][0].initialPoint(); if((int)firstKnot > 1){ @@ -171,12 +171,7 @@ LPETransform2Pts::reset() { A = Geom::Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Geom::Point(boundingbox_X.max(), boundingbox_Y.middle()); - SPCurve * c = NULL; - SPPath *path = dynamic_cast(sp_lpe_item); - if (path) { - c = path->get_original_curve(); - } - if(c && !fromOriginalWidth){ + if(c && !c->is_closed() && c->first_path() == c->last_path() && !fromOriginalWidth){ int nnodes = (int)c->nodes_in_path(); firstKnot.param_set_range(1, lastKnot-1); lastKnot.param_set_range(firstKnot+1, nnodes); diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index 90fc572e0..fdedf8af0 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -33,11 +33,11 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void updateIndex(); + void updateIndex(); virtual Gtk::Widget *newWidget(); - virtual void reset(); + void reset(); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); @@ -51,7 +51,8 @@ private: bool fromOriginalWidthToogler; Geom::Point A; Geom::Point B; - + SPCurve * c; + bool appandedPath; LPETransform2Pts(const LPETransform2Pts&); LPETransform2Pts& operator=(const LPETransform2Pts&); }; -- cgit v1.2.3 From 2a0d24e61c826a9bf33cad4c8f6769d52d433b43 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 8 Mar 2015 00:13:15 +0100 Subject: add interactive smooth to pen tool (bzr r13973.1.1) --- src/ui/tools/freehand-base.cpp | 26 ++++++++++++++++++++++++++ src/ui/tools/pencil-tool.cpp | 14 ++++++++++---- src/widgets/pencil-toolbar.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/widgets/toolbox.cpp | 2 ++ 4 files changed, 80 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 0f14d7534..5858bfcfd 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -21,6 +21,7 @@ #endif #include "live_effects/lpe-patternalongpath.h" +#include "live_effects/lpe-simplify.h" #include "display/canvas-bpath.h" #include "xml/repr.h" #include "svg/svg.h" @@ -266,6 +267,23 @@ static void spdc_apply_powerstroke_shape(const std::vector & points lpe->getRepr()->setAttribute("offset_points", s.str().c_str()); } +static void spdc_apply_simplify(std::string threshold, FreehandBase *dc, SPItem *item) +{ + using namespace Inkscape::LivePathEffect; + + Effect::createAndApply(SIMPLIFY, dc->desktop->doc(), item); + Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); + // write powerstroke parameters: + lpe->getRepr()->setAttribute("steps", "1"); + lpe->getRepr()->setAttribute("threshold", threshold); + lpe->getRepr()->setAttribute("Helper size", "0"); + lpe->getRepr()->setAttribute("smooth_angles", "360"); + lpe->getRepr()->setAttribute("nodes", "false"); + lpe->getRepr()->setAttribute("handles", "false"); + lpe->getRepr()->setAttribute("simplifyindividualpaths", "false"); + lpe->getRepr()->setAttribute("simplifyJustCoalesce", "false"); +} + static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, SPCurve *curve) { using namespace Inkscape::LivePathEffect; @@ -287,6 +305,14 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, shapeType shape = (shapeType)prefs->getInt(tool_name(dc) + "/shape", 0); + bool simplify = prefs->getInt(tool_name(dc) + "/simplify", 0); + if(simplify){ + double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); + tol = tol/(100.0*(101.0-tol)); + std::ostringstream ss; + ss << tol; + spdc_apply_simplify(ss.str(), dc, item); + } bool shape_applied = false; SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); const char *cstroke = sp_repr_css_property(css_item, "stroke", "none"); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index db24c7432..e30bb3a7a 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -637,8 +637,11 @@ void PencilTool::_interpolate() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4; - double const tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2); - + double tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2); + bool simplify = prefs->getInt("/tools/freehand/pencil/simplify", 0); + if(simplify){ + tolerance_sq = 0; + } g_assert(is_zero(this->req_tangent) || is_unit_vector(this->req_tangent)); this->green_curve->reset(); @@ -705,8 +708,11 @@ void PencilTool::_sketchInterpolate() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4; - double const tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2); - + double tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2); + bool simplify = prefs->getInt("/tools/freehand/pencil/simplify", 0); + if(simplify){ + tolerance_sq = 0; + } bool average_all_sketches = prefs->getBool("/tools/freehand/pencil/average_all_sketches", true); g_assert(is_zero(this->req_tangent) || is_unit_vector(this->req_tangent)); diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index 1214a378a..43d73dbc6 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -28,6 +28,7 @@ # include "config.h" #endif +#include #include #include "pencil-toolbar.h" @@ -43,6 +44,11 @@ #include "ui/tools/pen-tool.h" #include "ui/uxmanager.h" #include "widgets/spinbutton-events.h" +#include +#include "live_effects/lpe-simplify.h" +#include "live_effects/effect-enum.h" +#include "live_effects/lpeobject.h" +#include "sp-lpe-item.h" using Inkscape::UI::UXManager; using Inkscape::DocumentUndo; @@ -151,6 +157,12 @@ static void freehand_change_shape(EgeSelectOneAction* act, GObject *dataKludge) prefs->setInt(freehand_tool_name(dataKludge) + "/shape", shape); } +static void freehand_simplify_lpe(InkToggleAction* itact, GObject *dataKludge) { + gint simplify = gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(itact) ); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt(freehand_tool_name(dataKludge) + "/simplify", simplify); +} + /** * Generate the list of freehand advanced shape option entries. */ @@ -232,6 +244,24 @@ static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tb prefs->setDouble("/tools/freehand/pencil/tolerance", gtk_adjustment_get_value(adj)); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); + SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop")); + SPItem * item = desktop->getSelection()->singleItem(); + if(item){ + SPLPEItem* lpeitem = dynamic_cast(item); + if (lpeitem && lpeitem->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY); + if(thisEffect){ + Inkscape::LivePathEffect::LPESimplify *lpe = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + if (lpe) { + double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); + tol = tol/(100.0*(101.0-tol)); + std::ostringstream ss; + ss << tol; + lpe->getRepr()->setAttribute("threshold", ss.str()); + } + } + } + } } /* @@ -303,6 +333,18 @@ void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_pencil_tb_defaults), holder ); gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); } + /* LPE simplify based tolerance */ + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + InkToggleAction* itact = ink_toggle_action_new( "PencilLpeSimplify", + _("LPE based interactive simplify"), + _("LPE based interactive simplify"), + INKSCAPE_ICON("interactive_simplify"), + Inkscape::ICON_SIZE_DECORATION ); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(itact), prefs->getInt("/tools/freehand/pencil/simplify", 0) ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(freehand_simplify_lpe), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); + } g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 5d52db6f2..83180e43d 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -403,6 +403,8 @@ static gchar const * ui_descr = " " " " " " + " " + " " " " " " " " -- cgit v1.2.3 From c4383f04d9a3cbe231a31662cb0b5358d512e2f1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 8 Mar 2015 16:36:57 +0100 Subject: allow use multiple lines, added new icon (bzr r13973.1.3) --- src/ui/tools/freehand-base.cpp | 2 +- src/widgets/pencil-toolbar.cpp | 32 ++++++++++++++++++-------------- src/widgets/toolbox.cpp | 1 - 3 files changed, 19 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 5858bfcfd..0844091c3 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -276,7 +276,7 @@ static void spdc_apply_simplify(std::string threshold, FreehandBase *dc, SPItem // write powerstroke parameters: lpe->getRepr()->setAttribute("steps", "1"); lpe->getRepr()->setAttribute("threshold", threshold); - lpe->getRepr()->setAttribute("Helper size", "0"); + lpe->getRepr()->setAttribute("helper", "false"); lpe->getRepr()->setAttribute("smooth_angles", "360"); lpe->getRepr()->setAttribute("nodes", "false"); lpe->getRepr()->setAttribute("handles", "false"); diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index 43d73dbc6..a06d76d01 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -49,6 +49,7 @@ #include "live_effects/effect-enum.h" #include "live_effects/lpeobject.h" #include "sp-lpe-item.h" +#include "util/glib-list-iterators.h" using Inkscape::UI::UXManager; using Inkscape::DocumentUndo; @@ -245,19 +246,22 @@ static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tb gtk_adjustment_get_value(adj)); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop")); - SPItem * item = desktop->getSelection()->singleItem(); - if(item){ - SPLPEItem* lpeitem = dynamic_cast(item); - if (lpeitem && lpeitem->hasPathEffect()){ - Inkscape::LivePathEffect::Effect* thisEffect = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY); - if(thisEffect){ - Inkscape::LivePathEffect::LPESimplify *lpe = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); - if (lpe) { - double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); - tol = tol/(100.0*(101.0-tol)); - std::ostringstream ss; - ss << tol; - lpe->getRepr()->setAttribute("threshold", ss.str()); + std::list selected; + selected.insert >(selected.end(), desktop->getSelection()->itemList(), NULL); + if(!selected.empty()){ + for (std::list::iterator it(selected.begin()); it != selected.end(); ++it){ + SPLPEItem* lpeitem = dynamic_cast(*it); + if (lpeitem && lpeitem->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY); + if(thisEffect){ + Inkscape::LivePathEffect::LPESimplify *lpe = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + if (lpe) { + double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); + tol = tol/(100.0*(101.0-tol)); + std::ostringstream ss; + ss << tol; + lpe->getRepr()->setAttribute("threshold", ss.str()); + } } } } @@ -340,7 +344,7 @@ void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb _("LPE based interactive simplify"), _("LPE based interactive simplify"), INKSCAPE_ICON("interactive_simplify"), - Inkscape::ICON_SIZE_DECORATION ); + Inkscape::ICON_SIZE_SMALL_TOOLBAR ); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(itact), prefs->getInt("/tools/freehand/pencil/simplify", 0) ); g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(freehand_simplify_lpe), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 83180e43d..79b94cd24 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -402,7 +402,6 @@ static gchar const * ui_descr = " " " " " " - " " " " " " " " -- cgit v1.2.3 From 8fcb510cfc24026d6747b778664b952e6d788d67 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 8 Mar 2015 17:57:28 +0100 Subject: fix to fit the new parameters of simplify lpe (bzr r13973.1.5) --- src/ui/tools/freehand-base.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 0844091c3..35f85f928 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -276,7 +276,6 @@ static void spdc_apply_simplify(std::string threshold, FreehandBase *dc, SPItem // write powerstroke parameters: lpe->getRepr()->setAttribute("steps", "1"); lpe->getRepr()->setAttribute("threshold", threshold); - lpe->getRepr()->setAttribute("helper", "false"); lpe->getRepr()->setAttribute("smooth_angles", "360"); lpe->getRepr()->setAttribute("nodes", "false"); lpe->getRepr()->setAttribute("handles", "false"); -- cgit v1.2.3 From 8e5f2c798334914daa121c8a1a593a16b63b6d5f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 9 Mar 2015 20:38:13 +0100 Subject: Fix new added simplify parameter (bzr r13973.1.7) --- src/ui/tools/freehand-base.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 35f85f928..bc4f98413 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -277,6 +277,7 @@ static void spdc_apply_simplify(std::string threshold, FreehandBase *dc, SPItem lpe->getRepr()->setAttribute("steps", "1"); lpe->getRepr()->setAttribute("threshold", threshold); lpe->getRepr()->setAttribute("smooth_angles", "360"); + lpe->getRepr()->setAttribute("helper_size", "0"); lpe->getRepr()->setAttribute("nodes", "false"); lpe->getRepr()->setAttribute("handles", "false"); lpe->getRepr()->setAttribute("simplifyindividualpaths", "false"); -- cgit v1.2.3 From b64a562f4a8f6cca5d07fc6063d80739f1bb1dee Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 10 Mar 2015 19:30:57 +0100 Subject: Update to new simplify (bzr r13973.1.9) --- src/ui/tools/freehand-base.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index bc4f98413..c75e0a354 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -278,8 +278,6 @@ static void spdc_apply_simplify(std::string threshold, FreehandBase *dc, SPItem lpe->getRepr()->setAttribute("threshold", threshold); lpe->getRepr()->setAttribute("smooth_angles", "360"); lpe->getRepr()->setAttribute("helper_size", "0"); - lpe->getRepr()->setAttribute("nodes", "false"); - lpe->getRepr()->setAttribute("handles", "false"); lpe->getRepr()->setAttribute("simplifyindividualpaths", "false"); lpe->getRepr()->setAttribute("simplifyJustCoalesce", "false"); } -- cgit v1.2.3 From 9e7f573d4c93a7f40af7002010184b4f65e3c975 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 19 Mar 2015 10:44:56 +0100 Subject: fix a bug pointed by su_v (bzr r13879.1.12) --- src/live_effects/lpe-transform_2pts.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index fdedf8af0..8eb5cc734 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -17,7 +17,7 @@ #include "live_effects/lpegroupbbox.h" #include "live_effects/parameter/parameter.h" #include "live_effects/parameter/togglebutton.h" -#include "live_effects/parameter/pointreseteable.h" +#include "live_effects/parameter/point.h" namespace Inkscape { namespace LivePathEffect { @@ -44,8 +44,8 @@ protected: private: ToggleButtonParam fromOriginalWidth; - PointReseteableParam start; - PointReseteableParam end; + PointParam start; + PointParam end; ScalarParam firstKnot; ScalarParam lastKnot; bool fromOriginalWidthToogler; -- cgit v1.2.3 From 2b7ed651e29bd2f4f22830d8a0525609478a33ff Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 19 Mar 2015 13:07:13 +0100 Subject: Fixed compiling problems and removed ACTIVE DESKTOP from LPE (bzr r13879.1.13) --- src/live_effects/lpe-transform_2pts.cpp | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 5a7d1b16d..9b8c1879a 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -17,9 +17,7 @@ #include <2geom/transforms.h> #include <2geom/path.h> #include "sp-path.h" -#include "ui/tools-switch.h" #include "ui/icon-names.h" -#include "inkscape.h" #include @@ -73,9 +71,9 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) lastKnot.param_set_value(nnodes); } start.param_update_default(A); - start.param_set_and_write_default(); + start.param_set_default(); end.param_update_default(B); - end.param_set_and_write_default(); + end.param_set_default(); } void @@ -153,16 +151,13 @@ LPETransform2Pts::updateIndex() D = originalPV[0][(int)lastKnot-2].finalPoint(); } start.param_update_default(C); - start.param_set_and_write_default(); + start.param_set_default(); end.param_update_default(D); - end.param_set_and_write_default(); + end.param_set_default(); start.param_update_default(A); end.param_update_default(B); - start.param_set_and_write_default(); - end.param_set_and_write_default(); - SPDesktop * desktop = SP_ACTIVE_DESKTOP; - tools_switch(desktop, TOOLS_SELECT); - tools_switch(desktop, TOOLS_NODES); + start.param_set_default(); + end.param_set_default(); } } @@ -185,11 +180,8 @@ LPETransform2Pts::reset() } start.param_update_default(A); end.param_update_default(B); - start.param_set_and_write_default(); - end.param_set_and_write_default(); - SPDesktop * desktop = SP_ACTIVE_DESKTOP; - tools_switch(desktop, TOOLS_SELECT); - tools_switch(desktop, TOOLS_NODES); + start.param_set_default(); + end.param_set_default(); } Gtk::Widget *LPETransform2Pts::newWidget() -- cgit v1.2.3 From 4b881e97ff24ba534edab7592ed74bb1a07f6939 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 9 Apr 2015 20:57:44 +0200 Subject: Rename a variable to current coding style (bzr r12588.1.41) --- src/ui/tools/freehand-base.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 22948c7bc..096957be0 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -311,7 +311,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, bool shape_applied = false; SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); const char *cstroke = sp_repr_css_property(css_item, "stroke", "none"); - static SPItem *bendItem; + static SPItem *bend_item; #define SHAPE_LENGTH 10 #define SHAPE_HEIGHT 10 @@ -386,11 +386,11 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if(cm->paste(SP_ACTIVE_DESKTOP,true) == true){ item->transform = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2doc_affine().inverse(); gchar const *svgd = item->getRepr()->attribute("d"); - bendItem = dc->selection->singleItem(); - bendItem->moveTo(item,false); - spdc_apply_bend_shape(svgd, dc, bendItem); - bendItem->transform = Geom::Affine(1,0,0,1,0,0); - dc->selection->add(SP_OBJECT(bendItem)); + bend_item = dc->selection->singleItem(); + bend_item->moveTo(item,false); + spdc_apply_bend_shape(svgd, dc, bend_item); + bend_item->transform = Geom::Affine(1,0,0,1,0,0); + dc->selection->add(SP_OBJECT(bend_item)); } else { shape = NONE; } @@ -409,17 +409,17 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, } shape = CLIPBOARD; } else { - if(bendItem != NULL && bendItem->getRepr() != NULL){ + if(bend_item != NULL && bend_item->getRepr() != NULL){ item->transform = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2doc_affine().inverse(); gchar const *svgd = item->getRepr()->attribute("d"); - dc->selection->add(SP_OBJECT(bendItem)); + dc->selection->add(SP_OBJECT(bend_item)); sp_selection_duplicate(dc->desktop); - dc->selection->remove(SP_OBJECT(bendItem)); - bendItem = dc->selection->singleItem(); - bendItem->moveTo(item,false); - spdc_apply_bend_shape(svgd, dc, bendItem); - bendItem->transform = Geom::Affine(1,0,0,1,0,0); - dc->selection->add(SP_OBJECT(bendItem)); + dc->selection->remove(SP_OBJECT(bend_item)); + bend_item = dc->selection->singleItem(); + bend_item->moveTo(item,false); + spdc_apply_bend_shape(svgd, dc, bend_item); + bend_item->transform = Geom::Affine(1,0,0,1,0,0); + dc->selection->add(SP_OBJECT(bend_item)); } shape = BEND_CLIPBOARD; } -- cgit v1.2.3 From fbf782922e70079430192417f1a9ec84fe59c8dc Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 9 Apr 2015 21:20:32 +0200 Subject: astyle simplify LPE (bzr r13973.1.12) --- src/live_effects/lpe-simplify.cpp | 134 +++++++++++++++++++------------------- src/live_effects/lpe-simplify.h | 48 +++++++------- 2 files changed, 91 insertions(+), 91 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 1fe18dd5e..bbedd355a 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -27,39 +27,39 @@ namespace LivePathEffect { LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) : Effect(lpeobject), - steps(_("Steps:"),_("Change number of simplify steps "), "steps", &wr, this,1), - threshold(_("Roughly threshold:"), _("Roughly threshold:"), "threshold", &wr, this, 0.003), - smooth_angles(_("Smooth angles:"), _("Max degree difference on handles to preform a smooth"), "smooth_angles", &wr, this, 20.), - helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 5), - simplifyindividualpaths(_("Paths separately"), _("Simplifying paths (separately)"), "simplifyindividualpaths", &wr, this, false, - "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), - simplifyJustCoalesce(_("Just coalesce"), _("Simplify just coalesce"), "simplifyJustCoalesce", &wr, this, false, - "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")) - { - registerParameter(&steps); - registerParameter(&threshold); - registerParameter(&smooth_angles); - registerParameter(&helper_size); - registerParameter(&simplifyindividualpaths); - registerParameter(&simplifyJustCoalesce); + steps(_("Steps:"),_("Change number of simplify steps "), "steps", &wr, this,1), + threshold(_("Roughly threshold:"), _("Roughly threshold:"), "threshold", &wr, this, 0.003), + smooth_angles(_("Smooth angles:"), _("Max degree difference on handles to preform a smooth"), "smooth_angles", &wr, this, 20.), + helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 5), + simplifyindividualpaths(_("Paths separately"), _("Simplifying paths (separately)"), "simplifyindividualpaths", &wr, this, false, + "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + simplifyJustCoalesce(_("Just coalesce"), _("Simplify just coalesce"), "simplifyJustCoalesce", &wr, this, false, + "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")) +{ + registerParameter(&steps); + registerParameter(&threshold); + registerParameter(&smooth_angles); + registerParameter(&helper_size); + registerParameter(&simplifyindividualpaths); + registerParameter(&simplifyJustCoalesce); - threshold.param_set_range(0.0001, Geom::infinity()); - threshold.param_set_increments(0.0001, 0.0001); - threshold.param_set_digits(6); + threshold.param_set_range(0.0001, Geom::infinity()); + threshold.param_set_increments(0.0001, 0.0001); + threshold.param_set_digits(6); - steps.param_set_range(0, 100); - steps.param_set_increments(1, 1); - steps.param_set_digits(0); + steps.param_set_range(0, 100); + steps.param_set_increments(1, 1); + steps.param_set_digits(0); - smooth_angles.param_set_range(0.0, 365.0); - smooth_angles.param_set_increments(10, 10); - smooth_angles.param_set_digits(2); + smooth_angles.param_set_range(0.0, 365.0); + smooth_angles.param_set_increments(10, 10); + smooth_angles.param_set_digits(2); - helper_size.param_set_range(0.0, 999.0); - helper_size.param_set_increments(5, 5); - helper_size.param_set_digits(2); + helper_size.param_set_range(0.0, 999.0); + helper_size.param_set_increments(5, 5); + helper_size.param_set_digits(2); - radiusHelperNodes = 6.0; + radiusHelperNodes = 6.0; } LPESimplify::~LPESimplify() {} @@ -67,7 +67,7 @@ LPESimplify::~LPESimplify() {} void LPESimplify::doBeforeEffect (SPLPEItem const* lpeitem) { - if(!hp.empty()){ + if(!hp.empty()) { hp.clear(); } bbox = SP_ITEM(lpeitem)->visualBounds(); @@ -91,9 +91,8 @@ LPESimplify::newWidget() if ((*it)->widget_is_visible) { Parameter * param = *it; Gtk::Widget * widg = dynamic_cast(param->param_newWidget()); - if (param->param_key == "simplifyindividualpaths" || - param->param_key == "simplifyJustCoalesce") - { + if (param->param_key == "simplifyindividualpaths" || + param->param_key == "simplifyJustCoalesce") { Glib::ustring * tip = param->param_getTooltip(); if (widg) { buttons->pack_start(*widg, true, true, 2); @@ -104,7 +103,7 @@ LPESimplify::newWidget() widg->set_has_tooltip(false); } } - } else{ + } else { Glib::ustring * tip = param->param_getTooltip(); if (widg) { Gtk::HBox * scalarParameter = dynamic_cast(widg); @@ -128,28 +127,29 @@ LPESimplify::newWidget() return dynamic_cast(vbox); } -void -LPESimplify::doEffect(SPCurve *curve) { +void +LPESimplify::doEffect(SPCurve *curve) +{ Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); gdouble size = Geom::L2(bbox->dimensions()); //size /= Geom::Affine(0,0,0,0,0,0).descrim(); Path* pathliv = Path_for_pathvector(original_pathv); - if(simplifyindividualpaths){ + if(simplifyindividualpaths) { size = Geom::L2(Geom::bounds_fast(original_pathv)->dimensions()); } - for (int unsigned i = 0; i < steps; i++){ + for (int unsigned i = 0; i < steps; i++) { if ( simplifyJustCoalesce ) { - pathliv->Coalesce(threshold * size); - }else{ - pathliv->ConvertEvenLines(threshold * size); - pathliv->Simplify(threshold * size); + pathliv->Coalesce(threshold * size); + } else { + pathliv->ConvertEvenLines(threshold * size); + pathliv->Simplify(threshold * size); } } Geom::PathVector result = Geom::parse_svg_path(pathliv->svg_dump_path()); generateHelperPathAndSmooth(result); curve->set_pathvector(result); SPDesktop* desktop = SP_ACTIVE_DESKTOP; - if(desktop && INK_IS_NODE_TOOL(desktop->event_context)){ + if(desktop && INK_IS_NODE_TOOL(desktop->event_context)) { Inkscape::UI::Tools::NodeTool *nt = static_cast(desktop->event_context); nt->update_helperpath(); } @@ -158,15 +158,15 @@ LPESimplify::doEffect(SPCurve *curve) { void LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) { - if(steps < 1){ + if(steps < 1) { return; } Geom::PathVector tmpPath; Geom::CubicBezier const *cubic = NULL; for (Geom::PathVector::iterator path_it = result.begin(); path_it != result.end(); ++path_it) { //Si estĆ” vacĆ­o... - if (path_it->empty()){ - continue; + if (path_it->empty()) { + continue; } //Itreadores Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve @@ -174,20 +174,20 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop SPCurve *nCurve = new SPCurve(); if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the - // closing line segment has zerolength. - const Geom::Curve &closingline = - path_it->back_closed(); // the closing line segment is always of type - // Geom::LineSegment. - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for - // *exact* zero length, which goes wrong for relative coordinates and - // rounding errors... - // the closing line segment has zero-length. So stop before that one! - curve_endit = path_it->end_open(); - } + // if the path is closed, maybe we have to stop a bit earlier because the + // closing line segment has zerolength. + const Geom::Curve &closingline = + path_it->back_closed(); // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } } - if(helper_size > 0){ + if(helper_size > 0) { drawNode(curve_it1->initialPoint()); } nCurve->moveto(curve_it1->initialPoint()); @@ -202,14 +202,14 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) pointAt1 = (*cubic)[1]; pointAt2 = (*cubic)[2]; } - if(start == Geom::Point(0,0)){ + if(start == Geom::Point(0,0)) { start = pointAt1; } - - if(path_it->closed() && curve_it2 == curve_endit){ + + if(path_it->closed() && curve_it2 == curve_endit) { pointAt4 = start; } - if(curve_it2 != curve_endit){ + if(curve_it2 != curve_endit) { cubic = dynamic_cast(&*curve_it2); if (cubic) { pointAt4 = (*cubic)[1]; @@ -219,7 +219,7 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) Geom::Ray ray2(pointAt3, pointAt4); double angle1 = Geom::rad_to_deg(ray1.angle()); double angle2 = Geom::rad_to_deg(ray2.angle()); - if((smooth_angles >= angle2 - angle1) && !are_near(pointAt4,pointAt3) && !are_near(pointAt2,pointAt3)){ + if((smooth_angles >= angle2 - angle1) && !are_near(pointAt4,pointAt3) && !are_near(pointAt2,pointAt3)) { double dist = Geom::distance(pointAt2,pointAt3); Geom::Angle angleFixed = ray2.angle(); angleFixed -= Geom::Angle::from_degrees(180.0); @@ -231,11 +231,11 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) pointAt1 = (*cubic)[1]; pointAt2 = (*cubic)[2]; if(helper_size > 0) { - if(!are_near((*cubic)[0],(*cubic)[1])){ + if(!are_near((*cubic)[0],(*cubic)[1])) { drawHandle((*cubic)[1]); drawHandleLine((*cubic)[0],(*cubic)[1]); } - if(!are_near((*cubic)[3],(*cubic)[2])){ + if(!are_near((*cubic)[3],(*cubic)[2])) { drawHandle((*cubic)[2]); drawHandleLine((*cubic)[3],(*cubic)[2]); } @@ -257,7 +257,7 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) result = tmpPath; } -void +void LPESimplify::drawNode(Geom::Point p) { double r = radiusHelperNodes; @@ -289,7 +289,7 @@ LPESimplify::drawHandleLine(Geom::Point p,Geom::Point p2) Geom::Path path; path.start( p ); double diameter = radiusHelperNodes; - if(helper_size > 0 && Geom::distance(p,p2) > (diameter * 0.35)){ + if(helper_size > 0 && Geom::distance(p,p2) > (diameter * 0.35)) { Geom::Ray ray2(p, p2); p2 = p2 - Geom::Point::polar(ray2.angle(),(diameter * 0.35)); } diff --git a/src/live_effects/lpe-simplify.h b/src/live_effects/lpe-simplify.h index c18c3ecdf..bc70e9f54 100644 --- a/src/live_effects/lpe-simplify.h +++ b/src/live_effects/lpe-simplify.h @@ -14,43 +14,43 @@ namespace Inkscape { namespace LivePathEffect { -class LPESimplify : public Effect , GroupBBoxEffect{ +class LPESimplify : public Effect , GroupBBoxEffect { public: - LPESimplify(LivePathEffectObject *lpeobject); - virtual ~LPESimplify(); + LPESimplify(LivePathEffectObject *lpeobject); + virtual ~LPESimplify(); - virtual void doEffect(SPCurve *curve); + virtual void doEffect(SPCurve *curve); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void generateHelperPathAndSmooth(Geom::PathVector &result); + virtual void generateHelperPathAndSmooth(Geom::PathVector &result); - virtual Gtk::Widget * newWidget(); + virtual Gtk::Widget * newWidget(); - virtual void drawNode(Geom::Point p); - - virtual void drawHandle(Geom::Point p); + virtual void drawNode(Geom::Point p); - virtual void drawHandleLine(Geom::Point p,Geom::Point p2); + virtual void drawHandle(Geom::Point p); + + virtual void drawHandleLine(Geom::Point p,Geom::Point p2); protected: void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec); private: - ScalarParam steps; - ScalarParam threshold; - ScalarParam smooth_angles; - ScalarParam helper_size; - ToggleButtonParam simplifyindividualpaths; - ToggleButtonParam simplifyJustCoalesce; - - double radiusHelperNodes; - Geom::PathVector hp; - Geom::OptRect bbox; - - LPESimplify(const LPESimplify &); - LPESimplify &operator=(const LPESimplify &); + ScalarParam steps; + ScalarParam threshold; + ScalarParam smooth_angles; + ScalarParam helper_size; + ToggleButtonParam simplifyindividualpaths; + ToggleButtonParam simplifyJustCoalesce; + + double radiusHelperNodes; + Geom::PathVector hp; + Geom::OptRect bbox; + + LPESimplify(const LPESimplify &); + LPESimplify &operator=(const LPESimplify &); }; -- cgit v1.2.3 From cec061f7cf7b30d2a92ddf729c36aa032a1b6ddf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 9 Apr 2015 21:30:28 +0200 Subject: Coding style fixes (bzr r13973.1.13) --- src/live_effects/lpe-simplify.cpp | 80 +++++++++++++++++++-------------------- src/live_effects/lpe-simplify.h | 6 +-- 2 files changed, 43 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index bbedd355a..d2ced47ae 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -31,17 +31,17 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) threshold(_("Roughly threshold:"), _("Roughly threshold:"), "threshold", &wr, this, 0.003), smooth_angles(_("Smooth angles:"), _("Max degree difference on handles to preform a smooth"), "smooth_angles", &wr, this, 20.), helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 5), - simplifyindividualpaths(_("Paths separately"), _("Simplifying paths (separately)"), "simplifyindividualpaths", &wr, this, false, + simplify_individual_paths(_("Paths separately"), _("Simplifying paths (separately)"), "simplify_individual_paths", &wr, this, false, "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), - simplifyJustCoalesce(_("Just coalesce"), _("Simplify just coalesce"), "simplifyJustCoalesce", &wr, this, false, + simplify_just_coalesce(_("Just coalesce"), _("Simplify just coalesce"), "simplify_just_coalesce", &wr, this, false, "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")) { registerParameter(&steps); registerParameter(&threshold); registerParameter(&smooth_angles); registerParameter(&helper_size); - registerParameter(&simplifyindividualpaths); - registerParameter(&simplifyJustCoalesce); + registerParameter(&simplify_individual_paths); + registerParameter(&simplify_just_coalesce); threshold.param_set_range(0.0001, Geom::infinity()); threshold.param_set_increments(0.0001, 0.0001); @@ -59,7 +59,7 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) helper_size.param_set_increments(5, 5); helper_size.param_set_digits(2); - radiusHelperNodes = 6.0; + radius_helper_nodes = 6.0; } LPESimplify::~LPESimplify() {} @@ -72,7 +72,7 @@ LPESimplify::doBeforeEffect (SPLPEItem const* lpeitem) } bbox = SP_ITEM(lpeitem)->visualBounds(); SPLPEItem * item = const_cast(lpeitem); - radiusHelperNodes = helper_size; + radius_helper_nodes = helper_size; item->apply_to_clippath(item); item->apply_to_mask(item); } @@ -91,8 +91,8 @@ LPESimplify::newWidget() if ((*it)->widget_is_visible) { Parameter * param = *it; Gtk::Widget * widg = dynamic_cast(param->param_newWidget()); - if (param->param_key == "simplifyindividualpaths" || - param->param_key == "simplifyJustCoalesce") { + if (param->param_key == "simplify_individual_paths" || + param->param_key == "simplify_just_coalesce") { Glib::ustring * tip = param->param_getTooltip(); if (widg) { buttons->pack_start(*widg, true, true, 2); @@ -106,10 +106,10 @@ LPESimplify::newWidget() } else { Glib::ustring * tip = param->param_getTooltip(); if (widg) { - Gtk::HBox * scalarParameter = dynamic_cast(widg); - std::vector< Gtk::Widget* > childList = scalarParameter->get_children(); - Gtk::Entry* entryWidg = dynamic_cast(childList[1]); - entryWidg->set_width_chars(8); + Gtk::HBox * horizontal_box = dynamic_cast(widg); + std::vector< Gtk::Widget* > child_list = horizontal_box->get_children(); + Gtk::Entry* entry_widg = dynamic_cast(child_list[1]); + entry_widg->set_width_chars(8); vbox->pack_start(*widg, true, true, 2); if (tip) { widg->set_tooltip_text(*tip); @@ -134,11 +134,11 @@ LPESimplify::doEffect(SPCurve *curve) gdouble size = Geom::L2(bbox->dimensions()); //size /= Geom::Affine(0,0,0,0,0,0).descrim(); Path* pathliv = Path_for_pathvector(original_pathv); - if(simplifyindividualpaths) { + if(simplify_individual_paths) { size = Geom::L2(Geom::bounds_fast(original_pathv)->dimensions()); } for (int unsigned i = 0; i < steps; i++) { - if ( simplifyJustCoalesce ) { + if ( simplify_just_coalesce ) { pathliv->Coalesce(threshold * size); } else { pathliv->ConvertEvenLines(threshold * size); @@ -161,7 +161,7 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) if(steps < 1) { return; } - Geom::PathVector tmpPath; + Geom::PathVector tmp_path; Geom::CubicBezier const *cubic = NULL; for (Geom::PathVector::iterator path_it = result.begin(); path_it != result.end(); ++path_it) { //Si estĆ” vacĆ­o... @@ -188,48 +188,48 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) } } if(helper_size > 0) { - drawNode(curve_it1->initialPoint()); + draw_node(curve_it1->initialPoint()); } nCurve->moveto(curve_it1->initialPoint()); Geom::Point start = Geom::Point(0,0); while (curve_it1 != curve_endit) { cubic = dynamic_cast(&*curve_it1); - Geom::Point pointAt1 = curve_it1->initialPoint(); - Geom::Point pointAt2 = curve_it1->finalPoint(); - Geom::Point pointAt3 = curve_it1->finalPoint(); - Geom::Point pointAt4 = curve_it1->finalPoint(); + Geom::Point point_at1 = curve_it1->initialPoint(); + Geom::Point point_at2 = curve_it1->finalPoint(); + Geom::Point point_at3 = curve_it1->finalPoint(); + Geom::Point point_at4 = curve_it1->finalPoint(); if (cubic) { - pointAt1 = (*cubic)[1]; - pointAt2 = (*cubic)[2]; + point_at1 = (*cubic)[1]; + point_at2 = (*cubic)[2]; } if(start == Geom::Point(0,0)) { - start = pointAt1; + start = point_at1; } if(path_it->closed() && curve_it2 == curve_endit) { - pointAt4 = start; + point_at4 = start; } if(curve_it2 != curve_endit) { cubic = dynamic_cast(&*curve_it2); if (cubic) { - pointAt4 = (*cubic)[1]; + point_at4 = (*cubic)[1]; } } - Geom::Ray ray1(pointAt2, pointAt3); - Geom::Ray ray2(pointAt3, pointAt4); + Geom::Ray ray1(point_at2, point_at3); + Geom::Ray ray2(point_at3, point_at4); double angle1 = Geom::rad_to_deg(ray1.angle()); double angle2 = Geom::rad_to_deg(ray2.angle()); - if((smooth_angles >= angle2 - angle1) && !are_near(pointAt4,pointAt3) && !are_near(pointAt2,pointAt3)) { - double dist = Geom::distance(pointAt2,pointAt3); + if((smooth_angles >= angle2 - angle1) && !are_near(point_at4,point_at3) && !are_near(point_at2,point_at3)) { + double dist = Geom::distance(point_at2,point_at3); Geom::Angle angleFixed = ray2.angle(); angleFixed -= Geom::Angle::from_degrees(180.0); - pointAt2 = Geom::Point::polar(angleFixed,dist) + pointAt3; + point_at2 = Geom::Point::polar(angleFixed,dist) + point_at3; } - nCurve->curveto(pointAt1, pointAt2, curve_it1->finalPoint()); + nCurve->curveto(point_at1, point_at2, curve_it1->finalPoint()); cubic = dynamic_cast(nCurve->last_segment()); if (cubic) { - pointAt1 = (*cubic)[1]; - pointAt2 = (*cubic)[2]; + point_at1 = (*cubic)[1]; + point_at2 = (*cubic)[2]; if(helper_size > 0) { if(!are_near((*cubic)[0],(*cubic)[1])) { drawHandle((*cubic)[1]); @@ -242,7 +242,7 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) } } if(helper_size > 0) { - drawNode(curve_it1->finalPoint()); + draw_node(curve_it1->finalPoint()); } ++curve_it1; ++curve_it2; @@ -250,17 +250,17 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) if (path_it->closed()) { nCurve->closepath_current(); } - tmpPath.push_back(nCurve->get_pathvector()[0]); + tmp_path.push_back(nCurve->get_pathvector()[0]); nCurve->reset(); delete nCurve; } - result = tmpPath; + result = tmp_path; } void -LPESimplify::drawNode(Geom::Point p) +LPESimplify::draw_node(Geom::Point p) { - double r = radiusHelperNodes; + double r = radius_helper_nodes; char const * svgd; svgd = "M 0.55,0.5 A 0.05,0.05 0 0 1 0.5,0.55 0.05,0.05 0 0 1 0.45,0.5 0.05,0.05 0 0 1 0.5,0.45 0.05,0.05 0 0 1 0.55,0.5 Z M 0,0 1,0 1,1 0,1 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); @@ -273,7 +273,7 @@ LPESimplify::drawNode(Geom::Point p) void LPESimplify::drawHandle(Geom::Point p) { - double r = radiusHelperNodes; + double r = radius_helper_nodes; char const * svgd; svgd = "M 0.7,0.35 A 0.35,0.35 0 0 1 0.35,0.7 0.35,0.35 0 0 1 0,0.35 0.35,0.35 0 0 1 0.35,0 0.35,0.35 0 0 1 0.7,0.35 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); @@ -288,7 +288,7 @@ LPESimplify::drawHandleLine(Geom::Point p,Geom::Point p2) { Geom::Path path; path.start( p ); - double diameter = radiusHelperNodes; + double diameter = radius_helper_nodes; if(helper_size > 0 && Geom::distance(p,p2) > (diameter * 0.35)) { Geom::Ray ray2(p, p2); p2 = p2 - Geom::Point::polar(ray2.angle(),(diameter * 0.35)); diff --git a/src/live_effects/lpe-simplify.h b/src/live_effects/lpe-simplify.h index bc70e9f54..294d77b35 100644 --- a/src/live_effects/lpe-simplify.h +++ b/src/live_effects/lpe-simplify.h @@ -42,10 +42,10 @@ private: ScalarParam threshold; ScalarParam smooth_angles; ScalarParam helper_size; - ToggleButtonParam simplifyindividualpaths; - ToggleButtonParam simplifyJustCoalesce; + ToggleButtonParam simplify_individual_paths; + ToggleButtonParam simplify_just_coalesce; - double radiusHelperNodes; + double radius_helper_nodes; Geom::PathVector hp; Geom::OptRect bbox; -- cgit v1.2.3 From dbff287750e69fde0a98e67c297531113ed74d13 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 9 Apr 2015 21:34:51 +0200 Subject: fix a bug in refactor (bzr r13973.1.14) --- src/live_effects/lpe-simplify.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index d2ced47ae..7fc20ede1 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -188,7 +188,7 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) } } if(helper_size > 0) { - draw_node(curve_it1->initialPoint()); + drawNode(curve_it1->initialPoint()); } nCurve->moveto(curve_it1->initialPoint()); Geom::Point start = Geom::Point(0,0); @@ -242,7 +242,7 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) } } if(helper_size > 0) { - draw_node(curve_it1->finalPoint()); + drawNode(curve_it1->finalPoint()); } ++curve_it1; ++curve_it2; @@ -258,7 +258,7 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) } void -LPESimplify::draw_node(Geom::Point p) +LPESimplify::drawNode(Geom::Point p) { double r = radius_helper_nodes; char const * svgd; -- cgit v1.2.3 From c956c7436fbb9a9ba3281882f7d388f249a050a4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 11 Apr 2015 00:54:25 +0200 Subject: Fix coding style issues in transform by two points LPE (bzr r13879.1.15) --- src/live_effects/lpe-transform_2pts.cpp | 194 ++++++++++++++++---------------- src/live_effects/lpe-transform_2pts.h | 18 +-- 2 files changed, 106 insertions(+), 106 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 9b8c1879a..4b0cbadbb 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -26,25 +26,25 @@ namespace LivePathEffect { LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : Effect(lpeobject), - fromOriginalWidth(_("From original width"), _("From original width"), "fromOriginalWidth", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + from_original_width(_("From original width"), _("From original width"), "from_original_width", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), start(_("Start"), _("Start point"), "start", &wr, this, "Start point"), end(_("End"), _("End point"), "end", &wr, this, "End point"), - firstKnot(_("First Knot"), _("First Knot"), "firstKnot", &wr, this, 1), - lastKnot(_("Last Knot"), _("Last Knot"), "lastKnot", &wr, this, 1), - fromOriginalWidthToogler(false), - A(Geom::Point(0,0)), - B(Geom::Point(0,0)), - c(NULL), - appandedPath(false) + first_knot(_("First Knot"), _("First Knot"), "first_knot", &wr, this, 1), + last_knot(_("Last Knot"), _("Last Knot"), "last_knot", &wr, this, 1), + from_original_width_toogler(false), + point_a(Geom::Point(0,0)), + point_b(Geom::Point(0,0)), + curve_c(NULL), + append_path(false) { registerParameter(&start); registerParameter(&end); - registerParameter(&firstKnot); - registerParameter(&lastKnot); - registerParameter(&fromOriginalWidth); - - firstKnot.param_make_integer(true); - lastKnot.param_make_integer(true); + registerParameter(&first_knot); + registerParameter(&last_knot); + registerParameter(&from_original_width); + + first_knot.param_make_integer(true); + last_knot.param_make_integer(true); } LPETransform2Pts::~LPETransform2Pts() @@ -57,22 +57,22 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) using namespace Geom; original_bbox(lpeitem); - A = Point(boundingbox_X.min(), boundingbox_Y.middle()); - B = Point(boundingbox_X.max(), boundingbox_Y.middle()); + point_a = Point(boundingbox_X.min(), boundingbox_Y.middle()); + point_b = Point(boundingbox_X.max(), boundingbox_Y.middle()); SPLPEItem * splpeitem = const_cast(lpeitem); SPPath *path = dynamic_cast(splpeitem); if (path) { - c = path->get_original_curve(); + curve_c = path->get_original_curve(); } - if(c && !c->is_closed() && c->first_path() == c->last_path()){ - A = *(c->first_point()); - B = *(c->last_point()); - int nnodes = (int)c->nodes_in_path(); - lastKnot.param_set_value(nnodes); + if(curve_c && !curve_c->is_closed() && curve_c->first_path() == curve_c->last_path()) { + point_a = *(curve_c->first_point()); + point_b = *(curve_c->last_point()); + int nnodes = (int)curve_c->nodes_in_path(); + last_knot.param_set_value(nnodes); } - start.param_update_default(A); + start.param_update_default(point_a); start.param_set_default(); - end.param_update_default(B); + end.param_update_default(point_b); end.param_set_default(); } @@ -81,52 +81,52 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - A = Point(boundingbox_X.min(), boundingbox_Y.middle()); - B = Point(boundingbox_X.max(), boundingbox_Y.middle()); + point_a = Point(boundingbox_X.min(), boundingbox_Y.middle()); + point_b = Point(boundingbox_X.max(), boundingbox_Y.middle()); SPLPEItem * splpeitem = const_cast(lpeitem); SPPath *path = dynamic_cast(splpeitem); if (path) { - c = path->get_original_curve(); + curve_c = path->get_original_curve(); } - if(fromOriginalWidthToogler != fromOriginalWidth){ - fromOriginalWidthToogler = fromOriginalWidth; + if(from_original_width_toogler != from_original_width) { + from_original_width_toogler = from_original_width; reset(); } - if(c && !fromOriginalWidth){ - if(!c->is_closed() && c->first_path() == c->last_path()){ - appandedPath = false; - Geom::PathVector const originalPV = c->get_pathvector(); - A = originalPV[0][0].initialPoint(); - if((int)firstKnot > 1){ - A = originalPV[0][(int)firstKnot-2].finalPoint(); + if(curve_c && !from_original_width) { + if(!curve_c->is_closed() && curve_c->first_path() == curve_c->last_path()) { + append_path = false; + Geom::PathVector const originalPV = curve_c->get_pathvector(); + point_a = originalPV[0][0].initialPoint(); + if((int)first_knot > 1) { + point_a = originalPV[0][(int)first_knot-2].finalPoint(); } - B = originalPV[0][0].initialPoint(); - if((int)lastKnot > 1){ - B = originalPV[0][(int)lastKnot-2].finalPoint(); + point_b = originalPV[0][0].initialPoint(); + if((int)last_knot > 1) { + point_b = originalPV[0][(int)last_knot-2].finalPoint(); } - int nnodes = (int)c->nodes_in_path(); - firstKnot.param_set_range(1, lastKnot-1); - lastKnot.param_set_range(firstKnot+1, nnodes); - fromOriginalWidth.param_setValue(false); + int nnodes = (int)curve_c->nodes_in_path(); + first_knot.param_set_range(1, last_knot-1); + last_knot.param_set_range(first_knot+1, nnodes); + from_original_width.param_setValue(false); } else { - firstKnot.param_set_value(1); - lastKnot.param_set_value(2); - firstKnot.param_set_range(1,1); - lastKnot.param_set_range(2,2); - if(appandedPath == false){ - appandedPath = true; + first_knot.param_set_value(1); + last_knot.param_set_value(2); + first_knot.param_set_range(1,1); + last_knot.param_set_range(2,2); + if(append_path == false) { + append_path = true; } else { - fromOriginalWidth.param_setValue(true); + from_original_width.param_setValue(true); } } } else { - firstKnot.param_set_value(1); - lastKnot.param_set_value(2); - firstKnot.param_set_range(1,1); - lastKnot.param_set_range(2,2); - fromOriginalWidth.param_setValue(true); - appandedPath = false; + first_knot.param_set_value(1); + last_knot.param_set_value(2); + first_knot.param_set_range(1,1); + last_knot.param_set_range(2,2); + from_original_width.param_setValue(true); + append_path = false; } splpeitem->apply_to_clippath(splpeitem); splpeitem->apply_to_mask(splpeitem); @@ -135,27 +135,27 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) void LPETransform2Pts::updateIndex() { - SPCurve * c2 = NULL; + SPCurve * curve2 = NULL; SPShape *shape = SP_SHAPE(sp_lpe_item); if (shape) { - c2 = shape->getCurve(); + curve2 = shape->getCurve(); } - if(c2 && !fromOriginalWidth && !c->is_closed() && c->first_path() == c->last_path()){ - Geom::PathVector const originalPV = c2->get_pathvector(); - Geom::Point C = originalPV[0][0].initialPoint(); - Geom::Point D = originalPV[0][0].initialPoint(); - if((int)firstKnot > 1){ - C = originalPV[0][(int)firstKnot-2].finalPoint(); + if(curve2 && !from_original_width && !curve_c->is_closed() && curve_c->first_path() == curve_c->last_path()) { + Geom::PathVector const originalPV = curve2->get_pathvector(); + Geom::Point point_c = originalPV[0][0].initialPoint(); + Geom::Point point_d = originalPV[0][0].initialPoint(); + if((int)first_knot > 1) { + point_c = originalPV[0][(int)first_knot-2].finalPoint(); } - if((int)lastKnot > 1){ - D = originalPV[0][(int)lastKnot-2].finalPoint(); + if((int)last_knot > 1) { + point_d = originalPV[0][(int)last_knot-2].finalPoint(); } - start.param_update_default(C); + start.param_update_default(point_c); start.param_set_default(); - end.param_update_default(D); + end.param_update_default(point_d); end.param_set_default(); - start.param_update_default(A); - end.param_update_default(B); + start.param_update_default(point_a); + end.param_update_default(point_b); start.param_set_default(); end.param_set_default(); } @@ -164,22 +164,22 @@ LPETransform2Pts::updateIndex() void LPETransform2Pts::reset() { - A = Geom::Point(boundingbox_X.min(), boundingbox_Y.middle()); - B = Geom::Point(boundingbox_X.max(), boundingbox_Y.middle()); - if(c && !c->is_closed() && c->first_path() == c->last_path() && !fromOriginalWidth){ - int nnodes = (int)c->nodes_in_path(); - firstKnot.param_set_range(1, lastKnot-1); - lastKnot.param_set_range(firstKnot+1, nnodes); - firstKnot.param_set_value(1); - lastKnot.param_set_value(nnodes); - A = *(c->first_point()); - B = *(c->last_point()); + point_a = Geom::Point(boundingbox_X.min(), boundingbox_Y.middle()); + point_b = Geom::Point(boundingbox_X.max(), boundingbox_Y.middle()); + if(curve_c && !curve_c->is_closed() && curve_c->first_path() == curve_c->last_path() && !from_original_width) { + int nnodes = (int)curve_c->nodes_in_path(); + first_knot.param_set_range(1, last_knot-1); + last_knot.param_set_range(first_knot+1, nnodes); + first_knot.param_set_value(1); + last_knot.param_set_value(nnodes); + point_a = *(curve_c->first_point()); + point_b = *(curve_c->last_point()); } else { - firstKnot.param_set_value(1); - lastKnot.param_set_value(2); + first_knot.param_set_value(1); + last_knot.param_set_value(2); } - start.param_update_default(A); - end.param_update_default(B); + start.param_update_default(point_a); + end.param_update_default(point_b); start.param_set_default(); end.param_set_default(); } @@ -201,15 +201,15 @@ Gtk::Widget *LPETransform2Pts::newWidget() Parameter *param = *it; Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); Glib::ustring *tip = param->param_getTooltip(); - if (param->param_key == "firstKnot" || param->param_key == "lastKnot") { - Inkscape::UI::Widget::Scalar *widgRegistered = Gtk::manage(dynamic_cast(widg)); - widgRegistered->signal_value_changed().connect(sigc::mem_fun(*this, &LPETransform2Pts::updateIndex)); - widg = widgRegistered; + if (param->param_key == "first_knot" || param->param_key == "last_knot") { + Inkscape::UI::Widget::Scalar *registered_widget = Gtk::manage(dynamic_cast(widg)); + registered_widget->signal_value_changed().connect(sigc::mem_fun(*this, &LPETransform2Pts::updateIndex)); + widg = registered_widget; if (widg) { - Gtk::HBox *scalarParameter = dynamic_cast(widg); - std::vector childList = scalarParameter->get_children(); - Gtk::Entry *entryWidg = dynamic_cast(childList[1]); - entryWidg->set_width_chars(3); + Gtk::HBox *hbox_scalar = dynamic_cast(widg); + std::vector child_list = hbox_scalar->get_children(); + Gtk::Entry *entry_widget = dynamic_cast(child_list[1]); + entry_widget->set_width_chars(3); vbox->pack_start(*widg, true, true, 2); if (tip) { widg->set_tooltip_text(*tip); @@ -218,7 +218,7 @@ Gtk::Widget *LPETransform2Pts::newWidget() widg->set_has_tooltip(false); } } - } else if (param->param_key == "fromOriginalWidth"){ + } else if (param->param_key == "from_original_width") { Glib::ustring * tip = param->param_getTooltip(); if (widg) { button->pack_start(*widg, true, true, 2); @@ -253,13 +253,13 @@ Geom::Piecewise > LPETransform2Pts::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) { Geom::Piecewise > output; - double sca = Geom::distance((Geom::Point)start,(Geom::Point)end)/Geom::distance(A,B); - Geom::Ray original(A,B); + double sca = Geom::distance((Geom::Point)start,(Geom::Point)end)/Geom::distance(point_a,point_b); + Geom::Ray original(point_a,point_b); Geom::Ray transformed((Geom::Point)start,(Geom::Point)end); double rot = transformed.angle() - original.angle(); Geom::Path helper; - helper.start(A); - helper.appendNew(B); + helper.start(point_a); + helper.appendNew(point_b); Geom::Affine m; m *= Geom::Scale(sca); m *= Geom::Rotate(rot); diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index 8eb5cc734..c4a993acc 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -7,7 +7,7 @@ /* * Authors: - * + * * * * Released under GNU GPL, read the file 'COPYING' for more information @@ -43,16 +43,16 @@ protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); private: - ToggleButtonParam fromOriginalWidth; + ToggleButtonParam from_original_width; PointParam start; PointParam end; - ScalarParam firstKnot; - ScalarParam lastKnot; - bool fromOriginalWidthToogler; - Geom::Point A; - Geom::Point B; - SPCurve * c; - bool appandedPath; + ScalarParam first_knot; + ScalarParam last_knot; + bool from_original_width_toogler; + Geom::Point point_a; + Geom::Point point_b; + SPCurve * curve_c; + bool append_path; LPETransform2Pts(const LPETransform2Pts&); LPETransform2Pts& operator=(const LPETransform2Pts&); }; -- cgit v1.2.3 From 9b709f551c3d889cf4235913c317f1b10ee9e72e Mon Sep 17 00:00:00 2001 From: jabiertxof Date: Wed, 29 Apr 2015 10:31:50 -0400 Subject: Fis fix a bug finded in my presentation in the HackFest (bzr r12588.1.43) --- src/ui/tools/freehand-base.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 9aa6c9589..a13fc0d8b 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -384,8 +384,10 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if(cm->paste(SP_ACTIVE_DESKTOP,true) == true){ - item->transform = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2doc_affine().inverse(); gchar const *svgd = item->getRepr()->attribute("d"); + Geom::PathVector path = sp_svg_read_pathv(svgd); + path *= item->i2doc_affine().inverse(); + svgd = sp_svg_write_path( path ); bend_item = dc->selection->singleItem(); bend_item->moveTo(item,false); spdc_apply_bend_shape(svgd, dc, bend_item); @@ -410,8 +412,10 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, shape = CLIPBOARD; } else { if(bend_item != NULL && bend_item->getRepr() != NULL){ - item->transform = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2doc_affine().inverse(); gchar const *svgd = item->getRepr()->attribute("d"); + Geom::PathVector path = sp_svg_read_pathv(svgd); + path *= item->i2doc_affine().inverse(); + svgd = sp_svg_write_path( path ); dc->selection->add(SP_OBJECT(bend_item)); sp_selection_duplicate(dc->desktop); dc->selection->remove(SP_OBJECT(bend_item)); -- cgit v1.2.3 From 486b8633e480fcf8db8c562bbf5ad98bd9a4b639 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Sat, 23 May 2015 16:12:17 -0400 Subject: Cache SVG DOM node order for faster touch selection. (bzr r14169.1.1) --- src/document.cpp | 77 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 741e7c812..2b76625ff 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1335,20 +1335,11 @@ SPItem *SPDocument::getItemFromListAtPointBottom(unsigned int dkey, SPGroup *gro } /** -Returns the topmost (in z-order) item from the descendants of group (recursively) which -is at the point p, or NULL if none. Honors into_groups on whether to recurse into -non-layer groups or not. Honors take_insensitive on whether to return insensitive -items. If upto != NULL, then if item upto is encountered (at any level), stops searching -upwards in z-order and returns what it has found so far (i.e. the found item is -guaranteed to be lower than upto). - */ -static SPItem *find_item_at_point(unsigned int dkey, SPGroup *group, Geom::Point const &p, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL) +Turn the SVG DOM into a flat list of nodes that can be searched from top-down. +The list can be persisted, which improves "find at multiple points" speed. +*/ +static void build_flat_item_list(std::deque *nodes, unsigned int dkey, SPGroup *group, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL) { - SPItem *seen = NULL; - SPItem *newseen = NULL; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0); - for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) { if (!SP_IS_ITEM(o)) { continue; @@ -1359,27 +1350,43 @@ static SPItem *find_item_at_point(unsigned int dkey, SPGroup *group, Geom::Point } if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { - // if nothing found yet, recurse into the group - newseen = find_item_at_point(dkey, SP_GROUP(o), p, into_groups, take_insensitive, upto); - if (newseen) { - seen = newseen; - newseen = NULL; - } - - if (item_is_in_group(upto, SP_GROUP(o))) { - break; - } + build_flat_item_list(nodes, dkey, SP_GROUP(o), into_groups, take_insensitive, upto); } else { SPItem *child = SP_ITEM(o); - Inkscape::DrawingItem *arenaitem = child->get_arenaitem(dkey); - // seen remembers the last (topmost) of items pickable at this point - if (arenaitem && arenaitem->pick(p, delta, 1) != NULL - && (take_insensitive || child->isVisibleAndUnlocked(dkey))) { - seen = child; + if (take_insensitive || child->isVisibleAndUnlocked(dkey)) { + nodes->push_front(child); } } } +} + +/** +Returns the topmost (in z-order) item from the descendants of group (recursively) which +is at the point p, or NULL if none. Honors into_groups on whether to recurse into +non-layer groups or not. Honors take_insensitive on whether to return insensitive +items. If upto != NULL, then if item upto is encountered (at any level), stops searching +upwards in z-order and returns what it has found so far (i.e. the found item is +guaranteed to be lower than upto). Requires a list of nodes built by +build_flat_item_list. + */ +static SPItem *find_item_at_point(std::deque *nodes, unsigned int dkey, Geom::Point const &p) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0); + + SPItem *seen = NULL; + SPItem *child; + for (unsigned long i = 0; i < nodes->size(); ++i) { + child = nodes->at(i); + Inkscape::DrawingItem *arenaitem = child->get_arenaitem(dkey); + + if (arenaitem && arenaitem->pick(p, delta, 1) != NULL) { + seen = child; + break; + } + } + return seen; } @@ -1454,9 +1461,12 @@ std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vecto gdouble saved_delta = prefs->getDouble("/options/cursortolerance/value", 1.0); prefs->setDouble("/options/cursortolerance/value", 0.25); + // Cache a flattened SVG DOM to speed up selection. + std::deque nodes; + build_flat_item_list(&nodes, key, SP_GROUP(this->root), true, false, NULL); + for(int i = points.size()-1;i>=0; i--) { - SPItem *item = getItemAtPoint(key, points[i], - false, NULL); + SPItem *item = find_item_at_point(&nodes, key, points[i]); if (item && items.end()==find(items.begin(),items.end(), item)) items.push_back(item); } @@ -1472,7 +1482,11 @@ SPItem *SPDocument::getItemAtPoint( unsigned const key, Geom::Point const &p, { g_return_val_if_fail(this->priv != NULL, NULL); - return find_item_at_point(key, SP_GROUP(this->root), p, into_groups, false, upto); + // Build a flattened SVG DOM for find_item_at_point. + std::deque nodes; + build_flat_item_list(&nodes, key, SP_GROUP(this->root), into_groups, false, upto); + + return find_item_at_point(&nodes, key, p); } SPItem *SPDocument::getGroupAtPoint(unsigned int key, Geom::Point const &p) const @@ -1482,7 +1496,6 @@ SPItem *SPDocument::getGroupAtPoint(unsigned int key, Geom::Point const &p) cons return find_group_at_point(key, SP_GROUP(this->root), p); } - // Resource management bool SPDocument::addResource(gchar const *key, SPObject *object) -- cgit v1.2.3 From 43f80e25517651b82754e3b05303dacff0c03a10 Mon Sep 17 00:00:00 2001 From: Geoff Lankow Date: Tue, 7 Jul 2015 21:22:31 +1200 Subject: Read inkscape:color attribute on guides (bzr r14228.1.1) --- src/attributes.cpp | 1 + src/attributes.h | 1 + src/sp-guide.cpp | 5 +++++ src/sp-namedview.cpp | 1 - 4 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index af19360c1..991834cb2 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -125,6 +125,7 @@ static SPStyleProp const props[] = { /* SPGuide */ {SP_ATTR_ORIENTATION, "orientation"}, {SP_ATTR_POSITION, "position"}, + {SP_ATTR_INKSCAPE_COLOR, "inkscape:color"}, /* SPImage */ {SP_ATTR_X, "x"}, {SP_ATTR_Y, "y"}, diff --git a/src/attributes.h b/src/attributes.h index 7d6ea70a0..47f1388b0 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -127,6 +127,7 @@ enum SPAttributeEnum { /* SPGuide */ SP_ATTR_ORIENTATION, SP_ATTR_POSITION, + SP_ATTR_INKSCAPE_COLOR, /* SPImage */ SP_ATTR_X, SP_ATTR_Y, diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 4e1c5913d..83e723e5c 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -26,6 +26,7 @@ #include "display/sp-canvas.h" #include "display/guideline.h" #include "svg/svg.h" +#include "svg/svg-color.h" #include "svg/stringstream.h" #include "attributes.h" #include "sp-guide.h" @@ -70,6 +71,7 @@ void SPGuide::build(SPDocument *document, Inkscape::XML::Node *repr) { SPObject::build(document, repr); + this->readAttr( "inkscape:color" ); this->readAttr( "inkscape:label" ); this->readAttr( "orientation" ); this->readAttr( "position" ); @@ -95,6 +97,9 @@ void SPGuide::release() void SPGuide::set(unsigned int key, const gchar *value) { switch (key) { + case SP_ATTR_INKSCAPE_COLOR: + this->setColor(sp_svg_read_color(value, 0x0000ff00) | 0x7f); + break; case SP_ATTR_INKSCAPE_LABEL: if (this->label) g_free(this->label); diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 12c2cdf8e..1b5d9e3e2 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -247,7 +247,6 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) { SPGuide * g = SP_GUIDE(o); this->guides = g_slist_prepend(this->guides, g); //g_object_set(G_OBJECT(g), "color", nv->guidecolor, "hicolor", nv->guidehicolor, NULL); - g->setColor(this->guidecolor); g->setHiColor(this->guidehicolor); } } -- cgit v1.2.3 From c708f6f8ef412736862def24411cb1e7a86e6b27 Mon Sep 17 00:00:00 2001 From: Geoff Lankow Date: Sat, 11 Jul 2015 14:25:47 +1200 Subject: Read attribute after setting the default (bzr r14228.1.2) --- src/sp-guide.cpp | 5 +++-- src/sp-namedview.cpp | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 83e723e5c..b4f4cecc0 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -71,7 +71,6 @@ void SPGuide::build(SPDocument *document, Inkscape::XML::Node *repr) { SPObject::build(document, repr); - this->readAttr( "inkscape:color" ); this->readAttr( "inkscape:label" ); this->readAttr( "orientation" ); this->readAttr( "position" ); @@ -98,7 +97,9 @@ void SPGuide::release() void SPGuide::set(unsigned int key, const gchar *value) { switch (key) { case SP_ATTR_INKSCAPE_COLOR: - this->setColor(sp_svg_read_color(value, 0x0000ff00) | 0x7f); + if (value) { + this->setColor(sp_svg_read_color(value, 0x0000ff00) | 0x7f); + } break; case SP_ATTR_INKSCAPE_LABEL: if (this->label) g_free(this->label); diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 1b5d9e3e2..4b9429bc1 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -247,7 +247,10 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) { SPGuide * g = SP_GUIDE(o); this->guides = g_slist_prepend(this->guides, g); //g_object_set(G_OBJECT(g), "color", nv->guidecolor, "hicolor", nv->guidehicolor, NULL); + g->setColor(this->guidecolor); g->setHiColor(this->guidehicolor); + + g->readAttr( "inkscape:color" ); } } -- cgit v1.2.3 From 37450f60a28334989dd750880fa466acc90612c8 Mon Sep 17 00:00:00 2001 From: Geoff Lankow Date: Sun, 12 Jul 2015 16:46:51 +1200 Subject: Reread guide colour after setting default colour (bzr r14228.1.3) --- src/sp-namedview.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 4b9429bc1..29c528633 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -249,7 +249,6 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) { //g_object_set(G_OBJECT(g), "color", nv->guidecolor, "hicolor", nv->guidehicolor, NULL); g->setColor(this->guidecolor); g->setHiColor(this->guidehicolor); - g->readAttr( "inkscape:color" ); } } @@ -327,8 +326,9 @@ void SPNamedView::set(unsigned int key, const gchar* value) { } for (GSList *l = this->guides; l != NULL; l = l->next) { - //g_object_set(G_OBJECT(l->data), "color", nv->guidecolor, NULL); - SP_GUIDE(l->data)->setColor(this->guidecolor); + SPGuide * g = SP_GUIDE(l->data); + g->setColor(this->guidecolor); + g->readAttr("inkscape:color"); } this->requestModified(SP_OBJECT_MODIFIED_FLAG); @@ -338,8 +338,9 @@ void SPNamedView::set(unsigned int key, const gchar* value) { sp_nv_read_opacity(value, &this->guidecolor); for (GSList *l = this->guides; l != NULL; l = l->next) { - //g_object_set(G_OBJECT(l->data), "color", nv->guidecolor, NULL); - SP_GUIDE(l->data)->setColor(this->guidecolor); + SPGuide * g = SP_GUIDE(l->data); + g->setColor(this->guidecolor); + g->readAttr("inkscape:color"); } this->requestModified(SP_OBJECT_MODIFIED_FLAG); -- cgit v1.2.3 From 6699c5e9fbdae104044748ee6039a5e09d78f001 Mon Sep 17 00:00:00 2001 From: Geoff Lankow Date: Thu, 16 Jul 2015 00:23:14 +1200 Subject: Read inkscape:color attribute in more places (bzr r14228.1.4) --- src/sp-guide.cpp | 1 + src/sp-namedview.cpp | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index b4f4cecc0..b9c124138 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -71,6 +71,7 @@ void SPGuide::build(SPDocument *document, Inkscape::XML::Node *repr) { SPObject::build(document, repr); + this->readAttr( "inkscape:color" ); this->readAttr( "inkscape:label" ); this->readAttr( "orientation" ); this->readAttr( "position" ); diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 29c528633..b8554f352 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -665,6 +665,7 @@ void SPNamedView::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *r //g_object_set(G_OBJECT(g), "color", this->guidecolor, "hicolor", this->guidehicolor, NULL); g->setColor(this->guidecolor); g->setHiColor(this->guidehicolor); + g->readAttr("inkscape:color"); if (this->editable) { for (GSList *l = this->views; l != NULL; l = l->next) { -- cgit v1.2.3 From f873250f0c426d7b281acd37d65c4e549eb204a3 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Fri, 24 Jul 2015 21:38:06 +0200 Subject: Make persistence of snap indicator configurable, and clean up the snapping tab in the preferences dialog Fixed bugs: - https://launchpad.net/bugs/1420301 (bzr r14253) --- src/display/snap-indicator.cpp | 11 ++++++++--- src/ui/dialog/inkscape-preferences.cpp | 26 +++++++++++++++++++------- src/ui/dialog/inkscape-preferences.h | 1 + src/ui/tools/tool-base.h | 7 ++++++- src/ui/widget/preferences-widget.cpp | 1 + src/ui/widget/preferences-widget.h | 1 + 6 files changed, 36 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp index 926b35599..17deea16d 100644 --- a/src/display/snap-indicator.cpp +++ b/src/display/snap-indicator.cpp @@ -256,7 +256,12 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap "shape", SP_KNOT_SHAPE_CROSS, NULL ); - const int timeout_val = 4000; + double timeout_val = prefs->getDouble("/options/snapindicatorpersistence/value", 2.0); + if (timeout_val < 0.1) { + timeout_val = 0.1; // a zero value would mean infinite persistence (i.e. until new snap occurs) + // Besides, negatives values would ....? + } + // The snap indicator will be deleted after some time-out, and sp_canvas_item_dispose // will be called. This will set canvas->current_item to NULL if the snap indicator was @@ -272,7 +277,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap SP_CTRL(canvasitem)->pickable = false; SP_CTRL(canvasitem)->moveto(p.getPoint()); - _snaptarget = _desktop->add_temporary_canvasitem(canvasitem, timeout_val); + _snaptarget = _desktop->add_temporary_canvasitem(canvasitem, timeout_val*1000.0); _snaptarget_is_presnap = pre_snap; // Display the tooltip, which reveals the type of snap source and the type of snap target @@ -307,7 +312,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap SP_CANVASTEXT(canvas_tooltip)->anchor_position = TEXT_ANCHOR_CENTER; g_free(tooltip_str); - _snaptarget_tooltip = _desktop->add_temporary_canvasitem(canvas_tooltip, timeout_val); + _snaptarget_tooltip = _desktop->add_temporary_canvasitem(canvas_tooltip, timeout_val*1000.0); } // Display the bounding box, if we snapped to one diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 3b0731953..98695e080 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1229,26 +1229,38 @@ void InkscapePreferences::initPageBehavior() this->AddPage(_page_scrolling, _("Scrolling"), iter_behavior, PREFS_PAGE_BEHAVIOR_SCROLLING); // Snapping options + _page_snapping.add_group_header( _("Snap indicator")); + _snap_indicator.init( _("Enable snap indicator"), "/options/snapindicator/value", true); - _page_snapping.add_line( false, "", _snap_indicator, "", + _page_snapping.add_line( true, "", _snap_indicator, "", _("After snapping, a symbol is drawn at the point that has snapped")); - _snap_delay.init("/options/snapdelay/value", 0, 1000, 50, 100, 300, 0); - _page_snapping.add_line( false, _("_Delay (in ms):"), _snap_delay, "", - _("Postpone snapping as long as the mouse is moving, and then wait an additional fraction of a second. This additional delay is specified here. When set to zero or to a very small number, snapping will be immediate."), true); + _snap_indicator.changed_signal.connect( sigc::mem_fun(_snap_persistence, &Gtk::Widget::set_sensitive) ); + + _snap_persistence.init("/options/snapindicatorpersistence/value", 0.1, 10, 0.1, 1, 2, 1); + _page_snapping.add_line( true, _("Snap indicator persistence (in seconds):"), _snap_persistence, "", + _("Controls how long the snap indicator message will be shown, before it disappears"), true); + + _page_snapping.add_group_header( _("What should snap")); _snap_closest_only.init( _("Only snap the node closest to the pointer"), "/options/snapclosestonly/value", false); - _page_snapping.add_line( false, "", _snap_closest_only, "", + _page_snapping.add_line( true, "", _snap_closest_only, "", _("Only try to snap the node that is initially closest to the mouse pointer")); _snap_weight.init("/options/snapweight/value", 0, 1, 0.1, 0.2, 0.5, 1); - _page_snapping.add_line( false, _("_Weight factor:"), _snap_weight, "", + _page_snapping.add_line( true, _("_Weight factor:"), _snap_weight, "", _("When multiple snap solutions are found, then Inkscape can either prefer the closest transformation (when set to 0), or prefer the node that was initially the closest to the pointer (when set to 1)"), true); _snap_mouse_pointer.init( _("Snap the mouse pointer when dragging a constrained knot"), "/options/snapmousepointer/value", false); - _page_snapping.add_line( false, "", _snap_mouse_pointer, "", + _page_snapping.add_line( true, "", _snap_mouse_pointer, "", _("When dragging a knot along a constraint line, then snap the position of the mouse pointer instead of snapping the projection of the knot onto the constraint line")); + _page_snapping.add_group_header( _("Delayed snap")); + + _snap_delay.init("/options/snapdelay/value", 0, 1, 0.1, 0.2, 0.3, 1); + _page_snapping.add_line( true, _("Delay (in seconds):"), _snap_delay, "", + _("Postpone snapping as long as the mouse is moving, and then wait an additional fraction of a second. This additional delay is specified here. When set to zero or to a very small number, snapping will be immediate."), true); + this->AddPage(_page_snapping, _("Snapping"), iter_behavior, PREFS_PAGE_BEHAVIOR_SNAPPING); // Steps options diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index dcea91741..7e0184c55 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -322,6 +322,7 @@ protected: UI::Widget::PrefCheckButton _importexport_import_res_override; UI::Widget::PrefSlider _snap_delay; UI::Widget::PrefSlider _snap_weight; + UI::Widget::PrefSlider _snap_persistence; UI::Widget::PrefCheckButton _font_dialog; UI::Widget::PrefCombo _font_unit_type; UI::Widget::PrefCheckButton _font_output_px; diff --git a/src/ui/tools/tool-base.h b/src/ui/tools/tool-base.h index 7a6ab83e7..58eb6f88e 100644 --- a/src/ui/tools/tool-base.h +++ b/src/ui/tools/tool-base.h @@ -75,7 +75,12 @@ public: Inkscape::Preferences *prefs = Inkscape::Preferences::get(); double value = prefs->getDoubleLimited("/options/snapdelay/value", 0, 0, 1000); - _timer_id = g_timeout_add(value, &sp_event_context_snap_watchdog_callback, this); + // We used to have this specified in milliseconds; this has changed to seconds now for consistency's sake + if (value > 1) { // Apparently we have an old preference file, this value must have been in milliseconds; + value = value / 1000.0; // now convert this value to seconds + } + + _timer_id = g_timeout_add(value*1000.0, &sp_event_context_snap_watchdog_callback, this); _event = gdk_event_copy((GdkEvent*) event); ((GdkEventMotion *)_event)->time = GDK_CURRENT_TIME; diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp index 72597e4d9..e906762e3 100644 --- a/src/ui/widget/preferences-widget.cpp +++ b/src/ui/widget/preferences-widget.cpp @@ -205,6 +205,7 @@ void PrefCheckButton::init(Glib::ustring const &label, Glib::ustring const &pref void PrefCheckButton::on_toggled() { + this->changed_signal.emit(this->get_active()); if (this->get_visible()) //only take action if the user toggled it { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); diff --git a/src/ui/widget/preferences-widget.h b/src/ui/widget/preferences-widget.h index 8b75b8368..1d2d77699 100644 --- a/src/ui/widget/preferences-widget.h +++ b/src/ui/widget/preferences-widget.h @@ -59,6 +59,7 @@ class PrefCheckButton : public Gtk::CheckButton public: void init(Glib::ustring const &label, Glib::ustring const &prefs_path, bool default_value); + sigc::signal changed_signal; protected: Glib::ustring _prefs_path; void on_toggled(); -- cgit v1.2.3 From 1867f123d5c52008738a2873abda555d3bd882f3 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Fri, 24 Jul 2015 22:16:07 +0200 Subject: 3D box tool: the shift key must not prevent snapping of the vanishing point. It must only serve to separate the vanishing points, in case of multiple boxes sharing the same vanishing points Fixed bugs: - https://launchpad.net/bugs/1460415 (bzr r14254) --- src/vanishing-point.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp index 46f895c06..553e3a31d 100644 --- a/src/vanishing-point.cpp +++ b/src/vanishing-point.cpp @@ -130,7 +130,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g // FIXME: Do we need to create a new dragger as well? dragger->updateZOrders (); DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_3DBOX, - _("Split vanishing points")); + _("Split vanishing points")); return; } } @@ -175,22 +175,24 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g // as is currently the case. DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_3DBOX, - _("Merge vanishing points")); + _("Merge vanishing points")); return; } } + } - // We didn't snap to another dragger, so we'll try a regular snap - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - SnapManager &m = desktop->namedview->snap_manager; - m.setup(desktop); - Inkscape::SnappedPoint s = m.freeSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE)); - m.unSetup(); - if (s.getSnapped()) { - p = s.getPoint(); - knot->moveto(p); - } + // We didn't hit the return statement above, so we didn't snap to another dragger. Therefore we'll now try a regular snap + // Regardless of the status of the SHIFT key, we will try to snap; Here SHIFT does not disable snapping, as the shift key + // has a different purpose in this context (see above) + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); + Inkscape::SnappedPoint s = m.freeSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE)); + m.unSetup(); + if (s.getSnapped()) { + p = s.getPoint(); + knot->moveto(p); } dragger->point = p; // FIXME: Is dragger->point being used at all? @@ -241,7 +243,7 @@ vp_knot_ungrabbed_handler (SPKnot *knot, guint /*state*/, gpointer data) g_return_if_fail (dragger->parent); g_return_if_fail (dragger->parent->document); DocumentUndo::done(dragger->parent->document, SP_VERB_CONTEXT_3DBOX, - _("3D box: Move vanishing point")); + _("3D box: Move vanishing point")); } unsigned int VanishingPoint::global_counter = 0; @@ -630,7 +632,7 @@ VPDrag::updateBoxHandles () // FIXME: Is there a way to update the knots without accessing the // (previously) statically linked function KnotHolder::update_knots? - std::vector sel = selection->itemList(); + std::vector sel = selection->itemList(); if (sel.empty()) return; // no selection -- cgit v1.2.3 From 6a65a35182b059890732c0ddc9be9d0a3a37b941 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 25 Jul 2015 01:18:08 +0200 Subject: change from list to vector (bzr r13973.1.16) --- src/widgets/pencil-toolbar.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index a06d76d01..f2214bf49 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -246,10 +246,9 @@ static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tb gtk_adjustment_get_value(adj)); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop")); - std::list selected; - selected.insert >(selected.end(), desktop->getSelection()->itemList(), NULL); + std::vector selected = desktop->getSelection()->itemList(); if(!selected.empty()){ - for (std::list::iterator it(selected.begin()); it != selected.end(); ++it){ + for (std::vector::iterator it(selected.begin()); it != selected.end(); ++it){ SPLPEItem* lpeitem = dynamic_cast(*it); if (lpeitem && lpeitem->hasPathEffect()){ Inkscape::LivePathEffect::Effect* thisEffect = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY); -- cgit v1.2.3 From dc77ca9ec48c72a20fbd3f9ae038f41e01d98216 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sat, 25 Jul 2015 16:14:12 +0200 Subject: SPKnot no longer consumes all GDK_KEY_PRESS events Fixed bugs: - https://launchpad.net/bugs/1164964 (bzr r14255) --- src/knot.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/knot.cpp b/src/knot.cpp index b3813ab53..92d14afb9 100644 --- a/src/knot.cpp +++ b/src/knot.cpp @@ -206,6 +206,8 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot return true; } + bool key_press_event_unconsumed = FALSE; + knot_ref(knot); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -355,6 +357,7 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot break; default: consumed = FALSE; + key_press_event_unconsumed = TRUE; break; } break; @@ -364,7 +367,11 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot knot_unref(knot); - return consumed || grabbed; + if (key_press_event_unconsumed) { + return false; // e.g. in case "%" was pressed to toggle snapping, or Q for quick zoom (while dragging a handle) + } else { + return consumed || grabbed; + } } void sp_knot_handler_request_position(GdkEvent *event, SPKnot *knot) { -- cgit v1.2.3 From e54ebcdc4a05ada120a82c7d721044fdd4c205d0 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sat, 25 Jul 2015 16:23:16 +0200 Subject: Cleanup spurious indentation (bzr r14256) --- src/knot.cpp | 242 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 121 insertions(+), 121 deletions(-) (limited to 'src') diff --git a/src/knot.cpp b/src/knot.cpp index 92d14afb9..bfc0c4f0b 100644 --- a/src/knot.cpp +++ b/src/knot.cpp @@ -215,154 +215,154 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot switch (event->type) { case GDK_2BUTTON_PRESS: - if (event->button.button == 1) { - knot->doubleclicked_signal.emit(knot, event->button.state); + if (event->button.button == 1) { + knot->doubleclicked_signal.emit(knot, event->button.state); - grabbed = FALSE; - moved = FALSE; - consumed = TRUE; - } - break; + grabbed = FALSE; + moved = FALSE; + consumed = TRUE; + } + break; case GDK_BUTTON_PRESS: - if ((event->button.button == 1) && knot->desktop && knot->desktop->event_context && !knot->desktop->event_context->space_panning) { - Geom::Point const p = knot->desktop->w2d(Geom::Point(event->button.x, event->button.y)); - knot->startDragging(p, (gint) event->button.x, (gint) event->button.y, event->button.time); + if ((event->button.button == 1) && knot->desktop && knot->desktop->event_context && !knot->desktop->event_context->space_panning) { + Geom::Point const p = knot->desktop->w2d(Geom::Point(event->button.x, event->button.y)); + knot->startDragging(p, (gint) event->button.x, (gint) event->button.y, event->button.time); - consumed = TRUE; - } - break; + consumed = TRUE; + } + break; case GDK_BUTTON_RELEASE: - if (event->button.button == 1 && knot->desktop && knot->desktop->event_context && !knot->desktop->event_context->space_panning) { - // If we have any pending snap event, then invoke it now - if (knot->desktop->event_context->_delayed_snap_event) { - sp_event_context_snap_watchdog_callback(knot->desktop->event_context->_delayed_snap_event); - } - - sp_event_context_discard_delayed_snap_event(knot->desktop->event_context); - - knot->pressure = 0; - - if (transform_escaped) { - transform_escaped = false; - consumed = TRUE; - } else { - knot->setFlag(SP_KNOT_GRABBED, FALSE); - - if (!nograb) { - sp_canvas_item_ungrab(knot->item, event->button.time); - } + if (event->button.button == 1 && knot->desktop && knot->desktop->event_context && !knot->desktop->event_context->space_panning) { + // If we have any pending snap event, then invoke it now + if (knot->desktop->event_context->_delayed_snap_event) { + sp_event_context_snap_watchdog_callback(knot->desktop->event_context->_delayed_snap_event); + } - if (moved) { - knot->setFlag(SP_KNOT_DRAGGING, FALSE); + sp_event_context_discard_delayed_snap_event(knot->desktop->event_context); - knot->ungrabbed_signal.emit(knot, event->button.state); - } else { - knot->click_signal.emit(knot, event->button.state); - } + knot->pressure = 0; - grabbed = FALSE; - moved = FALSE; - consumed = TRUE; - } - } - if (tools_isactive(knot->desktop, TOOLS_NODES)) { - Inkscape::UI::Tools::NodeTool *nt = static_cast(knot->desktop->event_context); - nt->update_helperpath(); - } - break; - case GDK_MOTION_NOTIFY: - if (grabbed && knot->desktop && knot->desktop->event_context && !knot->desktop->event_context->space_panning) { + if (transform_escaped) { + transform_escaped = false; consumed = TRUE; + } else { + knot->setFlag(SP_KNOT_GRABBED, FALSE); - if ( within_tolerance - && ( abs( (gint) event->motion.x - xp ) < tolerance ) - && ( abs( (gint) event->motion.y - yp ) < tolerance ) ) { - break; // do not drag if we're within tolerance from origin + if (!nograb) { + sp_canvas_item_ungrab(knot->item, event->button.time); } - // 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 (moved) { + knot->setFlag(SP_KNOT_DRAGGING, FALSE); - if (gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &knot->pressure)) { - knot->pressure = CLAMP (knot->pressure, 0, 1); + knot->ungrabbed_signal.emit(knot, event->button.state); } else { - knot->pressure = 0.5; + knot->click_signal.emit(knot, event->button.state); } - if (!moved) { - knot->grabbed_signal.emit(knot, event->motion.state); + grabbed = FALSE; + moved = FALSE; + consumed = TRUE; + } + } + if (tools_isactive(knot->desktop, TOOLS_NODES)) { + Inkscape::UI::Tools::NodeTool *nt = static_cast(knot->desktop->event_context); + nt->update_helperpath(); + } + break; + case GDK_MOTION_NOTIFY: + if (grabbed && knot->desktop && knot->desktop->event_context && !knot->desktop->event_context->space_panning) { + consumed = TRUE; + + if ( within_tolerance + && ( abs( (gint) event->motion.x - xp ) < tolerance ) + && ( abs( (gint) event->motion.y - yp ) < tolerance ) ) { + break; // do not drag if we're within tolerance from origin + } - knot->setFlag(SP_KNOT_DRAGGING, TRUE); - } + // 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; - sp_event_context_snap_delay_handler(knot->desktop->event_context, NULL, knot, (GdkEventMotion *)event, Inkscape::UI::Tools::DelayedSnapEvent::KNOT_HANDLER); - sp_knot_handler_request_position(event, knot); - moved = TRUE; + if (gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &knot->pressure)) { + knot->pressure = CLAMP (knot->pressure, 0, 1); + } else { + knot->pressure = 0.5; } - if (tools_isactive(knot->desktop, TOOLS_NODES)) { - Inkscape::UI::Tools::NodeTool *nt = static_cast(knot->desktop->event_context); - nt->update_helperpath(); + + if (!moved) { + knot->grabbed_signal.emit(knot, event->motion.state); + + knot->setFlag(SP_KNOT_DRAGGING, TRUE); } - break; + + sp_event_context_snap_delay_handler(knot->desktop->event_context, NULL, knot, (GdkEventMotion *)event, Inkscape::UI::Tools::DelayedSnapEvent::KNOT_HANDLER); + sp_knot_handler_request_position(event, knot); + moved = TRUE; + } + if (tools_isactive(knot->desktop, TOOLS_NODES)) { + Inkscape::UI::Tools::NodeTool *nt = static_cast(knot->desktop->event_context); + nt->update_helperpath(); + } + break; case GDK_ENTER_NOTIFY: - knot->setFlag(SP_KNOT_MOUSEOVER, TRUE); - knot->setFlag(SP_KNOT_GRABBED, FALSE); + knot->setFlag(SP_KNOT_MOUSEOVER, TRUE); + knot->setFlag(SP_KNOT_GRABBED, FALSE); - if (knot->tip && knot->desktop && knot->desktop->event_context) { - knot->desktop->event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, knot->tip); - } + if (knot->tip && knot->desktop && knot->desktop->event_context) { + knot->desktop->event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, knot->tip); + } - grabbed = FALSE; - moved = FALSE; - consumed = TRUE; - break; + grabbed = FALSE; + moved = FALSE; + consumed = TRUE; + break; case GDK_LEAVE_NOTIFY: - knot->setFlag(SP_KNOT_MOUSEOVER, FALSE); - knot->setFlag(SP_KNOT_GRABBED, FALSE); + knot->setFlag(SP_KNOT_MOUSEOVER, FALSE); + knot->setFlag(SP_KNOT_GRABBED, FALSE); - if (knot->tip && knot->desktop && knot->desktop->event_context) { - knot->desktop->event_context->defaultMessageContext()->clear(); - } + if (knot->tip && knot->desktop && knot->desktop->event_context) { + knot->desktop->event_context->defaultMessageContext()->clear(); + } - grabbed = FALSE; - moved = FALSE; - consumed = TRUE; - break; + grabbed = FALSE; + moved = FALSE; + consumed = TRUE; + break; case GDK_KEY_PRESS: // keybindings for knot - switch (Inkscape::UI::Tools::get_group0_keyval(&event->key)) { - case GDK_KEY_Escape: - knot->setFlag(SP_KNOT_GRABBED, FALSE); - - if (!nograb) { - sp_canvas_item_ungrab(knot->item, event->button.time); - } - - if (moved) { - knot->setFlag(SP_KNOT_DRAGGING, FALSE); - - knot->ungrabbed_signal.emit(knot, event->button.state); - - DocumentUndo::undo(knot->desktop->getDocument()); - knot->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Node or handle drag canceled.")); - transform_escaped = true; - consumed = TRUE; - } - - grabbed = FALSE; - moved = FALSE; - - sp_event_context_discard_delayed_snap_event(knot->desktop->event_context); - break; - default: - consumed = FALSE; - key_press_event_unconsumed = TRUE; - break; - } - break; + switch (Inkscape::UI::Tools::get_group0_keyval(&event->key)) { + case GDK_KEY_Escape: + knot->setFlag(SP_KNOT_GRABBED, FALSE); + + if (!nograb) { + sp_canvas_item_ungrab(knot->item, event->button.time); + } + + if (moved) { + knot->setFlag(SP_KNOT_DRAGGING, FALSE); + + knot->ungrabbed_signal.emit(knot, event->button.state); + + DocumentUndo::undo(knot->desktop->getDocument()); + knot->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Node or handle drag canceled.")); + transform_escaped = true; + consumed = TRUE; + } + + grabbed = FALSE; + moved = FALSE; + + sp_event_context_discard_delayed_snap_event(knot->desktop->event_context); + break; + default: + consumed = FALSE; + key_press_event_unconsumed = TRUE; + break; + } + break; default: - break; + break; } knot_unref(knot); -- cgit v1.2.3 From 2416766e3b71f22adb6943495458697b1b958a08 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 25 Jul 2015 21:12:04 +0200 Subject: Removes extra unnecesary code pointed by Nathan Hurst (bzr r13973.1.19) --- src/widgets/pencil-toolbar.cpp | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index f2214bf49..4b177d3ad 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -247,20 +247,18 @@ static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tb g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop")); std::vector selected = desktop->getSelection()->itemList(); - if(!selected.empty()){ - for (std::vector::iterator it(selected.begin()); it != selected.end(); ++it){ - SPLPEItem* lpeitem = dynamic_cast(*it); - if (lpeitem && lpeitem->hasPathEffect()){ - Inkscape::LivePathEffect::Effect* thisEffect = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY); - if(thisEffect){ - Inkscape::LivePathEffect::LPESimplify *lpe = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); - if (lpe) { - double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); - tol = tol/(100.0*(101.0-tol)); - std::ostringstream ss; - ss << tol; - lpe->getRepr()->setAttribute("threshold", ss.str()); - } + for (std::vector::iterator it(selected.begin()); it != selected.end(); ++it){ + SPLPEItem* lpeitem = dynamic_cast(*it); + if (lpeitem && lpeitem->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY); + if(thisEffect){ + Inkscape::LivePathEffect::LPESimplify *lpe = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + if (lpe) { + double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); + tol = tol/(100.0*(101.0-tol)); + std::ostringstream ss; + ss << tol; + lpe->getRepr()->setAttribute("threshold", ss.str()); } } } -- cgit v1.2.3 From c7a58fa3190e53b2aaf2886ef3eb4dd0c7524bcd Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sat, 25 Jul 2015 21:52:00 +0200 Subject: =?UTF-8?q?Fix=20snapping=20of=20start=20point=20of=20path=20when?= =?UTF-8?q?=20holding=20the=20CTRL=20key=20in=20the=20B=C3=A9zier=20tool?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed bugs: - https://launchpad.net/bugs/1432354 (bzr r14257) --- src/ui/tools/pen-tool.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 827dbf5c3..d924d8773 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -268,6 +268,9 @@ void PenTool::_endpointSnap(Geom::Point &p, guint const state) const { if ((state & GDK_CONTROL_MASK) && !this->polylines_paraxial) { //CTRL enables angular snapping if (this->npoints > 0) { spdc_endpoint_snap_rotation(this, p, this->p[0], state); + } else { + boost::optional origin = boost::optional(); + spdc_endpoint_snap_free(this, p, origin, state); } } else { // We cannot use shift here to disable snapping because the shift-key is already used -- cgit v1.2.3 From 839c74d60e8c1dd4e2be802130905bafff934647 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 26 Jul 2015 12:53:15 +0200 Subject: Commented out tidy_operator_styled_whitespace (fixes bug 1477723). Fixed bugs: - https://launchpad.net/bugs/1477723 (bzr r14258) --- src/text-editing.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/text-editing.cpp b/src/text-editing.cpp index 050e223eb..d9cebc625 100644 --- a/src/text-editing.cpp +++ b/src/text-editing.cpp @@ -1805,6 +1805,14 @@ static bool tidy_operator_redundant_semi_nesting(SPObject **item, bool /*has_tex return false; } + +/* tidy_operator_styled_whitespace commented out: not only did it have bugs, + * but it did *not* preserve the rendering: spaces in different font sizes, + * for instance, have different width, so moving them out of tspans changes + * the document. cf https://bugs.launchpad.net/inkscape/+bug/1477723 +*/ + +#if 0 /** helper for tidy_operator_styled_whitespace(), finds the last string object in a paragraph which is not \a not_obj. */ static SPString* find_last_string_child_not_equal_to(SPObject *root, SPObject *not_obj) @@ -1883,6 +1891,7 @@ static bool tidy_operator_styled_whitespace(SPObject **item, bool has_text_decor delete_obj->deleteObject(); return true; } +#endif /* possible tidy operators that are not yet implemented, either because they are difficult, occur infrequently, or because I'm not sure that the @@ -1917,8 +1926,7 @@ static bool tidy_xml_tree_recursively(SPObject *root, bool has_text_decoration) tidy_operator_repeated_spans, tidy_operator_excessive_nesting, tidy_operator_redundant_double_nesting, - tidy_operator_redundant_semi_nesting, - tidy_operator_styled_whitespace + tidy_operator_redundant_semi_nesting }; bool changes = false; -- cgit v1.2.3 From 6fd1a081d166d88200a22a89928bdca9192b1491 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 27 Jul 2015 02:04:29 +0200 Subject: add flattern button to interactive simplify (bzr r14261) --- src/live_effects/lpe-simplify.cpp | 1 + src/widgets/pencil-toolbar.cpp | 50 ++++++++++++++++++++++++++++++++++++++- src/widgets/toolbox.cpp | 1 + 3 files changed, 51 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 265192a17..f6842a030 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -82,6 +82,7 @@ LPESimplify::newWidget() { // use manage here, because after deletion of Effect object, others might still be pointing to this widget. Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); + vbox->set_border_width(5); vbox->set_homogeneous(false); vbox->set_spacing(2); diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index 4b177d3ad..c889436b9 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -30,6 +30,7 @@ #include #include +#include #include "pencil-toolbar.h" #include "desktop.h" @@ -45,9 +46,11 @@ #include "ui/uxmanager.h" #include "widgets/spinbutton-events.h" #include +#include "live_effects/effect.h" #include "live_effects/lpe-simplify.h" #include "live_effects/effect-enum.h" #include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" #include "sp-lpe-item.h" #include "util/glib-list-iterators.h" @@ -233,6 +236,41 @@ static void sp_pencil_tb_defaults(GtkWidget * /*widget*/, GObject *obj) spinbutton_defocus(tbl); } +static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj) +{ + SPDesktop *desktop = static_cast(g_object_get_data(obj, "desktop")); + std::vector selected = desktop->getSelection()->itemList(); + for (std::vector::iterator it(selected.begin()); it != selected.end(); ++it){ + SPLPEItem* lpeitem = dynamic_cast(*it); + if (lpeitem && lpeitem->hasPathEffect()){ + PathEffectList lpelist = lpeitem->getEffectList(); + std::list::iterator i; + for (i = lpelist.begin(); i != lpelist.end(); ++i) { + LivePathEffectObject *lpeobj = (*i)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (dynamic_cast(lpe)) { + SPShape * shape = dynamic_cast(lpeitem); + if(shape){ + SPCurve * c = shape->getCurveBeforeLPE(); + lpe->doEffect(c); + lpeitem->setCurrentPathEffect(*i); + if (lpelist.size() > 1){ + lpeitem->removeCurrentPathEffect(true); + shape->setCurveBeforeLPE(c); + } else { + lpeitem->removeCurrentPathEffect(false); + shape->setCurve(c,0); + } + break; + } + } + } + } + } + } +} + static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tbl) { // quit if run by the attr_changed listener @@ -255,7 +293,7 @@ static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tb Inkscape::LivePathEffect::LPESimplify *lpe = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); if (lpe) { double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); - tol = tol/(100.0*(101.0-tol)); + tol = tol/(100.0*(102.0-tol)); std::ostringstream ss; ss << tol; lpe->getRepr()->setAttribute("threshold", ss.str()); @@ -346,6 +384,16 @@ void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(freehand_simplify_lpe), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); } + /* LPE simplify flatten */ + { + InkAction* inky = ink_action_new( "PencilLpeSimplifyFlatten", + _("LPE simplify flatten"), + _("LPE simplify flatten"), + INKSCAPE_ICON("flatten_simplify"), + Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_simplify_flatten), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 62e4bcb8b..cdf39e9ef 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -399,6 +399,7 @@ static gchar const * ui_descr = " " " " " " + " " " " " " " " -- cgit v1.2.3 From 3f83712a0ae1400d8ffa8dc0d40247b78f6d1a7a Mon Sep 17 00:00:00 2001 From: jtx Date: Mon, 27 Jul 2015 12:21:31 +0200 Subject: Fix LPE stack in interactive simplify (bzr r14262) --- src/ui/tools/freehand-base.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 865ee760e..2d742b6bf 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -288,6 +288,14 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (item && SP_IS_LPE_ITEM(item)) { + bool simplify = prefs->getInt(tool_name(dc) + "/simplify", 0); + if(simplify){ + double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); + tol = tol/(100.0*(102.0-tol)); + std::ostringstream ss; + ss << tol; + spdc_apply_simplify(ss.str(), dc, item); + } if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } @@ -303,14 +311,6 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, shapeType shape = (shapeType)prefs->getInt(tool_name(dc) + "/shape", 0); - bool simplify = prefs->getInt(tool_name(dc) + "/simplify", 0); - if(simplify){ - double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); - tol = tol/(100.0*(101.0-tol)); - std::ostringstream ss; - ss << tol; - spdc_apply_simplify(ss.str(), dc, item); - } bool shape_applied = false; SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); const char *cstroke = sp_repr_css_property(css_item, "stroke", "none"); -- cgit v1.2.3 From e252d27fc3e3f80c7f9745286992dfa06925d42e Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Mon, 27 Jul 2015 21:31:56 +0200 Subject: + NULL check (fixes bug #1474011 : Segmentation fault in sp_filter_primitive_read_in) (bzr r14263) --- src/sp-filter-primitive.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-filter-primitive.cpp b/src/sp-filter-primitive.cpp index 1f85c8193..2e57cbfd7 100644 --- a/src/sp-filter-primitive.cpp +++ b/src/sp-filter-primitive.cpp @@ -194,7 +194,9 @@ Inkscape::XML::Node* SPFilterPrimitive::write(Inkscape::XML::Document *doc, Inks int sp_filter_primitive_read_in(SPFilterPrimitive *prim, gchar const *name) { - if (!name) return Inkscape::Filters::NR_FILTER_SLOT_NOT_SET; + if (!name | !prim){ + return Inkscape::Filters::NR_FILTER_SLOT_NOT_SET; + } // TODO: are these case sensitive or not? (assumed yes) switch (name[0]) { case 'S': -- cgit v1.2.3 From a0de7d964dc4d7ae0d3c280d5f9463e63c964ae9 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 27 Jul 2015 16:32:00 -0400 Subject: \n (bzr r14266) --- src/sp-factory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-factory.cpp b/src/sp-factory.cpp index 55e673c4a..84329eaaf 100644 --- a/src/sp-factory.cpp +++ b/src/sp-factory.cpp @@ -297,7 +297,7 @@ SPObject *SPFactory::createObject(std::string const& id) else if (id.empty()) // comments {} else { - fprintf(stderr, "WARNING: unknown type: %s", id.c_str()); + fprintf(stderr, "WARNING: unknown type: %s\n", id.c_str()); } return ret; -- cgit v1.2.3 From 190eee4ce82f084b4903a0c585053c02bfde02da Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 27 Jul 2015 16:33:14 -0400 Subject: || (bzr r14267) --- src/sp-filter-primitive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-filter-primitive.cpp b/src/sp-filter-primitive.cpp index 2e57cbfd7..b18850914 100644 --- a/src/sp-filter-primitive.cpp +++ b/src/sp-filter-primitive.cpp @@ -194,7 +194,7 @@ Inkscape::XML::Node* SPFilterPrimitive::write(Inkscape::XML::Document *doc, Inks int sp_filter_primitive_read_in(SPFilterPrimitive *prim, gchar const *name) { - if (!name | !prim){ + if (!name || !prim){ return Inkscape::Filters::NR_FILTER_SLOT_NOT_SET; } // TODO: are these case sensitive or not? (assumed yes) -- cgit v1.2.3 From ac1d540f5e5dae805c051829fe10e76035238c6c Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Wed, 29 Jul 2015 22:51:14 +0200 Subject: fix for a small warning introduced in r14142 (cf ) (bzr r14268) --- src/sp-item.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 410fd9b37..4937e6c76 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -351,8 +351,8 @@ void SPItem::lowerToBottom() { SPObject * bottom=parent->firstChild(); while(dynamic_cast(bottom) && dynamic_cast(bottom->next) && bottom!=this && !is_item(*(bottom->next))) bottom=bottom->next; - if (bottom) { - Inkscape::XML::Node *ref = ( bottom ? bottom->getRepr() : NULL ); + if (bottom && bottom != this) { + Inkscape::XML::Node *ref = bottom->getRepr() ; parent->getRepr()->changeOrder(getRepr(), ref); } } -- cgit v1.2.3 From 56e98c4508ce491ce5d8406914e6b192de72fe6f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 31 Jul 2015 00:59:02 +0200 Subject: Fixed bugs in branch review and updated to new api (bzr r13879.1.20) --- src/live_effects/lpe-transform_2pts.cpp | 143 ++++++++++++++++++-------------- src/live_effects/lpe-transform_2pts.h | 12 ++- 2 files changed, 88 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 4b0cbadbb..d2c2cfc0e 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -15,7 +15,7 @@ #include "live_effects/lpe-transform_2pts.h" #include "display/curve.h" #include <2geom/transforms.h> -#include <2geom/path.h> +#include <2geom/pathvector.h> #include "sp-path.h" #include "ui/icon-names.h" @@ -31,10 +31,10 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : end(_("End"), _("End point"), "end", &wr, this, "End point"), first_knot(_("First Knot"), _("First Knot"), "first_knot", &wr, this, 1), last_knot(_("Last Knot"), _("Last Knot"), "last_knot", &wr, this, 1), - from_original_width_toogler(false), - point_a(Geom::Point(0,0)), - point_b(Geom::Point(0,0)), - curve_c(NULL), + from_original_width_toggler(false), + point_a(Geom::Point()), + point_b(Geom::Point()), + pathvector(), append_path(false) { registerParameter(&start); @@ -60,14 +60,14 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) point_a = Point(boundingbox_X.min(), boundingbox_Y.middle()); point_b = Point(boundingbox_X.max(), boundingbox_Y.middle()); SPLPEItem * splpeitem = const_cast(lpeitem); - SPPath *path = dynamic_cast(splpeitem); - if (path) { - curve_c = path->get_original_curve(); + SPPath *sp_path = dynamic_cast(splpeitem); + if (sp_path) { + pathvector = sp_path->get_original_curve()->get_pathvector(); } - if(curve_c && !curve_c->is_closed() && curve_c->first_path() == curve_c->last_path()) { - point_a = *(curve_c->first_point()); - point_b = *(curve_c->last_point()); - int nnodes = (int)curve_c->nodes_in_path(); + if(!pathvector.empty()) { + point_a = pathvector.initialPoint(); + point_b = pathvector.finalPoint(); + size_t nnodes = nodeCount(pathvector); last_knot.param_set_value(nnodes); } start.param_update_default(point_a); @@ -85,41 +85,22 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) point_b = Point(boundingbox_X.max(), boundingbox_Y.middle()); SPLPEItem * splpeitem = const_cast(lpeitem); - SPPath *path = dynamic_cast(splpeitem); - if (path) { - curve_c = path->get_original_curve(); + SPPath *sp_path = dynamic_cast(splpeitem); + if (sp_path) { + pathvector = sp_path->get_original_curve()->get_pathvector(); } - if(from_original_width_toogler != from_original_width) { - from_original_width_toogler = from_original_width; + if(from_original_width_toggler != from_original_width) { + from_original_width_toggler = from_original_width; reset(); } - if(curve_c && !from_original_width) { - if(!curve_c->is_closed() && curve_c->first_path() == curve_c->last_path()) { - append_path = false; - Geom::PathVector const originalPV = curve_c->get_pathvector(); - point_a = originalPV[0][0].initialPoint(); - if((int)first_knot > 1) { - point_a = originalPV[0][(int)first_knot-2].finalPoint(); - } - point_b = originalPV[0][0].initialPoint(); - if((int)last_knot > 1) { - point_b = originalPV[0][(int)last_knot-2].finalPoint(); - } - int nnodes = (int)curve_c->nodes_in_path(); - first_knot.param_set_range(1, last_knot-1); - last_knot.param_set_range(first_knot+1, nnodes); - from_original_width.param_setValue(false); - } else { - first_knot.param_set_value(1); - last_knot.param_set_value(2); - first_knot.param_set_range(1,1); - last_knot.param_set_range(2,2); - if(append_path == false) { - append_path = true; - } else { - from_original_width.param_setValue(true); - } - } + if(!pathvector.empty() && !from_original_width) { + append_path = false; + point_a = pointAtNodeIndex(pathvector,(size_t)first_knot-1); + point_b = pointAtNodeIndex(pathvector,(size_t)last_knot-1); + size_t nnodes = nodeCount(pathvector); + first_knot.param_set_range(1, last_knot-1); + last_knot.param_set_range(first_knot+1, nnodes); + from_original_width.param_setValue(false); } else { first_knot.param_set_value(1); last_knot.param_set_value(2); @@ -135,24 +116,17 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) void LPETransform2Pts::updateIndex() { - SPCurve * curve2 = NULL; - SPShape *shape = SP_SHAPE(sp_lpe_item); - if (shape) { - curve2 = shape->getCurve(); + SPLPEItem * splpeitem = const_cast(sp_lpe_item); + SPPath *sp_path = dynamic_cast(splpeitem); + if (sp_path) { + pathvector = sp_path->get_original_curve()->get_pathvector(); } - if(curve2 && !from_original_width && !curve_c->is_closed() && curve_c->first_path() == curve_c->last_path()) { - Geom::PathVector const originalPV = curve2->get_pathvector(); - Geom::Point point_c = originalPV[0][0].initialPoint(); - Geom::Point point_d = originalPV[0][0].initialPoint(); - if((int)first_knot > 1) { - point_c = originalPV[0][(int)first_knot-2].finalPoint(); - } - if((int)last_knot > 1) { - point_d = originalPV[0][(int)last_knot-2].finalPoint(); - } - start.param_update_default(point_c); + if(!pathvector.empty() && !from_original_width) { + point_a = pointAtNodeIndex(pathvector,(size_t)first_knot-1); + point_b = pointAtNodeIndex(pathvector,(size_t)last_knot-1); + start.param_update_default(point_a); start.param_set_default(); - end.param_update_default(point_d); + end.param_update_default(point_b); end.param_set_default(); start.param_update_default(point_a); end.param_update_default(point_b); @@ -160,20 +134,61 @@ LPETransform2Pts::updateIndex() end.param_set_default(); } } +//todo migrate to PathVector class? +size_t +LPETransform2Pts::nodeCount(Geom::PathVector pathvector) const +{ + size_t n = 0; + for (Geom::PathVector::iterator it = pathvector.begin(); it != pathvector.end(); ++it) { + n += it->size_closed(); + } + return n; +} +//todo migrate to PathVector class? +Geom::Point +LPETransform2Pts::pointAtNodeIndex(Geom::PathVector pathvector, size_t index) const +{ + size_t n = 0; + for (Geom::PathVector::iterator pv_it = pathvector.begin(); pv_it != pathvector.end(); ++pv_it) { + for (Geom::Path::iterator curve_it = pv_it->begin(); curve_it != pv_it->end_closed(); ++curve_it) { + if(index == n){ + return curve_it->initialPoint(); + } + n++; + } + } + return Geom::Point(); +} +//todo migrate to PathVector class? Not used +Geom::Path +LPETransform2Pts::pathAtNodeIndex(Geom::PathVector pathvector, size_t index) const +{ + size_t n = 0; + for (Geom::PathVector::iterator pv_it = pathvector.begin(); pv_it != pathvector.end(); ++pv_it) { + for (Geom::Path::iterator curve_it = pv_it->begin(); curve_it != pv_it->end_closed(); ++curve_it) { + if(index == n){ + return *pv_it; + } + n++; + } + } + return Geom::Path(); +} + void LPETransform2Pts::reset() { point_a = Geom::Point(boundingbox_X.min(), boundingbox_Y.middle()); point_b = Geom::Point(boundingbox_X.max(), boundingbox_Y.middle()); - if(curve_c && !curve_c->is_closed() && curve_c->first_path() == curve_c->last_path() && !from_original_width) { - int nnodes = (int)curve_c->nodes_in_path(); + if(!pathvector.empty() && !from_original_width) { + size_t nnodes = nodeCount(pathvector); first_knot.param_set_range(1, last_knot-1); last_knot.param_set_range(first_knot+1, nnodes); first_knot.param_set_value(1); last_knot.param_set_value(nnodes); - point_a = *(curve_c->first_point()); - point_b = *(curve_c->last_point()); + point_a = pathvector.initialPoint(); + point_b = pathvector.finalPoint(); } else { first_knot.param_set_value(1); last_knot.param_set_value(2); diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index c4a993acc..855780a7a 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -33,9 +33,15 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual Gtk::Widget *newWidget(); + void updateIndex(); - virtual Gtk::Widget *newWidget(); + size_t nodeCount(Geom::PathVector pathvector) const; + + Geom::Point pointAtNodeIndex(Geom::PathVector pathvector, size_t index) const; + + Geom::Path pathAtNodeIndex(Geom::PathVector pathvector, size_t index) const; void reset(); @@ -48,10 +54,10 @@ private: PointParam end; ScalarParam first_knot; ScalarParam last_knot; - bool from_original_width_toogler; + bool from_original_width_toggler; Geom::Point point_a; Geom::Point point_b; - SPCurve * curve_c; + Geom::PathVector pathvector; bool append_path; LPETransform2Pts(const LPETransform2Pts&); LPETransform2Pts& operator=(const LPETransform2Pts&); -- cgit v1.2.3 From d75d9a6b3f33a3d901b8bc0d1d37b0f6af8d2766 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sat, 1 Aug 2015 11:14:20 +0200 Subject: fix for 1478636 (crash on import when comments in defs) Fixed bugs: - https://launchpad.net/bugs/1478636 (bzr r14270) --- src/document.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index ebf5d312f..2ea969910 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1640,7 +1640,7 @@ void SPDocument::importDefs(SPDocument *source) prevent_id_clashes(source, this); for (std::vector::iterator defs = defsNodes.begin(); defs != defsNodes.end(); ++defs) { - importDefsNode(source, const_cast(*defs), target_defs); + importDefsNode(source, const_cast(*defs), target_defs); } } @@ -1688,11 +1688,10 @@ void SPDocument::importDefsNode(SPDocument *source, Inkscape::XML::Node *defs, I /* First pass: remove duplicates in clipboard of definitions in document */ for (Inkscape::XML::Node *def = defs->firstChild() ; def ; def = def->next()) { - + if(def->type() != Inkscape::XML::ELEMENT_NODE)continue; /* If this clipboard has been pasted into one document, and is now being pasted into another, or pasted again into the same, it will already have been processed. If we detect that then skip the rest of this pass. */ - Glib::ustring defid = def->attribute("id"); if( defid.find( DuplicateDefString ) != Glib::ustring::npos )break; @@ -1722,6 +1721,7 @@ void SPDocument::importDefsNode(SPDocument *source, Inkscape::XML::Node *defs, I /* Second pass: remove duplicates in clipboard of earlier definitions in clipboard */ for (Inkscape::XML::Node *def = defs->firstChild() ; def ; def = def->next()) { + if(def->type() != Inkscape::XML::ELEMENT_NODE)continue; Glib::ustring defid = def->attribute("id"); if( defid.find( DuplicateDefString ) != Glib::ustring::npos )continue; // this one already handled SPObject *src = source->getObjectByRepr(def); @@ -1749,6 +1749,7 @@ void SPDocument::importDefsNode(SPDocument *source, Inkscape::XML::Node *defs, I /* Final pass: copy over those parts which are not duplicates */ for (Inkscape::XML::Node *def = defs->firstChild() ; def ; def = def->next()) { + if(def->type() != Inkscape::XML::ELEMENT_NODE)continue; /* Ignore duplicate defs marked in the first pass */ Glib::ustring defid = def->attribute("id"); -- cgit v1.2.3 From aeedb1dda68d5529363a144c13d26f8804da4c64 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 1 Aug 2015 16:27:30 +0200 Subject: Update simplify interactive to handle trinagle out powerstrokes, also fix it for Spiro paths. Updated toolbar slider to also update powerstroke points (bzr r14271) --- src/ui/tools/freehand-base.cpp | 12 +++++++----- src/widgets/pencil-toolbar.cpp | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index fa45d8dbb..f4ad284c7 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -289,7 +289,7 @@ static void spdc_apply_simplify(std::string threshold, FreehandBase *dc, SPItem Effect::createAndApply(SIMPLIFY, dc->desktop->doc(), item); Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); - // write powerstroke parameters: + // write simplify parameters: lpe->getRepr()->setAttribute("steps", "1"); lpe->getRepr()->setAttribute("threshold", threshold); lpe->getRepr()->setAttribute("smooth_angles", "360"); @@ -314,20 +314,22 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, std::ostringstream ss; ss << tol; spdc_apply_simplify(ss.str(), dc, item); + sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); } if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - //add the bspline node in the waiting effects + if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } + SPShape *sp_shape = dynamic_cast(item); + if (sp_shape) { + curve = sp_shape->getCurve(); + } //Store the clipboard path to apply in the future without the use of clipboard - static Geom::PathVector previous_shape_pathv; - - shapeType shape = (shapeType)prefs->getInt(tool_name(dc) + "/shape", 0); bool shape_applied = false; diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index aef9b4560..17c1d341d 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -46,8 +46,10 @@ #include "ui/uxmanager.h" #include "widgets/spinbutton-events.h" #include +#include "display/curve.h" #include "live_effects/effect.h" #include "live_effects/lpe-simplify.h" +#include "live_effects/lpe-powerstroke.h" #include "live_effects/effect-enum.h" #include "live_effects/lpeobject.h" #include "live_effects/lpeobject-reference.h" @@ -289,15 +291,42 @@ static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tb for (std::vector::iterator it(selected.begin()); it != selected.end(); ++it){ SPLPEItem* lpeitem = dynamic_cast(*it); if (lpeitem && lpeitem->hasPathEffect()){ - Inkscape::LivePathEffect::Effect* thisEffect = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY); - if(thisEffect){ - Inkscape::LivePathEffect::LPESimplify *lpe = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); - if (lpe) { + Inkscape::LivePathEffect::Effect* simplify = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY); + if(simplify){ + Inkscape::LivePathEffect::LPESimplify *lpe_simplify = dynamic_cast(simplify->getLPEObj()->get_lpe()); + if (lpe_simplify) { double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); tol = tol/(100.0*(102.0-tol)); std::ostringstream ss; ss << tol; - lpe->getRepr()->setAttribute("threshold", ss.str()); + Inkscape::LivePathEffect::Effect* powerstroke = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::POWERSTROKE); + bool simplified = false; + if(powerstroke){ + Inkscape::LivePathEffect::LPEPowerStroke *lpe_powerstroke = dynamic_cast(powerstroke->getLPEObj()->get_lpe()); + if(lpe_powerstroke){ + lpe_powerstroke->getRepr()->setAttribute("is_visible", "false"); + sp_lpe_item_update_patheffect(lpeitem, false, false); + SPShape *sp_shape = dynamic_cast(lpeitem); + if (sp_shape) { + guint previous_curve_length = sp_shape->getCurve()->get_segment_count(); + lpe_simplify->getRepr()->setAttribute("threshold", ss.str()); + sp_lpe_item_update_patheffect(lpeitem, false, false); + simplified = true; + guint curve_length = sp_shape->getCurve()->get_segment_count(); + std::vector ts = lpe_powerstroke->offset_points.data(); + double factor = (double)curve_length/ (double)previous_curve_length; + for (size_t i = 0; i < ts.size(); i++) { + ts[i][Geom::X] = ts[i][Geom::X] * factor; + } + lpe_powerstroke->offset_points.param_setValue(ts); + } + lpe_powerstroke->getRepr()->setAttribute("is_visible", "true"); + sp_lpe_item_update_patheffect(lpeitem, false, false); + } + } + if(!simplified){ + lpe_simplify->getRepr()->setAttribute("threshold", ss.str()); + } } } } -- cgit v1.2.3 From d141eb2df3805c3049b863c1bf8429bed9d0763d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 2 Aug 2015 13:29:25 +0200 Subject: Fixed some typos in bsector and bspline In freehand base fix a crash un bend path if no clipboard. Also rewrite retrive clipboard to get it at correct document size (bzr r14272) --- src/live_effects/lpe-angle_bisector.cpp | 2 +- src/live_effects/lpe-bspline.cpp | 1 + src/ui/tools/freehand-base.cpp | 46 ++++++++++++++++++++++----------- 3 files changed, 33 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-angle_bisector.cpp b/src/live_effects/lpe-angle_bisector.cpp index 95a81c763..900d29e3a 100644 --- a/src/live_effects/lpe-angle_bisector.cpp +++ b/src/live_effects/lpe-angle_bisector.cpp @@ -38,7 +38,7 @@ public: virtual Geom::Point knot_get() const; }; -} // namespace TtC +} // namespace AB LPEAngleBisector::LPEAngleBisector(LivePathEffectObject *lpeobject) : Effect(lpeobject), diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index c2a2d080e..6575700c7 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -245,6 +245,7 @@ LPEBSpline::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vectordesktop->doc(), item); - Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); - static_cast(lpe)->pattern.on_paste_button_click(); + // take shape from clipboard; Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); Glib::ustring svgd = cm->getPathParameter(SP_ACTIVE_DESKTOP); - previous_shape_pathv = sp_svg_read_pathv(svgd.data()); - - shape_applied = true; + if(svgd != ""){ + previous_shape_pathv = sp_svg_read_pathv(svgd.data()); + Inkscape::XML::Node *nv_repr = SP_ACTIVE_DESKTOP->getNamedView()->getRepr(); + if (nv_repr->attribute("inkscape:document-units")){ + double scale_units = Inkscape::Util::Quantity::convert(1, "px", nv_repr->attribute("inkscape:document-units")); + if (!Geom::are_near(scale_units, 1.0, Geom::EPSILON)) { + previous_shape_pathv *= Geom::Scale(scale_units); + } + } + SPCurve const *c = new SPCurve(previous_shape_pathv); + spdc_paste_curve_as_freehand_shape(c, dc, item); + shape_applied = true; + } else { + shape = NONE; + } break; } case BEND_CLIPBOARD: @@ -413,10 +423,14 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, path *= item->i2doc_affine().inverse(); svgd = sp_svg_write_path( path ); bend_item = dc->selection->singleItem(); - bend_item->moveTo(item,false); - spdc_apply_bend_shape(svgd, dc, bend_item); - bend_item->transform = Geom::Affine(1,0,0,1,0,0); - dc->selection->add(SP_OBJECT(bend_item)); + if(bend_item){ + bend_item->moveTo(item,false); + spdc_apply_bend_shape(svgd, dc, bend_item); + bend_item->transform = Geom::Affine(1,0,0,1,0,0); + dc->selection->add(SP_OBJECT(bend_item)); + } else { + shape = NONE; + } } else { shape = NONE; } @@ -444,10 +458,12 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, sp_selection_duplicate(dc->desktop); dc->selection->remove(SP_OBJECT(bend_item)); bend_item = dc->selection->singleItem(); - bend_item->moveTo(item,false); - spdc_apply_bend_shape(svgd, dc, bend_item); - bend_item->transform = Geom::Affine(1,0,0,1,0,0); - dc->selection->add(SP_OBJECT(bend_item)); + if(bend_item){ + bend_item->moveTo(item,false); + spdc_apply_bend_shape(svgd, dc, bend_item); + bend_item->transform = Geom::Affine(1,0,0,1,0,0); + dc->selection->add(SP_OBJECT(bend_item)); + } } shape = BEND_CLIPBOARD; } -- cgit v1.2.3 From 19f8cf337ab1ceed9c654bb48b210fd9b391fcc8 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 2 Aug 2015 13:33:58 +0200 Subject: Added point parameter (bzr r14272.1.1) --- src/live_effects/lpe-bendpath.cpp | 43 +++++++++++++++++++++++- src/live_effects/lpe-bendpath.h | 14 ++++++-- src/live_effects/lpe-patternalongpath.cpp | 56 +++++++++++++++++++++++++++++-- src/live_effects/lpe-patternalongpath.h | 12 ++++++- 4 files changed, 118 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 33171b184..364c77ccb 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -48,17 +48,23 @@ first) but I think we can first forget about them. namespace Inkscape { namespace LivePathEffect { + LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) : Effect(lpeobject), bend_path(_("Bend path:"), _("Path along which to bend the original path"), "bendpath", &wr, this, "M0,0 L1,0"), prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1), scale_y_rel(_("W_idth in units of length"), _("Scale the width of the path in units of its length"), "scale_y_rel", &wr, this, false), - vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false) + vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false), + width(_("Width distance"), _("Change the width of bend path - Ctrl+Alt+Click: reset"), "width", &wr, this), + height(0), + original_height(0), + prop_scale_previous(1) { registerParameter( dynamic_cast(&bend_path) ); registerParameter( dynamic_cast(&prop_scale) ); registerParameter( dynamic_cast(&scale_y_rel) ); registerParameter( dynamic_cast(&vertical_pattern) ); + registerParameter( dynamic_cast(&width) ); prop_scale.param_set_digits(3); prop_scale.param_set_increments(0.01, 0.10); @@ -74,8 +80,38 @@ LPEBendPath::~LPEBendPath() void LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) { + hp.clear(); // get the item bounding box original_bbox(lpeitem); + original_height = boundingbox_Y.max() - boundingbox_Y.min(); + bool prop_scale_modified = false; + + Geom::Path path_in = bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); + Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); + Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in.curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints((*cubic)[1], ptA); + } + if(height == 0){ + height = original_height; + width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), (original_height/2.0)) + ptA); + } + if( prop_scale_previous != prop_scale ){ + prop_scale_modified = true; + } + if(!prop_scale_modified){ + prop_scale.param_set_value(height/original_height); + } + height = Geom::distance(width,ptA) * 2; + width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), ((original_height*prop_scale)/2.0)) + ptA); + width.param_update_default(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), (original_height/2.0)) + ptA); + prop_scale_previous = prop_scale; + Geom::Path hp_path(width); + hp_path.appendNew(ptA); + hp.push_back(hp_path); SPLPEItem * item = const_cast(lpeitem); item->apply_to_clippath(item); item->apply_to_mask(item); @@ -148,6 +184,11 @@ LPEBendPath::resetDefaults(SPItem const* item) bend_path.set_new_value( path.toPwSb(), true ); } +void +LPEBendPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) +{ + hp_vec.push_back(hp); +} } // namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 16b8c6137..6394ce07e 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -14,6 +14,7 @@ #include "live_effects/effect.h" #include "live_effects/parameter/path.h" #include "live_effects/parameter/bool.h" +#include "live_effects/parameter/point.h" #include <2geom/sbasis.h> #include <2geom/sbasis-geometric.h> @@ -27,6 +28,7 @@ namespace Inkscape { namespace LivePathEffect { + //for Bend path on group : we need information concerning the group Bounding box class LPEBendPath : public Effect, GroupBBoxEffect { public: @@ -39,15 +41,21 @@ public: virtual void resetDefaults(SPItem const* item); + void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec); private: - PathParam bend_path; - ScalarParam prop_scale; + PathParam bend_path; + ScalarParam prop_scale; BoolParam scale_y_rel; - BoolParam vertical_pattern; + BoolParam vertical_pattern; + PointParam width; + double height; + double original_height; + double prop_scale_previous; Geom::Piecewise > uskeleton; Geom::Piecewise > n; + Geom::PathVector hp; void on_pattern_pasted(); diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index ed65a0d50..5215f94ec 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -75,7 +75,11 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : vertical_pattern(_("Pattern is _vertical"), _("Rotate pattern 90 deg before applying"), "vertical_pattern", &wr, this, false), fuse_tolerance(_("_Fuse nearby ends:"), _("Fuse ends closer than this number. 0 means don't fuse."), - "fuse_tolerance", &wr, this, 0) + "fuse_tolerance", &wr, this, 0), + width(_("Width distance"), _("Change the width of pattern path - Ctrl+Alt+Click: reset"), "width", &wr, this), + height(0), + original_height(0), + prop_scale_previous(1) { registerParameter( dynamic_cast(&pattern) ); registerParameter( dynamic_cast(©type) ); @@ -87,7 +91,7 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast(&prop_units) ); registerParameter( dynamic_cast(&vertical_pattern) ); registerParameter( dynamic_cast(&fuse_tolerance) ); - + registerParameter( dynamic_cast(&width) ); prop_scale.param_set_digits(3); prop_scale.param_set_increments(0.01, 0.10); } @@ -97,6 +101,48 @@ LPEPatternAlongPath::~LPEPatternAlongPath() } +void +LPEPatternAlongPath::doBeforeEffect (SPLPEItem const* lpeitem) +{ + hp.clear(); + // get the pattern bounding box + Geom::OptRect bbox = pattern.get_pathvector().boundsFast(); + if (bbox) { + original_height = (*bbox)[Geom::Y].max() - (*bbox)[Geom::Y].min(); + bool prop_scale_modified = false; + SPShape const *sp_shape = dynamic_cast(lpeitem); + if (sp_shape) { + Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); + Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); + Geom::Point B = path_in->pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in->curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints((*cubic)[1], ptA); + } + if(height == 0){ + height = original_height; + width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), (original_height/2.0)) + ptA); + prop_scale.param_set_value(1); + } + if( prop_scale_previous != prop_scale ){ + prop_scale_modified = true; + } + height = Geom::distance(width,ptA) * 2; + if(!prop_scale_modified){ + prop_scale.param_set_value(height/original_height); + } + width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), ((original_height*prop_scale)/2.0)) + ptA); + width.param_update_default(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), (original_height/2.0)) + ptA); + prop_scale_previous = prop_scale; + Geom::Path hp_path(width); + hp_path.appendNew(ptA); + hp.push_back(hp_path); + } + } +} + Geom::Piecewise > LPEPatternAlongPath::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) { @@ -238,6 +284,12 @@ LPEPatternAlongPath::transform_multiply(Geom::Affine const& postmul, bool set) } } +void +LPEPatternAlongPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) +{ + hp_vec.push_back(hp); +} + } // namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-patternalongpath.h b/src/live_effects/lpe-patternalongpath.h index be2197ddb..440c56548 100644 --- a/src/live_effects/lpe-patternalongpath.h +++ b/src/live_effects/lpe-patternalongpath.h @@ -13,6 +13,7 @@ #include "live_effects/effect.h" #include "live_effects/parameter/path.h" #include "live_effects/parameter/bool.h" +#include "live_effects/parameter/point.h" namespace Inkscape { namespace LivePathEffect { @@ -30,10 +31,15 @@ public: LPEPatternAlongPath(LivePathEffectObject *lpeobject); virtual ~LPEPatternAlongPath(); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); virtual void transform_multiply(Geom::Affine const& postmul, bool set); + void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec); + + PathParam pattern; private: EnumParam copytype; @@ -45,7 +51,11 @@ private: BoolParam prop_units; BoolParam vertical_pattern; ScalarParam fuse_tolerance; - + PointParam width; + double height; + double original_height; + double prop_scale_previous; + Geom::PathVector hp; void on_pattern_pasted(); LPEPatternAlongPath(const LPEPatternAlongPath&); -- cgit v1.2.3 From a1760772685efb9ed2b02b5b47ffacab3707dc07 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Tue, 4 Aug 2015 21:14:05 +0200 Subject: Translations. First set of new Indian languages translations (Assamese, Dogri, Gujarati, Hindi, Odia, Santali and Tamil. Fixed bugs: - https://launchpad.net/bugs/1316569 - https://launchpad.net/bugs/1316565 - https://launchpad.net/bugs/1316571 - https://launchpad.net/bugs/1316548 - https://launchpad.net/bugs/1316479 - https://launchpad.net/bugs/1316476 - https://launchpad.net/bugs/1316440 (bzr r14274) --- src/ui/dialog/inkscape-preferences.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 98695e080..2bfec2ad7 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -522,22 +522,22 @@ void InkscapePreferences::initPageUI() Gtk::TreeModel::iterator iter_ui = this->AddPage(_page_ui, _("Interface"), PREFS_PAGE_UI); _path_ui = _page_list.get_model()->get_path(iter_ui); - Glib::ustring languages[] = {_("System default"), _("Albanian (sq)"), _("Amharic (am)"), _("Arabic (ar)"), _("Armenian (hy)"),_("Azerbaijani (az)"), _("Basque (eu)"), _("Belarusian (be)"), + Glib::ustring languages[] = {_("System default"), _("Albanian (sq)"), _("Amharic (am)"), _("Arabic (ar)"), _("Armenian (hy)"), _("Assamese (as)"), _("Azerbaijani (az)"), _("Basque (eu)"), _("Belarusian (be)"), _("Bulgarian (bg)"), _("Bengali (bn)"), _("Bengali/Bangladesh (bn_BD)"), _("Breton (br)"), _("Catalan (ca)"), _("Valencian Catalan (ca@valencia)"), _("Chinese/China (zh_CN)"), _("Chinese/Taiwan (zh_TW)"), _("Croatian (hr)"), _("Czech (cs)"), - _("Danish (da)"), _("Dutch (nl)"), _("Dzongkha (dz)"), _("German (de)"), _("Greek (el)"), _("English (en)"), _("English/Australia (en_AU)"), + _("Danish (da)"), _("Dogri (doi)"), _("Dutch (nl)"), _("Dzongkha (dz)"), _("German (de)"), _("Greek (el)"), _("English (en)"), _("English/Australia (en_AU)"), _("English/Canada (en_CA)"), _("English/Great Britain (en_GB)"), _("Pig Latin (en_US@piglatin)"), _("Esperanto (eo)"), _("Estonian (et)"), _("Farsi (fa)"), _("Finnish (fi)"), - _("French (fr)"), _("Irish (ga)"), _("Galician (gl)"), _("Hebrew (he)"), _("Hungarian (hu)"), + _("French (fr)"), _("Irish (ga)"), _("Galician (gl)"), _("Gujarati (gu)"), _("Hebrew (he)"), _("Hindi (hi)"), _("Hungarian (hu)"), _("Indonesian (id)"), _("Icelandic (is)"), _("Italian (it)"), _("Japanese (ja)"), _("Khmer (km)"), _("Kinyarwanda (rw)"), _("Korean (ko)"), _("Lithuanian (lt)"), _("Latvian (lv)"), _("Macedonian (mk)"), - _("Mongolian (mn)"), _("Nepali (ne)"), _("Norwegian BokmĆ„l (nb)"), _("Norwegian Nynorsk (nn)"), _("Panjabi (pa)"), - _("Polish (pl)"), _("Portuguese (pt)"), _("Portuguese/Brazil (pt_BR)"), _("Romanian (ro)"), _("Russian (ru)"), + _("Mongolian (mn)"), _("Nepali (ne)"), _("Norwegian BokmĆ„l (nb)"), _("Norwegian Nynorsk (nn)"), _("Odia (or)"), _("Panjabi (pa)"), + _("Polish (pl)"), _("Portuguese (pt)"), _("Portuguese/Brazil (pt_BR)"), _("Romanian (ro)"), _("Russian (ru)"), _("Santali in Devnagari script (sat@deva)"), _("Santali in Ol-Chiki script (sat@olck)"), _("Serbian (sr)"), _("Serbian in Latin script (sr@latin)"), _("Slovak (sk)"), _("Slovenian (sl)"), _("Spanish (es)"), _("Spanish/Mexico (es_MX)"), - _("Swedish (sv)"),_("Telugu (te)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Vietnamese (vi)")}; - Glib::ustring langValues[] = {"", "sq", "am", "ar", "hy", "az", "eu", "be", "bg", "bn", "bn_BD", "br", "ca", "ca@valencia", "zh_CN", "zh_TW", "hr", "cs", "da", "nl", + _("Swedish (sv)"), _("Tamil (ta)"), _("Telugu (te)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Vietnamese (vi)")}; + Glib::ustring langValues[] = {"", "sq", "am", "ar", "hy", "as", "az", "eu", "be", "bg", "bn", "bn_BD", "br", "ca", "ca@valencia", "zh_CN", "zh_TW", "hr", "cs", "da", "doi", "nl", "dz", "de", "el", "en", "en_AU", "en_CA", "en_GB", "en_US@piglatin", "eo", "et", "fa", "fi", "fr", "ga", - "gl", "he", "hu", "id", "is", "it", "ja", "km", "rw", "ko", "lt", "lv", "mk", "mn", "ne", "nb", "nn", "pa", - "pl", "pt", "pt_BR", "ro", "ru", "sr", "sr@latin", "sk", "sl", "es", "es_MX", "sv", "te", "th", "tr", "uk", "vi" }; + "gl", "gu", "he", "hi", "hu", "id", "is", "it", "ja", "km", "rw", "ko", "lt", "lv", "mk", "mn", "ne", "nb", "nn", "or", "pa", + "pl", "pt", "pt_BR", "ro", "ru", "sat@deva", "sat@olck", "sr", "sr@latin", "sk", "sl", "es", "es_MX", "sv", "ta", "te", "th", "tr", "uk", "vi" }; { // sorting languages according to translated name -- cgit v1.2.3 From ea883fa7a8b207aea8a86fb41084da03ee2ef827 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Aug 2015 21:25:52 +0200 Subject: Fix some transform problems in Bend path. Also refactor a bit the file to simplify it (bzr r14276) --- src/live_effects/lpe-bendpath.h | 3 +-- src/ui/tools/freehand-base.cpp | 44 ++++++++++++++++------------------------- 2 files changed, 18 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 16b8c6137..0871d532e 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -39,9 +39,8 @@ public: virtual void resetDefaults(SPItem const* item); - -private: PathParam bend_path; +private: ScalarParam prop_scale; BoolParam scale_y_rel; BoolParam vertical_pattern; diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index bdce1cd46..6adece54f 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -215,7 +215,7 @@ static Glib::ustring const tool_name(FreehandBase *dc) : "/tools/freehand/pencil" ); } -static void spdc_paste_curve_as_freehand_shape(const SPCurve *c, FreehandBase *dc, SPItem *item) +static void spdc_paste_curve_as_freehand_shape(gchar const *svgd, FreehandBase *dc, SPItem *item) { using namespace Inkscape::LivePathEffect; @@ -223,7 +223,6 @@ static void spdc_paste_curve_as_freehand_shape(const SPCurve *c, FreehandBase *d Effect::createAndApply(PATTERN_ALONG_PATH, dc->desktop->doc(), item); Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); - gchar *svgd = sp_svg_write_path(c->get_pathvector()); static_cast(lpe)->pattern.paste_param_path(svgd); } @@ -278,10 +277,10 @@ static void spdc_apply_bend_shape(gchar const *svgd, FreehandBase *dc, SPItem *i Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); // write bend parameters: - lpe->getRepr()->setAttribute("bendpath", svgd); lpe->getRepr()->setAttribute("prop_scale", "1"); lpe->getRepr()->setAttribute("scale_y_rel", "false"); lpe->getRepr()->setAttribute("vertical", "false"); + static_cast(lpe)->bend_path.paste_param_path(svgd); } static void spdc_apply_simplify(std::string threshold, FreehandBase *dc, SPItem *item) @@ -386,7 +385,8 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, c->curveto(SHAPE_LENGTH, (1 + C1) * SHAPE_HEIGHT/2, (1 + C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, SHAPE_LENGTH/2, SHAPE_HEIGHT); c->curveto((1 - C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, 0, (1 + C1) * SHAPE_HEIGHT/2, 0, SHAPE_HEIGHT/2); c->closepath(); - spdc_paste_curve_as_freehand_shape(c, dc, item); + gchar const *svgd = sp_svg_write_path(c->get_pathvector()); + spdc_paste_curve_as_freehand_shape(svgd, dc, item); c->unref(); shape_applied = true; @@ -399,15 +399,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, Glib::ustring svgd = cm->getPathParameter(SP_ACTIVE_DESKTOP); if(svgd != ""){ previous_shape_pathv = sp_svg_read_pathv(svgd.data()); - Inkscape::XML::Node *nv_repr = SP_ACTIVE_DESKTOP->getNamedView()->getRepr(); - if (nv_repr->attribute("inkscape:document-units")){ - double scale_units = Inkscape::Util::Quantity::convert(1, "px", nv_repr->attribute("inkscape:document-units")); - if (!Geom::are_near(scale_units, 1.0, Geom::EPSILON)) { - previous_shape_pathv *= Geom::Scale(scale_units); - } - } - SPCurve const *c = new SPCurve(previous_shape_pathv); - spdc_paste_curve_as_freehand_shape(c, dc, item); + spdc_paste_curve_as_freehand_shape(svgd.data(), dc, item); shape_applied = true; } else { shape = NONE; @@ -419,14 +411,11 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if(cm->paste(SP_ACTIVE_DESKTOP,true) == true){ gchar const *svgd = item->getRepr()->attribute("d"); - Geom::PathVector path = sp_svg_read_pathv(svgd); - path *= item->i2doc_affine().inverse(); - svgd = sp_svg_write_path( path ); bend_item = dc->selection->singleItem(); if(bend_item){ bend_item->moveTo(item,false); + bend_item->transform = Geom::Affine(1,0,0,1,0,0); spdc_apply_bend_shape(svgd, dc, bend_item); - bend_item->transform = Geom::Affine(1,0,0,1,0,0); dc->selection->add(SP_OBJECT(bend_item)); } else { shape = NONE; @@ -440,32 +429,33 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, { if(previous_shape_type == CLIPBOARD){ if(previous_shape_pathv.size() != 0){ - SPCurve * c = new SPCurve(); - c->set_pathvector(previous_shape_pathv); - spdc_paste_curve_as_freehand_shape(c, dc, item); - c->unref(); + gchar const *svgd = sp_svg_write_path(previous_shape_pathv); + spdc_paste_curve_as_freehand_shape(svgd, dc, item); shape_applied = true; + shape = CLIPBOARD; + } else{ + shape = NONE; } - shape = CLIPBOARD; } else { if(bend_item != NULL && bend_item->getRepr() != NULL){ gchar const *svgd = item->getRepr()->attribute("d"); - Geom::PathVector path = sp_svg_read_pathv(svgd); - path *= item->i2doc_affine().inverse(); - svgd = sp_svg_write_path( path ); dc->selection->add(SP_OBJECT(bend_item)); sp_selection_duplicate(dc->desktop); dc->selection->remove(SP_OBJECT(bend_item)); bend_item = dc->selection->singleItem(); if(bend_item){ bend_item->moveTo(item,false); - spdc_apply_bend_shape(svgd, dc, bend_item); bend_item->transform = Geom::Affine(1,0,0,1,0,0); + spdc_apply_bend_shape(svgd, dc, bend_item); dc->selection->add(SP_OBJECT(bend_item)); + shape = BEND_CLIPBOARD; + } else { + shape = NONE; } + } else { + shape = NONE; } - shape = BEND_CLIPBOARD; } break; } -- cgit v1.2.3 From 7a19998853ca88c2ff03bcf7e0cbb049b693c106 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Aug 2015 22:08:24 +0200 Subject: Fix bug on apply effect from pen/pencil toolbar (bzr r14272.1.2) --- src/live_effects/lpe-bendpath.cpp | 45 ++++++++++++++++++------------- src/live_effects/lpe-bendpath.h | 6 ++--- src/live_effects/lpe-patternalongpath.cpp | 41 ++++++++++++++++------------ src/live_effects/lpe-patternalongpath.h | 4 +-- src/ui/tools/freehand-base.cpp | 44 ++++++++++++------------------ 5 files changed, 72 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 364c77ccb..4d72af38c 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -52,13 +52,13 @@ namespace LivePathEffect { LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) : Effect(lpeobject), bend_path(_("Bend path:"), _("Path along which to bend the original path"), "bendpath", &wr, this, "M0,0 L1,0"), - prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1), + prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1.0), + width(_("Width distance"), _("Change the width of bend path - Ctrl+Alt+Click: reset"), "width", &wr, this), scale_y_rel(_("W_idth in units of length"), _("Scale the width of the path in units of its length"), "scale_y_rel", &wr, this, false), vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false), - width(_("Width distance"), _("Change the width of bend path - Ctrl+Alt+Click: reset"), "width", &wr, this), - height(0), - original_height(0), - prop_scale_previous(1) + height(0.0), + original_height(0.0), + prop_scale_from_widget(1.0) { registerParameter( dynamic_cast(&bend_path) ); registerParameter( dynamic_cast(&prop_scale) ); @@ -84,8 +84,6 @@ LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) // get the item bounding box original_bbox(lpeitem); original_height = boundingbox_Y.max() - boundingbox_Y.min(); - bool prop_scale_modified = false; - Geom::Path path_in = bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0)); @@ -95,20 +93,29 @@ LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) if (cubic) { ray.setPoints((*cubic)[1], ptA); } - if(height == 0){ + //This Hack is to fix a boring bug in the first call to the function, we have + //a wrong "ptA" + if(height == 0.0 && Geom::are_near(width, Geom::Point())){ + height = 0.1; + std::cout << ptA << "ptA0.5\n"; + } else if(height == 0.1 && Geom::are_near(width, Geom::Point())){ + Geom::Point default_point = Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), (original_height/2.0)) + ptA; + prop_scale.param_set_value(1.0); height = original_height; - width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), (original_height/2.0)) + ptA); - } - if( prop_scale_previous != prop_scale ){ - prop_scale_modified = true; - } - if(!prop_scale_modified){ - prop_scale.param_set_value(height/original_height); + width.param_setValue(default_point); + width.param_update_default(default_point); + } else { + double distance_knot = Geom::distance(width , ptA); + width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), distance_knot) + ptA); + height = distance_knot * 2; + if(prop_scale_from_widget == prop_scale){ + prop_scale.param_set_value(height/original_height); + } else { + height = original_height * prop_scale; + width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), height/2.0) + ptA); + } } - height = Geom::distance(width,ptA) * 2; - width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), ((original_height*prop_scale)/2.0)) + ptA); - width.param_update_default(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), (original_height/2.0)) + ptA); - prop_scale_previous = prop_scale; + prop_scale_from_widget = prop_scale; Geom::Path hp_path(width); hp_path.appendNew(ptA); hp.push_back(hp_path); diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 6394ce07e..cb9ced570 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -43,15 +43,15 @@ public: void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec); -private: PathParam bend_path; +private: ScalarParam prop_scale; + PointParam width; BoolParam scale_y_rel; BoolParam vertical_pattern; - PointParam width; double height; double original_height; - double prop_scale_previous; + double prop_scale_from_widget; Geom::Piecewise > uskeleton; Geom::Piecewise > n; diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index 5215f94ec..53730d4d4 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -59,7 +59,8 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : pattern(_("Pattern source:"), _("Path to put along the skeleton path"), "pattern", &wr, this, "M0,0 L1,0"), copytype(_("Pattern copies:"), _("How many pattern copies to place along the skeleton path"), "copytype", PAPCopyTypeConverter, &wr, this, PAPCT_SINGLE_STRETCHED), - prop_scale(_("_Width:"), _("Width of the pattern"), "prop_scale", &wr, this, 1), + prop_scale(_("_Width:"), _("Width of the pattern"), "prop_scale", &wr, this, 1.0), + width(_("Width distance"), _("Change the width of pattern path - Ctrl+Alt+Click: reset"), "width", &wr, this), scale_y_rel(_("Wid_th in units of length"), _("Scale the width of the pattern in units of its length"), "scale_y_rel", &wr, this, false), @@ -76,10 +77,9 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : "vertical_pattern", &wr, this, false), fuse_tolerance(_("_Fuse nearby ends:"), _("Fuse ends closer than this number. 0 means don't fuse."), "fuse_tolerance", &wr, this, 0), - width(_("Width distance"), _("Change the width of pattern path - Ctrl+Alt+Click: reset"), "width", &wr, this), height(0), original_height(0), - prop_scale_previous(1) + prop_scale_from_widget(1) { registerParameter( dynamic_cast(&pattern) ); registerParameter( dynamic_cast(©type) ); @@ -109,7 +109,6 @@ LPEPatternAlongPath::doBeforeEffect (SPLPEItem const* lpeitem) Geom::OptRect bbox = pattern.get_pathvector().boundsFast(); if (bbox) { original_height = (*bbox)[Geom::Y].max() - (*bbox)[Geom::Y].min(); - bool prop_scale_modified = false; SPShape const *sp_shape = dynamic_cast(lpeitem); if (sp_shape) { Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); @@ -121,21 +120,29 @@ LPEPatternAlongPath::doBeforeEffect (SPLPEItem const* lpeitem) if (cubic) { ray.setPoints((*cubic)[1], ptA); } - if(height == 0){ + //This Hack is to fix a boring bug in the first call to the function, we have + //a wrong "ptA" + if(height == 0.0 && Geom::are_near(width, Geom::Point())){ + height = 0.1; + std::cout << ptA << "ptA0.5\n"; + } else if(height == 0.1 && Geom::are_near(width, Geom::Point())){ + Geom::Point default_point = Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), (original_height/2.0)) + ptA; + prop_scale.param_set_value(1.0); height = original_height; - width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), (original_height/2.0)) + ptA); - prop_scale.param_set_value(1); - } - if( prop_scale_previous != prop_scale ){ - prop_scale_modified = true; - } - height = Geom::distance(width,ptA) * 2; - if(!prop_scale_modified){ - prop_scale.param_set_value(height/original_height); + width.param_setValue(default_point); + width.param_update_default(default_point); + } else { + double distance_knot = Geom::distance(width , ptA); + width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), distance_knot) + ptA); + height = distance_knot * 2; + if(prop_scale_from_widget == prop_scale){ + prop_scale.param_set_value(height/original_height); + } else { + height = original_height * prop_scale; + width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), height/2.0) + ptA); + } } - width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), ((original_height*prop_scale)/2.0)) + ptA); - width.param_update_default(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), (original_height/2.0)) + ptA); - prop_scale_previous = prop_scale; + prop_scale_from_widget = prop_scale; Geom::Path hp_path(width); hp_path.appendNew(ptA); hp.push_back(hp_path); diff --git a/src/live_effects/lpe-patternalongpath.h b/src/live_effects/lpe-patternalongpath.h index 440c56548..df0ae9777 100644 --- a/src/live_effects/lpe-patternalongpath.h +++ b/src/live_effects/lpe-patternalongpath.h @@ -44,6 +44,7 @@ public: private: EnumParam copytype; ScalarParam prop_scale; + PointParam width; BoolParam scale_y_rel; ScalarParam spacing; ScalarParam normal_offset; @@ -51,10 +52,9 @@ private: BoolParam prop_units; BoolParam vertical_pattern; ScalarParam fuse_tolerance; - PointParam width; double height; double original_height; - double prop_scale_previous; + double prop_scale_from_widget; Geom::PathVector hp; void on_pattern_pasted(); diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index bdce1cd46..6adece54f 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -215,7 +215,7 @@ static Glib::ustring const tool_name(FreehandBase *dc) : "/tools/freehand/pencil" ); } -static void spdc_paste_curve_as_freehand_shape(const SPCurve *c, FreehandBase *dc, SPItem *item) +static void spdc_paste_curve_as_freehand_shape(gchar const *svgd, FreehandBase *dc, SPItem *item) { using namespace Inkscape::LivePathEffect; @@ -223,7 +223,6 @@ static void spdc_paste_curve_as_freehand_shape(const SPCurve *c, FreehandBase *d Effect::createAndApply(PATTERN_ALONG_PATH, dc->desktop->doc(), item); Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); - gchar *svgd = sp_svg_write_path(c->get_pathvector()); static_cast(lpe)->pattern.paste_param_path(svgd); } @@ -278,10 +277,10 @@ static void spdc_apply_bend_shape(gchar const *svgd, FreehandBase *dc, SPItem *i Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); // write bend parameters: - lpe->getRepr()->setAttribute("bendpath", svgd); lpe->getRepr()->setAttribute("prop_scale", "1"); lpe->getRepr()->setAttribute("scale_y_rel", "false"); lpe->getRepr()->setAttribute("vertical", "false"); + static_cast(lpe)->bend_path.paste_param_path(svgd); } static void spdc_apply_simplify(std::string threshold, FreehandBase *dc, SPItem *item) @@ -386,7 +385,8 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, c->curveto(SHAPE_LENGTH, (1 + C1) * SHAPE_HEIGHT/2, (1 + C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, SHAPE_LENGTH/2, SHAPE_HEIGHT); c->curveto((1 - C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, 0, (1 + C1) * SHAPE_HEIGHT/2, 0, SHAPE_HEIGHT/2); c->closepath(); - spdc_paste_curve_as_freehand_shape(c, dc, item); + gchar const *svgd = sp_svg_write_path(c->get_pathvector()); + spdc_paste_curve_as_freehand_shape(svgd, dc, item); c->unref(); shape_applied = true; @@ -399,15 +399,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, Glib::ustring svgd = cm->getPathParameter(SP_ACTIVE_DESKTOP); if(svgd != ""){ previous_shape_pathv = sp_svg_read_pathv(svgd.data()); - Inkscape::XML::Node *nv_repr = SP_ACTIVE_DESKTOP->getNamedView()->getRepr(); - if (nv_repr->attribute("inkscape:document-units")){ - double scale_units = Inkscape::Util::Quantity::convert(1, "px", nv_repr->attribute("inkscape:document-units")); - if (!Geom::are_near(scale_units, 1.0, Geom::EPSILON)) { - previous_shape_pathv *= Geom::Scale(scale_units); - } - } - SPCurve const *c = new SPCurve(previous_shape_pathv); - spdc_paste_curve_as_freehand_shape(c, dc, item); + spdc_paste_curve_as_freehand_shape(svgd.data(), dc, item); shape_applied = true; } else { shape = NONE; @@ -419,14 +411,11 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if(cm->paste(SP_ACTIVE_DESKTOP,true) == true){ gchar const *svgd = item->getRepr()->attribute("d"); - Geom::PathVector path = sp_svg_read_pathv(svgd); - path *= item->i2doc_affine().inverse(); - svgd = sp_svg_write_path( path ); bend_item = dc->selection->singleItem(); if(bend_item){ bend_item->moveTo(item,false); + bend_item->transform = Geom::Affine(1,0,0,1,0,0); spdc_apply_bend_shape(svgd, dc, bend_item); - bend_item->transform = Geom::Affine(1,0,0,1,0,0); dc->selection->add(SP_OBJECT(bend_item)); } else { shape = NONE; @@ -440,32 +429,33 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, { if(previous_shape_type == CLIPBOARD){ if(previous_shape_pathv.size() != 0){ - SPCurve * c = new SPCurve(); - c->set_pathvector(previous_shape_pathv); - spdc_paste_curve_as_freehand_shape(c, dc, item); - c->unref(); + gchar const *svgd = sp_svg_write_path(previous_shape_pathv); + spdc_paste_curve_as_freehand_shape(svgd, dc, item); shape_applied = true; + shape = CLIPBOARD; + } else{ + shape = NONE; } - shape = CLIPBOARD; } else { if(bend_item != NULL && bend_item->getRepr() != NULL){ gchar const *svgd = item->getRepr()->attribute("d"); - Geom::PathVector path = sp_svg_read_pathv(svgd); - path *= item->i2doc_affine().inverse(); - svgd = sp_svg_write_path( path ); dc->selection->add(SP_OBJECT(bend_item)); sp_selection_duplicate(dc->desktop); dc->selection->remove(SP_OBJECT(bend_item)); bend_item = dc->selection->singleItem(); if(bend_item){ bend_item->moveTo(item,false); - spdc_apply_bend_shape(svgd, dc, bend_item); bend_item->transform = Geom::Affine(1,0,0,1,0,0); + spdc_apply_bend_shape(svgd, dc, bend_item); dc->selection->add(SP_OBJECT(bend_item)); + shape = BEND_CLIPBOARD; + } else { + shape = NONE; } + } else { + shape = NONE; } - shape = BEND_CLIPBOARD; } break; } -- cgit v1.2.3 From 4edf64a6334e4d67866e0b77acca5df037840eb7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Aug 2015 23:03:18 +0200 Subject: Allow scale on bend items (bzr r14277) --- src/ui/tools/freehand-base.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 6adece54f..31fb2f376 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -414,7 +414,11 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, bend_item = dc->selection->singleItem(); if(bend_item){ bend_item->moveTo(item,false); - bend_item->transform = Geom::Affine(1,0,0,1,0,0); + Geom::Coord expansion_X = bend_item->transform.expansionX(); + Geom::Coord expansion_Y = bend_item->transform.expansionY(); + bend_item->transform = Geom::Affine(1,0,0,1,0,0); + bend_item->transform.setExpansionX(expansion_X); + bend_item->transform.setExpansionY(expansion_Y); spdc_apply_bend_shape(svgd, dc, bend_item); dc->selection->add(SP_OBJECT(bend_item)); } else { @@ -446,7 +450,11 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, bend_item = dc->selection->singleItem(); if(bend_item){ bend_item->moveTo(item,false); + Geom::Coord expansion_X = bend_item->transform.expansionX(); + Geom::Coord expansion_Y = bend_item->transform.expansionY(); bend_item->transform = Geom::Affine(1,0,0,1,0,0); + bend_item->transform.setExpansionX(expansion_X); + bend_item->transform.setExpansionY(expansion_Y); spdc_apply_bend_shape(svgd, dc, bend_item); dc->selection->add(SP_OBJECT(bend_item)); shape = BEND_CLIPBOARD; -- cgit v1.2.3 From c77df2a9ee1f988a2652528465ba5357a5e72ab2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 6 Aug 2015 02:24:34 +0200 Subject: fix a bug appliening from patheffect list the LPE (bzr r14272.1.5) --- src/live_effects/lpe-bendpath.cpp | 32 ++++++++++++++++++++++---------- src/live_effects/lpe-bendpath.h | 3 ++- 2 files changed, 24 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 4d72af38c..9b015245d 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -58,7 +58,9 @@ LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) : vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false), height(0.0), original_height(0.0), - prop_scale_from_widget(1.0) + prop_scale_from_widget(1.0), + firstTime(false), + secondTime(false) { registerParameter( dynamic_cast(&bend_path) ); registerParameter( dynamic_cast(&prop_scale) ); @@ -91,28 +93,38 @@ LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); Geom::Ray ray(ptA, B); if (cubic) { - ray.setPoints((*cubic)[1], ptA); + ray.setPoints(ptA,(*cubic)[1]); } + + Geom::Angle first_curve_angle = ray.transformed(Geom::Rotate(Geom::deg_to_rad(90))).angle(); //This Hack is to fix a boring bug in the first call to the function, we have //a wrong "ptA" - if(height == 0.0 && Geom::are_near(width, Geom::Point())){ - height = 0.1; - std::cout << ptA << "ptA0.5\n"; - } else if(height == 0.1 && Geom::are_near(width, Geom::Point())){ - Geom::Point default_point = Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), (original_height/2.0)) + ptA; + if(!firstTime && Geom::are_near(width, Geom::Point())){ + firstTime = true; + } else if(firstTime && Geom::are_near(width, Geom::Point())){ + Geom::Point default_point = Geom::Point::polar(first_curve_angle, original_height/2.0) + ptA; prop_scale.param_set_value(1.0); height = original_height; width.param_setValue(default_point); width.param_update_default(default_point); } else { double distance_knot = Geom::distance(width , ptA); - width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), distance_knot) + ptA); + width.param_setValue(Geom::Point::polar(first_curve_angle, distance_knot) + ptA); height = distance_knot * 2; - if(prop_scale_from_widget == prop_scale){ + if(secondTime){ + prop_scale.param_set_value(1); + height = original_height; + width.param_setValue(Geom::Point::polar(first_curve_angle, height/2.0) + ptA); + secondTime = false; + } else if(prop_scale_from_widget == prop_scale){ prop_scale.param_set_value(height/original_height); } else { height = original_height * prop_scale; - width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), height/2.0) + ptA); + width.param_setValue(Geom::Point::polar(first_curve_angle, height/2.0) + ptA); + } + if(firstTime){ + firstTime = false; + secondTime = true; } } prop_scale_from_widget = prop_scale; diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index a59d2322a..5d58f3320 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -53,7 +53,8 @@ private: double height; double original_height; double prop_scale_from_widget; - + bool firstTime; + bool secondTime; Geom::Piecewise > uskeleton; Geom::Piecewise > n; Geom::PathVector hp; -- cgit v1.2.3 From 98e57f9888244c7bb7c1e528f4d9d0feca935d19 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 6 Aug 2015 23:42:52 +0200 Subject: Refactor BSPline and Spiro to remove duplicated functions (bzr r14280) --- src/live_effects/lpe-bspline.cpp | 239 ++++++++++++++++-------------------- src/live_effects/lpe-bspline.h | 13 +- src/live_effects/lpe-spiro.cpp | 16 +-- src/live_effects/lpe-spiro.h | 2 + src/ui/tools/pen-tool.cpp | 255 +-------------------------------------- src/ui/tools/pen-tool.h | 2 - 6 files changed, 122 insertions(+), 405 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 6575700c7..d2da33aa9 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -20,6 +20,8 @@ const double HANDLE_CUBIC_GAP = 0.01; const double NO_POWER = 0.0; const double DEFAULT_START_POWER = 0.3334; const double DEFAULT_END_POWER = 0.6667; +Geom::PathVector hp; +void sp_bspline_drawHandle(Geom::Point p, double helper_size); LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : Effect(lpeobject), @@ -67,15 +69,115 @@ void LPEBSpline::doOnApply(SPLPEItem const* lpeitem) } } +void +LPEBSpline::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) +{ + hp_vec.push_back(hp); +} + +Gtk::Widget *LPEBSpline::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + + vbox->set_border_width(5); + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + if (param->param_key == "weight") { + Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::Button *default_weight = + Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight")))); + default_weight->signal_clicked() + .connect(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight)); + buttons->pack_start(*default_weight, true, true, 2); + Gtk::Button *make_cusp = + Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); + make_cusp->signal_clicked() + .connect(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp)); + buttons->pack_start(*make_cusp, true, true, 2); + vbox->pack_start(*buttons, true, true, 2); + } + if (param->param_key == "weight" || param->param_key == "steps") { + Inkscape::UI::Widget::Scalar *widg_registered = + Gtk::manage(dynamic_cast(widg)); + widg_registered->signal_value_changed() + .connect(sigc::mem_fun(*this, &LPEBSpline::toWeight)); + widg = dynamic_cast(widg_registered); + if (widg) { + Gtk::HBox * hbox_weight_steps = dynamic_cast(widg); + std::vector< Gtk::Widget* > childList = hbox_weight_steps->get_children(); + Gtk::Entry* entry_widget = dynamic_cast(childList[1]); + entry_widget->set_width_chars(6); + } + } + if (param->param_key == "only_selected") { + Gtk::CheckButton *widg_registered = + Gtk::manage(dynamic_cast(widg)); + widg = dynamic_cast(widg_registered); + } + if (param->param_key == "ignore_cusp") { + Gtk::CheckButton *widg_registered = + Gtk::manage(dynamic_cast(widg)); + widg = dynamic_cast(widg_registered); + } + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + return dynamic_cast(vbox); +} + +void LPEBSpline::toDefaultWeight() +{ + changeWeight(DEFAULT_START_POWER); +} + +void LPEBSpline::toMakeCusp() +{ + changeWeight(NO_POWER); +} + +void LPEBSpline::toWeight() +{ + changeWeight(weight); +} + +void LPEBSpline::changeWeight(double weight_ammount) +{ + SPPath *path = dynamic_cast(sp_lpe_item); + if(path) { + SPCurve *curve = path->get_curve_for_edit(); + doBSplineFromWidget(curve, weight_ammount); + gchar *str = sp_svg_write_path(curve->get_pathvector()); + path->getRepr()->setAttribute("inkscape:original-d", str); + } +} + void LPEBSpline::doEffect(SPCurve *curve) { + sp_bspline_do_effect(curve, helper_size); +} +void sp_bspline_do_effect(SPCurve *curve, double helper_size) +{ if (curve->get_segment_count() < 1) { return; } - // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); - curve->reset(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); @@ -99,20 +201,6 @@ void LPEBSpline::doEffect(SPCurve *curve) Geom::D2 sbasis_out; Geom::D2 sbasis_helper; Geom::CubicBezier const *cubic = NULL; - if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the - // closing line segment has zerolength. - const Geom::Curve &closingline = - path_it->back_closed(); // the closing line segment is always of type - // Geom::LineSegment. - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for - // *exact* zero length, which goes wrong for relative coordinates and - // rounding errors... - // the closing line segment has zero-length. So stop before that one! - curve_endit = path_it->end_open(); - } - } curve_n->moveto(curve_it1->initialPoint()); while (curve_it1 != curve_endit) { SPCurve *in = new SPCurve(); @@ -209,12 +297,11 @@ void LPEBSpline::doEffect(SPCurve *curve) curve_n->curveto(point_at1, point_at2, node); } if(!are_near(node,curve_it1->finalPoint()) && helper_size > 0.0) { - drawHandle(node, helper_size); + sp_bspline_drawHandle(node, helper_size); } ++curve_it1; ++curve_it2; } - //y cerramos la curva if (path_it->closed()) { curve_n->closepath_current(); } @@ -228,8 +315,8 @@ void LPEBSpline::doEffect(SPCurve *curve) } } -void -LPEBSpline::drawHandle(Geom::Point p, double helper_size) + +void sp_bspline_drawHandle(Geom::Point p, double helper_size) { char const * svgd = "M 1,0.5 A 0.5,0.5 0 0 1 0.5,1 0.5,0.5 0 0 1 0,0.5 0.5,0.5 0 0 1 0.5,0 0.5,0.5 0 0 1 1,0.5 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); @@ -240,104 +327,6 @@ LPEBSpline::drawHandle(Geom::Point p, double helper_size) hp.push_back(pathv[0]); } -void -LPEBSpline::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) -{ - hp_vec.push_back(hp); -} - -Gtk::Widget *LPEBSpline::newWidget() -{ - // use manage here, because after deletion of Effect object, others might - // still be pointing to this widget. - Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - - vbox->set_border_width(5); - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter *param = *it; - Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); - if (param->param_key == "weight") { - Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0)); - Gtk::Button *default_weight = - Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight")))); - default_weight->signal_clicked() - .connect(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight)); - buttons->pack_start(*default_weight, true, true, 2); - Gtk::Button *make_cusp = - Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); - make_cusp->signal_clicked() - .connect(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp)); - buttons->pack_start(*make_cusp, true, true, 2); - vbox->pack_start(*buttons, true, true, 2); - } - if (param->param_key == "weight" || param->param_key == "steps") { - Inkscape::UI::Widget::Scalar *widg_registered = - Gtk::manage(dynamic_cast(widg)); - widg_registered->signal_value_changed() - .connect(sigc::mem_fun(*this, &LPEBSpline::toWeight)); - widg = dynamic_cast(widg_registered); - if (widg) { - Gtk::HBox * hbox_weight_steps = dynamic_cast(widg); - std::vector< Gtk::Widget* > childList = hbox_weight_steps->get_children(); - Gtk::Entry* entry_widget = dynamic_cast(childList[1]); - entry_widget->set_width_chars(6); - } - } - if (param->param_key == "only_selected") { - Gtk::CheckButton *widg_registered = - Gtk::manage(dynamic_cast(widg)); - widg = dynamic_cast(widg_registered); - } - if (param->param_key == "ignore_cusp") { - Gtk::CheckButton *widg_registered = - Gtk::manage(dynamic_cast(widg)); - widg = dynamic_cast(widg_registered); - } - Glib::ustring *tip = param->param_getTooltip(); - if (widg) { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } - - ++it; - } - return dynamic_cast(vbox); -} - -void LPEBSpline::toDefaultWeight() -{ - changeWeight(DEFAULT_START_POWER); -} - -void LPEBSpline::toMakeCusp() -{ - changeWeight(NO_POWER); -} - -void LPEBSpline::toWeight() -{ - changeWeight(weight); -} - -void LPEBSpline::changeWeight(double weight_ammount) -{ - SPPath *path = dynamic_cast(sp_lpe_item); - if(path) { - SPCurve *curve = path->get_curve_for_edit(); - doBSplineFromWidget(curve, weight_ammount); - gchar *str = sp_svg_write_path(curve->get_pathvector()); - path->getRepr()->setAttribute("inkscape:original-d", str); - } -} - void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) { using Geom::X; @@ -367,20 +356,6 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) Geom::D2 sbasis_in; Geom::D2 sbasis_out; Geom::CubicBezier const *cubic = NULL; - if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the - // closing line segment has zerolength. - const Geom::Curve &closingline = - path_it->back_closed(); // the closing line segment is always of type - // Geom::LineSegment. - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for - // *exact* zero length, which goes wrong for relative coordinates and - // rounding errors... - // the closing line segment has zero-length. So stop before that one! - curve_endit = path_it->end_open(); - } - } curve_n->moveto(curve_it1->initialPoint()); while (curve_it1 != curve_endit) { SPCurve *in = new SPCurve(); diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index fc0f66353..033e85cf0 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -25,14 +25,13 @@ public: virtual void doOnApply(SPLPEItem const* lpeitem); virtual void doEffect(SPCurve *curve); virtual void doBeforeEffect (SPLPEItem const* lpeitem); - void drawHandle(Geom::Point p, double radiusHelperNodes); - virtual void doBSplineFromWidget(SPCurve *curve, double value); + void doBSplineFromWidget(SPCurve *curve, double value); void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec); virtual Gtk::Widget *newWidget(); - virtual void changeWeight(double weightValue); - virtual void toDefaultWeight(); - virtual void toMakeCusp(); - virtual void toWeight(); + void changeWeight(double weightValue); + void toDefaultWeight(); + void toMakeCusp(); + void toWeight(); // TODO make this private ScalarParam steps; @@ -42,12 +41,12 @@ private: BoolParam ignore_cusp; BoolParam only_selected; ScalarParam weight; - Geom::PathVector hp; LPEBSpline(const LPEBSpline &); LPEBSpline &operator=(const LPEBSpline &); }; +void sp_bspline_do_effect(SPCurve *curve, double helper_size); } //namespace LivePathEffect } //namespace Inkscape diff --git a/src/live_effects/lpe-spiro.cpp b/src/live_effects/lpe-spiro.cpp index eefd25c7d..0d42596b2 100644 --- a/src/live_effects/lpe-spiro.cpp +++ b/src/live_effects/lpe-spiro.cpp @@ -37,6 +37,10 @@ LPESpiro::~LPESpiro() void LPESpiro::doEffect(SPCurve * curve) { + sp_spiro_do_effect(curve); +} + +void sp_spiro_do_effect(SPCurve *curve){ using Geom::X; using Geom::Y; @@ -54,7 +58,7 @@ LPESpiro::doEffect(SPCurve * curve) // start of path { - Geom::Point p = path_it->front().pointAt(0); + Geom::Point p = path_it->initialPoint(); path[ip].x = p[X]; path[ip].y = p[Y]; path[ip].ty = '{' ; // for closed paths, this is overwritten @@ -64,17 +68,7 @@ LPESpiro::doEffect(SPCurve * curve) // midpoints Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve - Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop - if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. - const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... - // the closing line segment has zero-length. So stop before that one! - curve_endit = path_it->end_open(); - } - } while ( curve_it2 != curve_endit ) { diff --git a/src/live_effects/lpe-spiro.h b/src/live_effects/lpe-spiro.h index edce42280..c8aba53d9 100644 --- a/src/live_effects/lpe-spiro.h +++ b/src/live_effects/lpe-spiro.h @@ -27,6 +27,8 @@ private: LPESpiro& operator=(const LPESpiro&); }; +void sp_spiro_do_effect(SPCurve *curve); + }; //namespace LivePathEffect }; //namespace Inkscape diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index d924d8773..6a3928f27 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1717,9 +1717,9 @@ void PenTool::_bsplineSpiroBuild() //Effect *spr = static_cast ( new LPEbspline(lpeobj) ); //spr->doEffect(curve); if(this->bspline){ - this->_bsplineDoEffect(curve); + LivePathEffect::sp_bspline_do_effect(curve, 0); }else{ - this->_spiroDoEffect(curve); + LivePathEffect::sp_spiro_do_effect(curve); } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue_bpath), curve); @@ -1743,257 +1743,6 @@ void PenTool::_bsplineSpiroBuild() } } -//from LPE BSPLINE: -void PenTool::_bsplineDoEffect(SPCurve * curve) -{ - //const double NO_POWER = 0.0; - const double DEFAULT_START_POWER = 0.3334; - const double DEFAULT_END_POWER = 0.6667; - if (curve->get_segment_count() < 1) { - return; - } - // Make copy of old path as it is changed during processing - Geom::PathVector const original_pathv = curve->get_pathvector(); - - curve->reset(); - - for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); - path_it != original_pathv.end(); ++path_it) { - if (path_it->empty()) { - continue; - } - Geom::Path::const_iterator curve_it1 = path_it->begin(); - Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); - Geom::Path::const_iterator curve_endit = path_it->end_default(); - SPCurve *curve_n = new SPCurve(); - Geom::Point previousNode(0, 0); - Geom::Point node(0, 0); - Geom::Point point_at1(0, 0); - Geom::Point point_at2(0, 0); - Geom::Point next_point_at1(0, 0); - Geom::D2 sbasis_in; - Geom::D2 sbasis_out; - Geom::D2 sbasis_helper; - Geom::CubicBezier const *cubic = NULL; - if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the - // closing line segment has zerolength. - const Geom::Curve &closingline = - path_it->back_closed(); // the closing line segment is always of type - // Geom::LineSegment. - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for - // *exact* zero length, which goes wrong for relative coordinates and - // rounding errors... - // the closing line segment has zero-length. So stop before that one! - curve_endit = path_it->end_open(); - } - } - curve_n->moveto(curve_it1->initialPoint()); - while (curve_it1 != curve_endit) { - SPCurve *in = new SPCurve(); - in->moveto(curve_it1->initialPoint()); - in->lineto(curve_it1->finalPoint()); - cubic = dynamic_cast(&*curve_it1); - if (cubic) { - sbasis_in = in->first_segment()->toSBasis(); - if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) { - point_at1 = sbasis_in.valueAt(DEFAULT_START_POWER); - } else { - point_at1 = sbasis_in.valueAt(Geom::nearest_time((*cubic)[1], *in->first_segment())); - } - if(are_near((*cubic)[2],(*cubic)[3]) && !are_near((*cubic)[1],(*cubic)[0])) { - point_at2 = sbasis_in.valueAt(DEFAULT_END_POWER); - } else { - point_at2 = sbasis_in.valueAt(Geom::nearest_time((*cubic)[2], *in->first_segment())); - } - } else { - point_at1 = in->first_segment()->initialPoint(); - point_at2 = in->first_segment()->finalPoint(); - } - in->reset(); - delete in; - if ( curve_it2 != curve_endit ) { - SPCurve *out = new SPCurve(); - out->moveto(curve_it2->initialPoint()); - out->lineto(curve_it2->finalPoint()); - cubic = dynamic_cast(&*curve_it2); - if (cubic) { - sbasis_out = out->first_segment()->toSBasis(); - if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) { - next_point_at1 = sbasis_in.valueAt(DEFAULT_START_POWER); - } else { - next_point_at1 = sbasis_out.valueAt(Geom::nearest_time((*cubic)[1], *out->first_segment())); - } - } else { - next_point_at1 = out->first_segment()->initialPoint(); - } - out->reset(); - delete out; - } - if (path_it->closed() && curve_it2 == curve_endit) { - SPCurve *start = new SPCurve(); - start->moveto(path_it->begin()->initialPoint()); - start->lineto(path_it->begin()->finalPoint()); - Geom::D2 sbasis_start = start->first_segment()->toSBasis(); - SPCurve *line_helper = new SPCurve(); - cubic = dynamic_cast(&*path_it->begin()); - if (cubic) { - line_helper->moveto(sbasis_start.valueAt( - Geom::nearest_time((*cubic)[1], *start->first_segment()))); - } else { - line_helper->moveto(start->first_segment()->initialPoint()); - } - start->reset(); - delete start; - - SPCurve *end = new SPCurve(); - end->moveto(curve_it1->initialPoint()); - end->lineto(curve_it1->finalPoint()); - Geom::D2 sbasis_end = end->first_segment()->toSBasis(); - cubic = dynamic_cast(&*curve_it1); - if (cubic) { - line_helper->lineto(sbasis_end.valueAt( - Geom::nearest_time((*cubic)[2], *end->first_segment()))); - } else { - line_helper->lineto(end->first_segment()->finalPoint()); - } - end->reset(); - delete end; - sbasis_helper = line_helper->first_segment()->toSBasis(); - line_helper->reset(); - delete line_helper; - node = sbasis_helper.valueAt(0.5); - curve_n->curveto(point_at1, point_at2, node); - curve_n->move_endpoints(node, node); - } else if ( curve_it2 == curve_endit) { - curve_n->curveto(point_at1, point_at2, curve_it1->finalPoint()); - curve_n->move_endpoints(path_it->begin()->initialPoint(), curve_it1->finalPoint()); - } else { - SPCurve *line_helper = new SPCurve(); - line_helper->moveto(point_at2); - line_helper->lineto(next_point_at1); - sbasis_helper = line_helper->first_segment()->toSBasis(); - line_helper->reset(); - delete line_helper; - previousNode = node; - node = sbasis_helper.valueAt(0.5); - Geom::CubicBezier const *cubic2 = dynamic_cast(&*curve_it1); - if((cubic && are_near((*cubic)[0],(*cubic)[1])) || (cubic2 && are_near((*cubic2)[2],(*cubic2)[3]))) { - node = curve_it1->finalPoint(); - } - curve_n->curveto(point_at1, point_at2, node); - } - ++curve_it1; - ++curve_it2; - } - //y cerramos la curva - if (path_it->closed()) { - curve_n->closepath_current(); - } - curve->append(curve_n, false); - curve_n->reset(); - delete curve_n; - } -} - -//Spiro function cloned from lpe-spiro.cpp -// commenting the function "doEffect" from src/live_effects/lpe-spiro.cpp -void PenTool::_spiroDoEffect(SPCurve * curve) -{ - using Geom::X; - using Geom::Y; - - Geom::PathVector const original_pathv = curve->get_pathvector(); - guint len = curve->get_segment_count() + 2; - - curve->reset(); - Spiro::spiro_cp *path = g_new (Spiro::spiro_cp, len); - int ip = 0; - - for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { - if (path_it->empty()) - continue; - - { - Geom::Point p = path_it->front().pointAt(0); - path[ip].x = p[X]; - path[ip].y = p[Y]; - path[ip].ty = '{' ; - ip++; - } - - Geom::Path::const_iterator curve_it1 = path_it->begin(); - Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); - - Geom::Path::const_iterator curve_endit = path_it->end_default(); - if (path_it->closed()) { - const Geom::Curve &closingline = path_it->back_closed(); - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - curve_endit = path_it->end_open(); - } - } - - while ( curve_it2 != curve_endit ) - { - Geom::Point p = curve_it1->finalPoint(); - path[ip].x = p[X]; - path[ip].y = p[Y]; - - bool this_is_line = is_straight_curve(*curve_it1); - bool next_is_line = is_straight_curve(*curve_it2); - - Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, *curve_it2); - - if ( nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM ) - { - if (this_is_line && !next_is_line) { - path[ip].ty = ']'; - } else if (next_is_line && !this_is_line) { - path[ip].ty = '['; - } else { - path[ip].ty = 'c'; - } - } else { - path[ip].ty = 'v'; - } - - ++curve_it1; - ++curve_it2; - ip++; - } - - Geom::Point p = curve_it1->finalPoint(); - path[ip].x = p[X]; - path[ip].y = p[Y]; - if (path_it->closed()) { - Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, path_it->front()); - switch (nodetype) { - case Geom::NODE_NONE: - path[ip].ty = '}'; - ip++; - break; - case Geom::NODE_CUSP: - path[0].ty = path[ip].ty = 'v'; - break; - case Geom::NODE_SMOOTH: - case Geom::NODE_SYMM: - path[0].ty = path[ip].ty = 'c'; - break; - } - } else { - path[ip].ty = '}'; - ip++; - } - - int sp_len = ip; - Spiro::spiro_run(path, sp_len, *curve); - ip = 0; - } - - g_free (path); -} - void PenTool::_setSubsequentPoint(Geom::Point const p, bool statusbar, guint status) { g_assert( this->npoints != 0 ); diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 0ae16caf0..3c27703eb 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -112,8 +112,6 @@ private: void _bsplineSpiroEndAnchorOff(); //CHECK: join all the curves "in game" and we call doEffect function void _bsplineSpiroBuild(); - //function bspline cloned from lpe-bspline.cpp - void _bsplineDoEffect(SPCurve * curve); //function spiro cloned from lpe-spiro.cpp void _spiroDoEffect(SPCurve * curve); -- cgit v1.2.3 From 04275f838ded3768133f25b68cb5f7fc457f7a11 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 6 Aug 2015 23:53:53 +0200 Subject: Remove unused function declaration and change some comments (bzr r14281) --- src/ui/tools/pen-tool.h | 100 ++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 3c27703eb..5a21e3bac 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -22,21 +22,21 @@ namespace Tools { */ class PenTool : public FreehandBase { public: - PenTool(); - PenTool(gchar const *const *cursor_shape, gint hot_x, gint hot_y); - virtual ~PenTool(); - - enum Mode { - MODE_CLICK, - MODE_DRAG - }; - - enum State { - POINT, - CONTROL, - CLOSE, - STOP - }; + PenTool(); + PenTool(gchar const *const *cursor_shape, gint hot_x, gint hot_y); + virtual ~PenTool(); + + enum Mode { + MODE_CLICK, + MODE_DRAG + }; + + enum State { + POINT, + CONTROL, + CLOSE, + STOP + }; Geom::Point p[5]; @@ -66,28 +66,28 @@ public: bool events_disabled; - static const std::string prefsPath; + static const std::string prefsPath; - virtual const std::string& getPrefsPath(); + virtual const std::string& getPrefsPath(); - int nextParaxialDirection(Geom::Point const &pt, Geom::Point const &origin, guint state) const; - void setPolylineMode(); - bool hasWaitingLPE(); + int nextParaxialDirection(Geom::Point const &pt, Geom::Point const &origin, guint state) const; + void setPolylineMode(); + bool hasWaitingLPE(); void waitForLPEMouseClicks(Inkscape::LivePathEffect::EffectType effect_type, unsigned int num_clicks, bool use_polylines = true); protected: - virtual void setup(); - virtual void finish(); - virtual void set(const Inkscape::Preferences::Entry& val); - virtual bool root_handler(GdkEvent* event); - virtual bool item_handler(SPItem* item, GdkEvent* event); + virtual void setup(); + virtual void finish(); + virtual void set(const Inkscape::Preferences::Entry& val); + virtual bool root_handler(GdkEvent* event); + virtual bool item_handler(SPItem* item, GdkEvent* event); private: - bool _handleButtonPress(GdkEventButton const &bevent); - bool _handleMotionNotify(GdkEventMotion const &mevent); - bool _handleButtonRelease(GdkEventButton const &revent); - bool _handle2ButtonPress(GdkEventButton const &bevent); - bool _handleKeyPress(GdkEvent *event); + bool _handleButtonPress(GdkEventButton const &bevent); + bool _handleMotionNotify(GdkEventMotion const &mevent); + bool _handleButtonRelease(GdkEventButton const &revent); + bool _handle2ButtonPress(GdkEventButton const &bevent); + bool _handleKeyPress(GdkEvent *event); //adds spiro & bspline modes void _penContextSetMode(guint mode); //this function changes the colors red, green and blue making them transparent or not depending on if the function uses spiro @@ -110,38 +110,36 @@ private: void _bsplineSpiroEndAnchorOn(); //closes the curve with the last node in CUSP mode void _bsplineSpiroEndAnchorOff(); - //CHECK: join all the curves "in game" and we call doEffect function + //apply the effect void _bsplineSpiroBuild(); - //function spiro cloned from lpe-spiro.cpp - void _spiroDoEffect(SPCurve * curve); - void _setInitialPoint(Geom::Point const p); - void _setSubsequentPoint(Geom::Point const p, bool statusbar, guint status = 0); - void _setCtrl(Geom::Point const p, guint state); - void _finishSegment(Geom::Point p, guint state); + void _setInitialPoint(Geom::Point const p); + void _setSubsequentPoint(Geom::Point const p, bool statusbar, guint status = 0); + void _setCtrl(Geom::Point const p, guint state); + void _finishSegment(Geom::Point p, guint state); bool _undoLastPoint(); - void _finish(gboolean closed); + void _finish(gboolean closed); - void _resetColors(); + void _resetColors(); - void _disableEvents(); - void _enableEvents(); + void _disableEvents(); + void _enableEvents(); - void _setToNearestHorizVert(Geom::Point &pt, guint const state, bool snap) const; + void _setToNearestHorizVert(Geom::Point &pt, guint const state, bool snap) const; - void _setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_to_compare, gchar const *message); + void _setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_to_compare, gchar const *message); - void _lastpointToLine(); - void _lastpointToCurve(); - void _lastpointMoveScreen(gdouble x, gdouble y); - void _lastpointMove(gdouble x, gdouble y); - void _redrawAll(); + void _lastpointToLine(); + void _lastpointToCurve(); + void _lastpointMoveScreen(gdouble x, gdouble y); + void _lastpointMove(gdouble x, gdouble y); + void _redrawAll(); - void _endpointSnapHandle(Geom::Point &p, guint const state) const; - void _endpointSnap(Geom::Point &p, guint const state) const; + void _endpointSnapHandle(Geom::Point &p, guint const state) const; + void _endpointSnap(Geom::Point &p, guint const state) const; - void _cancel(); + void _cancel(); }; } -- cgit v1.2.3 From 7ffbb0399458946dfdbbd14438521ab52acf48a6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 7 Aug 2015 23:54:00 +0200 Subject: Full refactor of the LPE now too much simple code (bzr r14272.1.6) --- src/live_effects/lpe-bendpath.cpp | 120 ++++++++++++++++-------------- src/live_effects/lpe-bendpath.h | 18 ++--- src/live_effects/lpe-patternalongpath.cpp | 120 ++++++++++++++++++------------ src/live_effects/lpe-patternalongpath.h | 17 +++-- 4 files changed, 158 insertions(+), 117 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 9b015245d..d80f8e33a 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -20,7 +20,13 @@ #include <2geom/d2.h> #include <2geom/piecewise.h> +#include "knot-holder-entity.h" +#include "knotholder.h" + +#include + #include + using std::vector; @@ -48,29 +54,33 @@ first) but I think we can first forget about them. namespace Inkscape { namespace LivePathEffect { +Geom::PathVector bp_helper_path; +namespace BeP { +class KnotHolderEntityWidthBendPath : public LPEKnotHolderEntity { + public: + KnotHolderEntityWidthBendPath(LPEBendPath * effect) : LPEKnotHolderEntity(effect) {} + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; + }; +} // BeP LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) : Effect(lpeobject), bend_path(_("Bend path:"), _("Path along which to bend the original path"), "bendpath", &wr, this, "M0,0 L1,0"), + original_height(0.0), prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1.0), - width(_("Width distance"), _("Change the width of bend path - Ctrl+Alt+Click: reset"), "width", &wr, this), scale_y_rel(_("W_idth in units of length"), _("Scale the width of the path in units of its length"), "scale_y_rel", &wr, this, false), - vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false), - height(0.0), - original_height(0.0), - prop_scale_from_widget(1.0), - firstTime(false), - secondTime(false) + vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false) { registerParameter( dynamic_cast(&bend_path) ); registerParameter( dynamic_cast(&prop_scale) ); registerParameter( dynamic_cast(&scale_y_rel) ); registerParameter( dynamic_cast(&vertical_pattern) ); - registerParameter( dynamic_cast(&width) ); prop_scale.param_set_digits(3); prop_scale.param_set_increments(0.01, 0.10); + _provides_knotholder_entities = true; concatenate_before_pwd2 = true; } @@ -82,56 +92,11 @@ LPEBendPath::~LPEBendPath() void LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) { - hp.clear(); // get the item bounding box original_bbox(lpeitem); original_height = boundingbox_Y.max() - boundingbox_Y.min(); - Geom::Path path_in = bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); - Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); - Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0)); - Geom::Curve const *first_curve = &path_in.curveAt(Geom::PathTime(0, 0.0)); - Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); - Geom::Ray ray(ptA, B); - if (cubic) { - ray.setPoints(ptA,(*cubic)[1]); - } - - Geom::Angle first_curve_angle = ray.transformed(Geom::Rotate(Geom::deg_to_rad(90))).angle(); - //This Hack is to fix a boring bug in the first call to the function, we have - //a wrong "ptA" - if(!firstTime && Geom::are_near(width, Geom::Point())){ - firstTime = true; - } else if(firstTime && Geom::are_near(width, Geom::Point())){ - Geom::Point default_point = Geom::Point::polar(first_curve_angle, original_height/2.0) + ptA; - prop_scale.param_set_value(1.0); - height = original_height; - width.param_setValue(default_point); - width.param_update_default(default_point); - } else { - double distance_knot = Geom::distance(width , ptA); - width.param_setValue(Geom::Point::polar(first_curve_angle, distance_knot) + ptA); - height = distance_knot * 2; - if(secondTime){ - prop_scale.param_set_value(1); - height = original_height; - width.param_setValue(Geom::Point::polar(first_curve_angle, height/2.0) + ptA); - secondTime = false; - } else if(prop_scale_from_widget == prop_scale){ - prop_scale.param_set_value(height/original_height); - } else { - height = original_height * prop_scale; - width.param_setValue(Geom::Point::polar(first_curve_angle, height/2.0) + ptA); - } - if(firstTime){ - firstTime = false; - secondTime = true; - } - } - prop_scale_from_widget = prop_scale; - Geom::Path hp_path(width); - hp_path.appendNew(ptA); - hp.push_back(hp_path); SPLPEItem * item = const_cast(lpeitem); + item->apply_to_clippath(item); item->apply_to_mask(item); } @@ -206,9 +171,54 @@ LPEBendPath::resetDefaults(SPItem const* item) void LPEBendPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) { - hp_vec.push_back(hp); + hp_vec.push_back(bp_helper_path); } +void +LPEBendPath::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) +{ + KnotHolderEntity *e = new BeP::KnotHolderEntityWidthBendPath(this); + e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE); + knotholder->add(e); +} + +namespace BeP { + +void +KnotHolderEntityWidthBendPath::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) +{ + LPEBendPath *lpe = dynamic_cast (_effect); + + Geom::Point const s = snap_knot_position(p, state); + Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); + Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); + lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); +} + +Geom::Point +KnotHolderEntityWidthBendPath::knot_get() const +{ + LPEBendPath *lpe = dynamic_cast (_effect); + + bp_helper_path.clear(); + Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); + Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); + Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in.curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints(ptA,(*cubic)[1]); + } + Geom::Angle first_curve_angle = ray.transformed(Geom::Rotate(Geom::deg_to_rad(90))).angle(); + Geom::Point result_point = Geom::Point::polar(first_curve_angle, (lpe->original_height * lpe->prop_scale)/2.0) + ptA; + Geom::Path hp_path(result_point); + hp_path.appendNew(ptA); + bp_helper_path.push_back(hp_path); + return result_point; +} +} // namespace BeP } // namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 5d58f3320..eeda86a5e 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -14,7 +14,6 @@ #include "live_effects/effect.h" #include "live_effects/parameter/path.h" #include "live_effects/parameter/bool.h" -#include "live_effects/parameter/point.h" #include <2geom/sbasis.h> #include <2geom/sbasis-geometric.h> @@ -28,6 +27,9 @@ namespace Inkscape { namespace LivePathEffect { +namespace BeP { +class KnotHolderEntityWidthBendPath; +} //for Bend path on group : we need information concerning the group Bounding box class LPEBendPath : public Effect, GroupBBoxEffect { @@ -43,21 +45,19 @@ public: void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec); + virtual void addKnotHolderEntities(KnotHolder * knotholder, SPDesktop * desktop, SPItem * item); + PathParam bend_path; -private: + friend class BeP::KnotHolderEntityWidthBendPath; +protected: + double original_height; ScalarParam prop_scale; - PointParam width; +private: BoolParam scale_y_rel; BoolParam vertical_pattern; - double height; - double original_height; - double prop_scale_from_widget; - bool firstTime; - bool secondTime; Geom::Piecewise > uskeleton; Geom::Piecewise > n; - Geom::PathVector hp; void on_pattern_pasted(); diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index 53730d4d4..72e1892ef 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -18,6 +18,9 @@ #include <2geom/d2.h> #include <2geom/piecewise.h> +#include "knot-holder-entity.h" +#include "knotholder.h" + #include using std::vector; @@ -45,6 +48,16 @@ first) but I think we can first forget about them. namespace Inkscape { namespace LivePathEffect { +Geom::PathVector pap_helper_path; + +namespace WPAP { + class KnotHolderEntityWidthPatternAlongPath : public LPEKnotHolderEntity { + public: + KnotHolderEntityWidthPatternAlongPath(LPEPatternAlongPath * effect) : LPEKnotHolderEntity(effect) {} + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; + }; +} // WPAP static const Util::EnumData PAPCopyTypeData[PAPCT_END] = { {PAPCT_SINGLE, N_("Single"), "single"}, @@ -57,10 +70,10 @@ static const Util::EnumDataConverter PAPCopyTypeConverter(PAPCopyTy LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : Effect(lpeobject), pattern(_("Pattern source:"), _("Path to put along the skeleton path"), "pattern", &wr, this, "M0,0 L1,0"), + original_height(0), + prop_scale(_("_Width:"), _("Width of the pattern"), "prop_scale", &wr, this, 1.0), copytype(_("Pattern copies:"), _("How many pattern copies to place along the skeleton path"), "copytype", PAPCopyTypeConverter, &wr, this, PAPCT_SINGLE_STRETCHED), - prop_scale(_("_Width:"), _("Width of the pattern"), "prop_scale", &wr, this, 1.0), - width(_("Width distance"), _("Change the width of pattern path - Ctrl+Alt+Click: reset"), "width", &wr, this), scale_y_rel(_("Wid_th in units of length"), _("Scale the width of the pattern in units of its length"), "scale_y_rel", &wr, this, false), @@ -76,10 +89,7 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : vertical_pattern(_("Pattern is _vertical"), _("Rotate pattern 90 deg before applying"), "vertical_pattern", &wr, this, false), fuse_tolerance(_("_Fuse nearby ends:"), _("Fuse ends closer than this number. 0 means don't fuse."), - "fuse_tolerance", &wr, this, 0), - height(0), - original_height(0), - prop_scale_from_widget(1) + "fuse_tolerance", &wr, this, 0) { registerParameter( dynamic_cast(&pattern) ); registerParameter( dynamic_cast(©type) ); @@ -91,9 +101,11 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast(&prop_units) ); registerParameter( dynamic_cast(&vertical_pattern) ); registerParameter( dynamic_cast(&fuse_tolerance) ); - registerParameter( dynamic_cast(&width) ); prop_scale.param_set_digits(3); prop_scale.param_set_increments(0.01, 0.10); + + _provides_knotholder_entities = true; + } LPEPatternAlongPath::~LPEPatternAlongPath() @@ -104,49 +116,10 @@ LPEPatternAlongPath::~LPEPatternAlongPath() void LPEPatternAlongPath::doBeforeEffect (SPLPEItem const* lpeitem) { - hp.clear(); // get the pattern bounding box Geom::OptRect bbox = pattern.get_pathvector().boundsFast(); if (bbox) { original_height = (*bbox)[Geom::Y].max() - (*bbox)[Geom::Y].min(); - SPShape const *sp_shape = dynamic_cast(lpeitem); - if (sp_shape) { - Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); - Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); - Geom::Point B = path_in->pointAt(Geom::PathTime(1, 0.0)); - Geom::Curve const *first_curve = &path_in->curveAt(Geom::PathTime(0, 0.0)); - Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); - Geom::Ray ray(ptA, B); - if (cubic) { - ray.setPoints((*cubic)[1], ptA); - } - //This Hack is to fix a boring bug in the first call to the function, we have - //a wrong "ptA" - if(height == 0.0 && Geom::are_near(width, Geom::Point())){ - height = 0.1; - std::cout << ptA << "ptA0.5\n"; - } else if(height == 0.1 && Geom::are_near(width, Geom::Point())){ - Geom::Point default_point = Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), (original_height/2.0)) + ptA; - prop_scale.param_set_value(1.0); - height = original_height; - width.param_setValue(default_point); - width.param_update_default(default_point); - } else { - double distance_knot = Geom::distance(width , ptA); - width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), distance_knot) + ptA); - height = distance_knot * 2; - if(prop_scale_from_widget == prop_scale){ - prop_scale.param_set_value(height/original_height); - } else { - height = original_height * prop_scale; - width.param_setValue(Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), height/2.0) + ptA); - } - } - prop_scale_from_widget = prop_scale; - Geom::Path hp_path(width); - hp_path.appendNew(ptA); - hp.push_back(hp_path); - } } } @@ -294,9 +267,62 @@ LPEPatternAlongPath::transform_multiply(Geom::Affine const& postmul, bool set) void LPEPatternAlongPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) { - hp_vec.push_back(hp); + hp_vec.push_back(pap_helper_path); } + +void +LPEPatternAlongPath::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) +{ + KnotHolderEntity *e = new WPAP::KnotHolderEntityWidthPatternAlongPath(this); + e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE); + knotholder->add(e); +} + +namespace WPAP { + +void +KnotHolderEntityWidthPatternAlongPath::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) +{ + LPEPatternAlongPath *lpe = dynamic_cast (_effect); + + Geom::Point const s = snap_knot_position(p, state); + SPShape const *sp_shape = dynamic_cast(SP_LPE_ITEM(item)); + if (sp_shape) { + Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); + Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); + lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); +} + +Geom::Point +KnotHolderEntityWidthPatternAlongPath::knot_get() const +{ + LPEPatternAlongPath *lpe = dynamic_cast (_effect); + + SPShape const *sp_shape = dynamic_cast(SP_LPE_ITEM(item)); + if (sp_shape) { + pap_helper_path.clear(); + Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); + Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); + Geom::Point B = path_in->pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in->curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints((*cubic)[1], ptA); + } + Geom::Angle first_curve_angle = ray.transformed(Geom::Rotate(Geom::deg_to_rad(90))).angle(); + Geom::Point result_point = Geom::Point::polar(first_curve_angle, (lpe->original_height * lpe->prop_scale)/2.0) + ptA; + Geom::Path hp_path(result_point); + hp_path.appendNew(ptA); + pap_helper_path.push_back(hp_path); + return result_point; + } + return Geom::Point(); +} +} // namespace WPAP } // namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-patternalongpath.h b/src/live_effects/lpe-patternalongpath.h index df0ae9777..3b9a17ab0 100644 --- a/src/live_effects/lpe-patternalongpath.h +++ b/src/live_effects/lpe-patternalongpath.h @@ -18,6 +18,10 @@ namespace Inkscape { namespace LivePathEffect { +namespace WPAP { +class KnotHolderEntityWidthPatternAlongPath; +} + enum PAPCopyType { PAPCT_SINGLE = 0, PAPCT_SINGLE_STRETCHED, @@ -39,12 +43,17 @@ public: void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec); + virtual void addKnotHolderEntities(KnotHolder * knotholder, SPDesktop * desktop, SPItem * item); PathParam pattern; + + friend class WPAP::KnotHolderEntityWidthPatternAlongPath; +protected: + double original_height; + ScalarParam prop_scale; + private: EnumParam copytype; - ScalarParam prop_scale; - PointParam width; BoolParam scale_y_rel; ScalarParam spacing; ScalarParam normal_offset; @@ -52,10 +61,6 @@ private: BoolParam prop_units; BoolParam vertical_pattern; ScalarParam fuse_tolerance; - double height; - double original_height; - double prop_scale_from_widget; - Geom::PathVector hp; void on_pattern_pasted(); LPEPatternAlongPath(const LPEPatternAlongPath&); -- cgit v1.2.3 From 8887b2a26bf5f558db43f6cda7bdd504b474bea3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 8 Aug 2015 01:58:22 +0200 Subject: Fix a bug scaling path parameters (bzr r14282) --- src/ui/tools/freehand-base.cpp | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 31fb2f376..4e5fcfbee 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -215,7 +215,7 @@ static Glib::ustring const tool_name(FreehandBase *dc) : "/tools/freehand/pencil" ); } -static void spdc_paste_curve_as_freehand_shape(gchar const *svgd, FreehandBase *dc, SPItem *item) +static void spdc_paste_curve_as_freehand_shape(Geom::PathVector const &newpath, FreehandBase *dc, SPItem *item) { using namespace Inkscape::LivePathEffect; @@ -223,7 +223,7 @@ static void spdc_paste_curve_as_freehand_shape(gchar const *svgd, FreehandBase * Effect::createAndApply(PATTERN_ALONG_PATH, dc->desktop->doc(), item); Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); - static_cast(lpe)->pattern.paste_param_path(svgd); + static_cast(lpe)->pattern.set_new_value(newpath,true); } static void spdc_apply_powerstroke_shape(const std::vector & points, FreehandBase *dc, SPItem *item) @@ -385,8 +385,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, c->curveto(SHAPE_LENGTH, (1 + C1) * SHAPE_HEIGHT/2, (1 + C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, SHAPE_LENGTH/2, SHAPE_HEIGHT); c->curveto((1 - C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, 0, (1 + C1) * SHAPE_HEIGHT/2, 0, SHAPE_HEIGHT/2); c->closepath(); - gchar const *svgd = sp_svg_write_path(c->get_pathvector()); - spdc_paste_curve_as_freehand_shape(svgd, dc, item); + spdc_paste_curve_as_freehand_shape(c->get_pathvector(), dc, item); c->unref(); shape_applied = true; @@ -396,11 +395,27 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, { // take shape from clipboard; Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); - Glib::ustring svgd = cm->getPathParameter(SP_ACTIVE_DESKTOP); - if(svgd != ""){ - previous_shape_pathv = sp_svg_read_pathv(svgd.data()); - spdc_paste_curve_as_freehand_shape(svgd.data(), dc, item); - shape_applied = true; + if(cm->paste(SP_ACTIVE_DESKTOP,true) == true){ + SPItem * pasted_clipboard = dc->selection->singleItem(); + if(pasted_clipboard){ + Inkscape::XML::Node *pasted_clipboard_root = pasted_clipboard->getRepr(); + Inkscape::XML::Node *path = sp_repr_lookup_name(pasted_clipboard_root, "svg:path", -1); // unlimited search depth + if ( path != NULL ) { + gchar const *svgd = path->attribute("d"); + dc->selection->remove(SP_OBJECT(pasted_clipboard)); + previous_shape_pathv = sp_svg_read_pathv(svgd); + previous_shape_pathv *= pasted_clipboard->transform; + spdc_paste_curve_as_freehand_shape(previous_shape_pathv, dc, item); + + shape = CLIPBOARD; + shape_applied = true; + pasted_clipboard->deleteObject(); + } else { + shape = NONE; + } + } else { + shape = NONE; + } } else { shape = NONE; } @@ -421,6 +436,8 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, bend_item->transform.setExpansionY(expansion_Y); spdc_apply_bend_shape(svgd, dc, bend_item); dc->selection->add(SP_OBJECT(bend_item)); + + shape = BEND_CLIPBOARD; } else { shape = NONE; } @@ -433,8 +450,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, { if(previous_shape_type == CLIPBOARD){ if(previous_shape_pathv.size() != 0){ - gchar const *svgd = sp_svg_write_path(previous_shape_pathv); - spdc_paste_curve_as_freehand_shape(svgd, dc, item); + spdc_paste_curve_as_freehand_shape(previous_shape_pathv, dc, item); shape_applied = true; shape = CLIPBOARD; @@ -457,6 +473,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, bend_item->transform.setExpansionY(expansion_Y); spdc_apply_bend_shape(svgd, dc, bend_item); dc->selection->add(SP_OBJECT(bend_item)); + shape = BEND_CLIPBOARD; } else { shape = NONE; -- cgit v1.2.3 From e37df71275e0b1b195924670766d5408a80cca31 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 8 Aug 2015 02:23:52 +0200 Subject: allow more translations than only scale (bzr r14283) --- src/ui/tools/freehand-base.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 4e5fcfbee..a889a12e6 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -429,11 +429,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, bend_item = dc->selection->singleItem(); if(bend_item){ bend_item->moveTo(item,false); - Geom::Coord expansion_X = bend_item->transform.expansionX(); - Geom::Coord expansion_Y = bend_item->transform.expansionY(); - bend_item->transform = Geom::Affine(1,0,0,1,0,0); - bend_item->transform.setExpansionX(expansion_X); - bend_item->transform.setExpansionY(expansion_Y); + bend_item->transform.setTranslation(Geom::Point()); spdc_apply_bend_shape(svgd, dc, bend_item); dc->selection->add(SP_OBJECT(bend_item)); -- cgit v1.2.3 From ec559a5dfe4b9ab24a9e8a0799fa490b70c1f0a4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 8 Aug 2015 12:28:31 +0200 Subject: minor changes (bzr r14272.1.10) --- src/live_effects/lpe-bendpath.cpp | 12 ++++++++---- src/live_effects/lpe-patternalongpath.cpp | 13 ++++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index d80f8e33a..5c20a7f9e 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -193,6 +193,7 @@ KnotHolderEntityWidthBendPath::knot_set(Geom::Point const &p, Geom::Point const& Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); } @@ -201,7 +202,6 @@ KnotHolderEntityWidthBendPath::knot_get() const { LPEBendPath *lpe = dynamic_cast (_effect); - bp_helper_path.clear(); Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0)); @@ -213,9 +213,13 @@ KnotHolderEntityWidthBendPath::knot_get() const } Geom::Angle first_curve_angle = ray.transformed(Geom::Rotate(Geom::deg_to_rad(90))).angle(); Geom::Point result_point = Geom::Point::polar(first_curve_angle, (lpe->original_height * lpe->prop_scale)/2.0) + ptA; - Geom::Path hp_path(result_point); - hp_path.appendNew(ptA); - bp_helper_path.push_back(hp_path); + + bp_helper_path.clear(); + Geom::Path hp(result_point); + hp.appendNew(ptA); + bp_helper_path.push_back(hp); + hp.clear(); + return result_point; } } // namespace BeP diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index 72e1892ef..ed377e7f9 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -285,7 +285,7 @@ void KnotHolderEntityWidthPatternAlongPath::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) { LPEPatternAlongPath *lpe = dynamic_cast (_effect); - + Geom::Point const s = snap_knot_position(p, state); SPShape const *sp_shape = dynamic_cast(SP_LPE_ITEM(item)); if (sp_shape) { @@ -303,7 +303,6 @@ KnotHolderEntityWidthPatternAlongPath::knot_get() const SPShape const *sp_shape = dynamic_cast(SP_LPE_ITEM(item)); if (sp_shape) { - pap_helper_path.clear(); Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); Geom::Point B = path_in->pointAt(Geom::PathTime(1, 0.0)); @@ -315,9 +314,13 @@ KnotHolderEntityWidthPatternAlongPath::knot_get() const } Geom::Angle first_curve_angle = ray.transformed(Geom::Rotate(Geom::deg_to_rad(90))).angle(); Geom::Point result_point = Geom::Point::polar(first_curve_angle, (lpe->original_height * lpe->prop_scale)/2.0) + ptA; - Geom::Path hp_path(result_point); - hp_path.appendNew(ptA); - pap_helper_path.push_back(hp_path); + + pap_helper_path.clear(); + Geom::Path hp(result_point); + hp.appendNew(ptA); + pap_helper_path.push_back(hp); + hp.clear(); + return result_point; } return Geom::Point(); -- cgit v1.2.3 From ea061109b19616f4bef39cbe77c4f16c7a28208d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 8 Aug 2015 22:19:02 +0200 Subject: minor coding style changes (bzr r14284) --- src/ui/tool/multi-path-manipulator.cpp | 9 +++--- src/ui/tool/node.cpp | 52 +++++++++++++++++----------------- 2 files changed, 31 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 46c6246a1..9ec6f733f 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -683,13 +683,14 @@ bool MultiPathManipulator::event(Inkscape::UI::Tools::ToolBase *event_context, G //if the trace is bspline ( mode 2) if(mode==2){ // is this correct ? - if(del_preserves_shape ^ held_control(event->key)) + if(del_preserves_shape ^ held_control(event->key)){ deleteNodes(false); - else + } else { deleteNodes(true); - } - else + } + } else { deleteNodes(del_preserves_shape ^ held_control(event->key)); + } // Delete any selected gradient nodes as well event_context->deleteSelectedDrag(held_control(event->key)); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index ca6f5abb1..eaec4477a 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -176,8 +176,8 @@ void Handle::move(Geom::Point const &new_pos) //move the handler and its oposite the same proportion if(_pm()._isBSpline()){ - setPosition(_pm()._bsplineHandleReposition(this,this)); - this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(),this)); + setPosition(_pm()._bsplineHandleReposition(this, this)); + this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), this)); } return; } @@ -193,8 +193,8 @@ void Handle::move(Geom::Point const &new_pos) //move the handler and its oposite the same proportion if(_pm()._isBSpline()){ - setPosition(_pm()._bsplineHandleReposition(this,this)); - this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(),this)); + setPosition(_pm()._bsplineHandleReposition(this, this)); + this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), this)); } return; @@ -219,8 +219,8 @@ void Handle::move(Geom::Point const &new_pos) // moves the handler and its oposite the same proportion if(_pm()._isBSpline()){ - setPosition(_pm()._bsplineHandleReposition(this,this)); - this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(),this)); + setPosition(_pm()._bsplineHandleReposition(this, this)); + this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), this)); } } @@ -313,8 +313,8 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven //this function moves the handler and its oposite to the default proportion of defaultStartPower void Handle::handle_2button_press(){ if(_pm()._isBSpline()){ - setPosition(_pm()._bsplineHandleReposition(this,defaultStartPower)); - this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(),defaultStartPower)); + setPosition(_pm()._bsplineHandleReposition(this, defaultStartPower)); + this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), defaultStartPower)); _pm().update(); } } @@ -375,7 +375,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) if(_pm()._isBSpline()){ setPosition(new_pos); int steps = _pm()._bsplineGetSteps(); - new_pos=_pm()._bsplineHandleReposition(this,ceilf(_pm()._bsplineHandlePosition(this,this)*steps)/steps); + new_pos=_pm()._bsplineHandleReposition(this,ceilf(_pm()._bsplineHandlePosition(this, this)*steps)/steps); } } @@ -549,7 +549,7 @@ Glib::ustring Handle::_getTip(unsigned state) const "Auto node handle: drag to convert to smooth node (%s)"), more); }else{ return format_tip(C_("Path handle tip", - "BSpline node handle: Shift to drag, double click to reset (%s). %g power"),more,_pm()._bsplineHandlePosition(h,NULL)); + "BSpline node handle: Shift to drag, double click to reset (%s). %g power"),more,_pm()._bsplineHandlePosition(h, NULL)); } } } @@ -636,12 +636,12 @@ void Node::move(Geom::Point const &new_pos) nodeWeight = fmax(_pm()._bsplineHandlePosition(n->front()),_pm()._bsplineHandlePosition(n->back())); if(prevNode){ if(prevNode->isEndNode()){ - prevNodeWeight = _pm()._bsplineHandlePosition(prevNode->front(),prevNode->front()); + prevNodeWeight = _pm()._bsplineHandlePosition(prevNode->front(), prevNode->front()); } } if(nextNode){ if(nextNode->isEndNode()){ - nextNodeWeight = _pm()._bsplineHandlePosition(nextNode->back(),nextNode->back()); + nextNodeWeight = _pm()._bsplineHandlePosition(nextNode->back(), nextNode->back()); } } @@ -660,16 +660,16 @@ void Node::move(Geom::Point const &new_pos) _back.setPosition(_pm()._bsplineHandleReposition(this->back(),nodeWeight)); if(prevNode){ if(prevNode->isEndNode()){ - prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(),prevNodeWeight)); + prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(), prevNodeWeight)); }else{ - prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(),prevNode->back())); + prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(), prevNode->back())); } } if(nextNode){ if(nextNode->isEndNode()){ - nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(),nextNodeWeight)); + nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(), nextNodeWeight)); }else{ - nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(),nextNode->front())); + nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(), nextNode->front())); } } } @@ -690,12 +690,12 @@ void Node::transform(Geom::Affine const &m) nodeWeight = _pm()._bsplineHandlePosition(n->front()); if(prevNode){ if(prevNode->isEndNode()){ - prevNodeWeight = _pm()._bsplineHandlePosition(prevNode->front(),prevNode->front()); + prevNodeWeight = _pm()._bsplineHandlePosition(prevNode->front(), prevNode->front()); } } if(nextNode){ if(nextNode->isEndNode()){ - nextNodeWeight = _pm()._bsplineHandlePosition(nextNode->back(),nextNode->back()); + nextNodeWeight = _pm()._bsplineHandlePosition(nextNode->back(), nextNode->back()); } } @@ -709,20 +709,20 @@ void Node::transform(Geom::Affine const &m) // move the involved handlers, first the node ones, later the adjoining ones if(_pm()._isBSpline()){ - _front.setPosition(_pm()._bsplineHandleReposition(this->front(),nodeWeight)); - _back.setPosition(_pm()._bsplineHandleReposition(this->back(),nodeWeight)); + _front.setPosition(_pm()._bsplineHandleReposition(this->front(), nodeWeight)); + _back.setPosition(_pm()._bsplineHandleReposition(this->back(), nodeWeight)); if(prevNode){ if(prevNode->isEndNode()){ - prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(),prevNodeWeight)); + prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(), prevNodeWeight)); }else{ - prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(),prevNode->back())); + prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(), prevNode->back())); } } if(nextNode){ if(nextNode->isEndNode()){ - nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(),nextNodeWeight)); + nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(), nextNodeWeight)); }else{ - nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(),nextNode->front())); + nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(), nextNode->front())); } } } @@ -920,8 +920,8 @@ void Node::setType(NodeType type, bool update_handles) if(_pm()._bsplineHandlePosition(this->front()) != noPower ){ weight = defaultStartPower; } - _front.setPosition(_pm()._bsplineHandleReposition(this->front(),weight)); - _back.setPosition(_pm()._bsplineHandleReposition(this->back(),weight)); + _front.setPosition(_pm()._bsplineHandleReposition(this->front(), weight)); + _back.setPosition(_pm()._bsplineHandleReposition(this->back(), weight)); } } _type = type; -- cgit v1.2.3 From a2c91998644ae5a8096b0ee53beea16bee0a7ac7 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Sat, 8 Aug 2015 18:08:49 -0400 Subject: for spiro converters, close path only after last segment. (Bug 1473641) Fixed bugs: - https://launchpad.net/bugs/1473641 (bzr r14285) --- src/live_effects/spiro-converters.cpp | 32 ++++++++++++++++++++------------ src/live_effects/spiro-converters.h | 24 ++++++++++++------------ src/live_effects/spiro.cpp | 15 ++++++++------- 3 files changed, 40 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/live_effects/spiro-converters.cpp b/src/live_effects/spiro-converters.cpp index f116d5256..ee214704c 100644 --- a/src/live_effects/spiro-converters.cpp +++ b/src/live_effects/spiro-converters.cpp @@ -21,43 +21,49 @@ namespace Spiro { void -ConverterSPCurve::moveto(double x, double y, bool is_open) +ConverterSPCurve::moveto(double x, double y) { if ( IS_FINITE(x) && IS_FINITE(y) ) { _curve.moveto(x, y); - if (!is_open) { - _curve.closepath(); - } } else { SPIRO_G_MESSAGE("Spiro: moveto not finite"); } } void -ConverterSPCurve::lineto(double x, double y) +ConverterSPCurve::lineto(double x, double y, bool close_last) { if ( IS_FINITE(x) && IS_FINITE(y) ) { _curve.lineto(x, y); + if (close_last) { + _curve.closepath(); + } } else { SPIRO_G_MESSAGE("Spiro: lineto not finite"); } } void -ConverterSPCurve::quadto(double xm, double ym, double x3, double y3) +ConverterSPCurve::quadto(double xm, double ym, double x3, double y3, bool close_last) { if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) { _curve.quadto(xm, ym, x3, y3); + if (close_last) { + _curve.closepath(); + } } else { SPIRO_G_MESSAGE("Spiro: quadto not finite"); } } void -ConverterSPCurve::curveto(double x1, double y1, double x2, double y2, double x3, double y3) +ConverterSPCurve::curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last) { if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) { _curve.curveto(x1, y1, x2, y2, x3, y3); + if (close_last) { + _curve.closepath(); + } } else { SPIRO_G_MESSAGE("Spiro: curveto not finite"); } @@ -71,41 +77,43 @@ ConverterPath::ConverterPath(Geom::Path &path) } void -ConverterPath::moveto(double x, double y, bool is_open) +ConverterPath::moveto(double x, double y) { if ( IS_FINITE(x) && IS_FINITE(y) ) { _path.start(Geom::Point(x, y)); - _path.close(!is_open); } else { SPIRO_G_MESSAGE("spiro moveto not finite"); } } void -ConverterPath::lineto(double x, double y) +ConverterPath::lineto(double x, double y, bool close_last) { if ( IS_FINITE(x) && IS_FINITE(y) ) { _path.appendNew( Geom::Point(x, y) ); + _path.close(close_last); } else { SPIRO_G_MESSAGE("spiro lineto not finite"); } } void -ConverterPath::quadto(double xm, double ym, double x3, double y3) +ConverterPath::quadto(double xm, double ym, double x3, double y3, bool close_last) { if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) { _path.appendNew(Geom::Point(xm, ym), Geom::Point(x3, y3)); + _path.close(close_last); } else { SPIRO_G_MESSAGE("spiro quadto not finite"); } } void -ConverterPath::curveto(double x1, double y1, double x2, double y2, double x3, double y3) +ConverterPath::curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last) { if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) { _path.appendNew(Geom::Point(x1, y1), Geom::Point(x2, y2), Geom::Point(x3, y3)); + _path.close(close_last); } else { SPIRO_G_MESSAGE("spiro curveto not finite"); } diff --git a/src/live_effects/spiro-converters.h b/src/live_effects/spiro-converters.h index 90855d2d6..6182a5dcd 100644 --- a/src/live_effects/spiro-converters.h +++ b/src/live_effects/spiro-converters.h @@ -11,10 +11,10 @@ public: ConverterBase() {}; virtual ~ConverterBase() {}; - virtual void moveto(double x, double y, bool is_open) = 0; - virtual void lineto(double x, double y) = 0; - virtual void quadto(double x1, double y1, double x2, double y2) = 0; - virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3) = 0; + virtual void moveto(double x, double y) = 0; + virtual void lineto(double x, double y, bool close_last) = 0; + virtual void quadto(double x1, double y1, double x2, double y2, bool close_last) = 0; + virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last) = 0; }; @@ -27,10 +27,10 @@ public: : _curve(curve) {} - virtual void moveto(double x, double y, bool is_open); - virtual void lineto(double x, double y); - virtual void quadto(double x1, double y1, double x2, double y2); - virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3); + virtual void moveto(double x, double y); + virtual void lineto(double x, double y, bool close_last); + virtual void quadto(double x1, double y1, double x2, double y2, bool close_last); + virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last); private: SPCurve &_curve; @@ -47,10 +47,10 @@ class ConverterPath : public ConverterBase { public: ConverterPath(Geom::Path &path); - virtual void moveto(double x, double y, bool is_open); - virtual void lineto(double x, double y); - virtual void quadto(double x1, double y1, double x2, double y2); - virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3); + virtual void moveto(double x, double y); + virtual void lineto(double x, double y, bool close_last); + virtual void quadto(double x1, double y1, double x2, double y2, bool close_last); + virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last); private: Geom::Path &_path; diff --git a/src/live_effects/spiro.cpp b/src/live_effects/spiro.cpp index 46e53a0da..0ac2815bf 100644 --- a/src/live_effects/spiro.cpp +++ b/src/live_effects/spiro.cpp @@ -847,13 +847,13 @@ solve_spiro(spiro_seg *s, const int nseg) static void spiro_seg_to_otherpath(const double ks[4], double x0, double y0, double x1, double y1, - ConverterBase &bc, int depth) + ConverterBase &bc, int depth, bool close_last) { double bend = fabs(ks[0]) + fabs(.5 * ks[1]) + fabs(.125 * ks[2]) + fabs((1./48) * ks[3]); if (!(bend > 1e-8)) { - bc.lineto(x1, y1); + bc.lineto(x1, y1, close_last); } else { double seg_ch = hypot(x1 - x0, y1 - y0); double seg_th = atan2(y1 - y0, x1 - x0); @@ -876,7 +876,7 @@ spiro_seg_to_otherpath(const double ks[4], vl = (scale * (1./3)) * sin(th_even - th_odd); ur = (scale * (1./3)) * cos(th_even + th_odd); vr = (scale * (1./3)) * sin(th_even + th_odd); - bc.curveto(x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1); + bc.curveto(x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1, close_last); } else { /* subdivide */ double ksub[4]; @@ -895,11 +895,11 @@ spiro_seg_to_otherpath(const double ks[4], integrate_spiro(ksub, xysub); xmid = x0 + cth * xysub[0] - sth * xysub[1]; ymid = y0 + cth * xysub[1] + sth * xysub[0]; - spiro_seg_to_otherpath(ksub, x0, y0, xmid, ymid, bc, depth + 1); + spiro_seg_to_otherpath(ksub, x0, y0, xmid, ymid, bc, depth + 1, false); ksub[0] += .25 * ks[1] + (1./384) * ks[3]; ksub[1] += .125 * ks[2]; ksub[2] += (1./16) * ks[3]; - spiro_seg_to_otherpath(ksub, xmid, ymid, x1, y1, bc, depth + 1); + spiro_seg_to_otherpath(ksub, xmid, ymid, x1, y1, bc, depth + 1, close_last); } } } @@ -933,9 +933,10 @@ spiro_to_otherpath(const spiro_seg *s, int n, ConverterBase &bc) double y1 = s[i + 1].y; if (i == 0) { - bc.moveto(x0, y0, s[0].ty == '{'); + bc.moveto(x0, y0); } - spiro_seg_to_otherpath(s[i].ks, x0, y0, x1, y1, bc, 0); + // on the last segment, set the 'close_last' flag if path is closed + spiro_seg_to_otherpath(s[i].ks, x0, y0, x1, y1, bc, 0, (nsegs == n) && (i == n - 1)); } } -- cgit v1.2.3 From ecf586f701c881523a035178baa6322564f80c0c Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Tue, 11 Aug 2015 16:28:35 +0200 Subject: Translations. Second set of new Indian languages translations (Bodo, Malayalam, Marathi, Urdu, Sindhi [PA and Devanagari], and Sanskrit). Fixed bugs: - https://launchpad.net/bugs/1316442 - https://launchpad.net/bugs/1316564 - https://launchpad.net/bugs/1316427 - https://launchpad.net/bugs/1316572 - https://launchpad.net/bugs/1316570 - https://launchpad.net/bugs/1316566 (bzr r14288) --- src/ui/dialog/inkscape-preferences.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 2bfec2ad7..84eb8435b 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -523,21 +523,21 @@ void InkscapePreferences::initPageUI() _path_ui = _page_list.get_model()->get_path(iter_ui); Glib::ustring languages[] = {_("System default"), _("Albanian (sq)"), _("Amharic (am)"), _("Arabic (ar)"), _("Armenian (hy)"), _("Assamese (as)"), _("Azerbaijani (az)"), _("Basque (eu)"), _("Belarusian (be)"), - _("Bulgarian (bg)"), _("Bengali (bn)"), _("Bengali/Bangladesh (bn_BD)"), _("Breton (br)"), _("Catalan (ca)"), _("Valencian Catalan (ca@valencia)"), _("Chinese/China (zh_CN)"), + _("Bulgarian (bg)"), _("Bengali (bn)"), _("Bengali/Bangladesh (bn_BD)"), _("Bodo (brx)"), _("Breton (br)"), _("Catalan (ca)"), _("Valencian Catalan (ca@valencia)"), _("Chinese/China (zh_CN)"), _("Chinese/Taiwan (zh_TW)"), _("Croatian (hr)"), _("Czech (cs)"), _("Danish (da)"), _("Dogri (doi)"), _("Dutch (nl)"), _("Dzongkha (dz)"), _("German (de)"), _("Greek (el)"), _("English (en)"), _("English/Australia (en_AU)"), _("English/Canada (en_CA)"), _("English/Great Britain (en_GB)"), _("Pig Latin (en_US@piglatin)"), _("Esperanto (eo)"), _("Estonian (et)"), _("Farsi (fa)"), _("Finnish (fi)"), _("French (fr)"), _("Irish (ga)"), _("Galician (gl)"), _("Gujarati (gu)"), _("Hebrew (he)"), _("Hindi (hi)"), _("Hungarian (hu)"), - _("Indonesian (id)"), _("Icelandic (is)"), _("Italian (it)"), _("Japanese (ja)"), _("Khmer (km)"), _("Kinyarwanda (rw)"), _("Korean (ko)"), _("Lithuanian (lt)"), _("Latvian (lv)"), _("Macedonian (mk)"), + _("Indonesian (id)"), _("Icelandic (is)"), _("Italian (it)"), _("Japanese (ja)"), _("Khmer (km)"), _("Kinyarwanda (rw)"), _("Korean (ko)"), _("Lithuanian (lt)"), _("Latvian (lv)"), _("Macedonian (mk)"), _("Malayalam (ml)"), _("Marathi (mr)"), _("Mongolian (mn)"), _("Nepali (ne)"), _("Norwegian BokmĆ„l (nb)"), _("Norwegian Nynorsk (nn)"), _("Odia (or)"), _("Panjabi (pa)"), - _("Polish (pl)"), _("Portuguese (pt)"), _("Portuguese/Brazil (pt_BR)"), _("Romanian (ro)"), _("Russian (ru)"), _("Santali in Devnagari script (sat@deva)"), _("Santali in Ol-Chiki script (sat@olck)"), - _("Serbian (sr)"), _("Serbian in Latin script (sr@latin)"), _("Slovak (sk)"), _("Slovenian (sl)"), _("Spanish (es)"), _("Spanish/Mexico (es_MX)"), - _("Swedish (sv)"), _("Tamil (ta)"), _("Telugu (te)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Vietnamese (vi)")}; - Glib::ustring langValues[] = {"", "sq", "am", "ar", "hy", "as", "az", "eu", "be", "bg", "bn", "bn_BD", "br", "ca", "ca@valencia", "zh_CN", "zh_TW", "hr", "cs", "da", "doi", "nl", + _("Polish (pl)"), _("Portuguese (pt)"), _("Portuguese/Brazil (pt_BR)"), _("Romanian (ro)"), _("Russian (ru)"), _("Sanskrit (sa)"), _("Santali (sat)"), _("Santali in Devanagari script (sat@deva)"), + _("Serbian (sr)"), _("Serbian in Latin script (sr@latin)"), _("Sindhi (sd)"), _("Sindhi in Devanagari script (sd@deva)"), _("Slovak (sk)"), _("Slovenian (sl)"), _("Spanish (es)"), _("Spanish/Mexico (es_MX)"), + _("Swedish (sv)"), _("Tamil (ta)"), _("Telugu (te)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Urdu (ur)"), _("Vietnamese (vi)")}; + Glib::ustring langValues[] = {"", "sq", "am", "ar", "hy", "as", "az", "eu", "be", "bg", "bn", "bn_BD", "brx", "br", "ca", "ca@valencia", "zh_CN", "zh_TW", "hr", "cs", "da", "doi", "nl", "dz", "de", "el", "en", "en_AU", "en_CA", "en_GB", "en_US@piglatin", "eo", "et", "fa", "fi", "fr", "ga", - "gl", "gu", "he", "hi", "hu", "id", "is", "it", "ja", "km", "rw", "ko", "lt", "lv", "mk", "mn", "ne", "nb", "nn", "or", "pa", - "pl", "pt", "pt_BR", "ro", "ru", "sat@deva", "sat@olck", "sr", "sr@latin", "sk", "sl", "es", "es_MX", "sv", "ta", "te", "th", "tr", "uk", "vi" }; + "gl", "gu", "he", "hi", "hu", "id", "is", "it", "ja", "km", "rw", "ko", "lt", "lv", "mk", "ml", "mr", "mn", "ne", "nb", "nn", "or", "pa", + "pl", "pt", "pt_BR", "ro", "ru", "sa", "sat", "sat@deva", "sr", "sr@latin", "sd", "sd@deva", "sk", "sl", "es", "es_MX", "sv", "ta", "te", "th", "tr", "uk", "ur", "vi" }; { // sorting languages according to translated name -- cgit v1.2.3 From 86c3fa9255f57488f2fe2dc9beeccb0ecb636ecf Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 12 Aug 2015 11:12:17 +0200 Subject: Translations. Last set of new Indian languages translations (Kannada, Kashmiri [Perso-Arabic and Devanagari scripts], Kokani [Roman and Devanagari scripts], Maithili, and Manipuri [Meetei Mayek and Bengali scripts]). Fixed bugs: - https://launchpad.net/bugs/1316550 - https://launchpad.net/bugs/1316555 - https://launchpad.net/bugs/1316559 - https://launchpad.net/bugs/1316560 - https://launchpad.net/bugs/1316561 (bzr r14291) --- src/ui/dialog/inkscape-preferences.cpp | 64 +++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 84eb8435b..49864ccbb 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -522,22 +522,54 @@ void InkscapePreferences::initPageUI() Gtk::TreeModel::iterator iter_ui = this->AddPage(_page_ui, _("Interface"), PREFS_PAGE_UI); _path_ui = _page_list.get_model()->get_path(iter_ui); - Glib::ustring languages[] = {_("System default"), _("Albanian (sq)"), _("Amharic (am)"), _("Arabic (ar)"), _("Armenian (hy)"), _("Assamese (as)"), _("Azerbaijani (az)"), _("Basque (eu)"), _("Belarusian (be)"), - _("Bulgarian (bg)"), _("Bengali (bn)"), _("Bengali/Bangladesh (bn_BD)"), _("Bodo (brx)"), _("Breton (br)"), _("Catalan (ca)"), _("Valencian Catalan (ca@valencia)"), _("Chinese/China (zh_CN)"), - _("Chinese/Taiwan (zh_TW)"), _("Croatian (hr)"), _("Czech (cs)"), - _("Danish (da)"), _("Dogri (doi)"), _("Dutch (nl)"), _("Dzongkha (dz)"), _("German (de)"), _("Greek (el)"), _("English (en)"), _("English/Australia (en_AU)"), - _("English/Canada (en_CA)"), _("English/Great Britain (en_GB)"), _("Pig Latin (en_US@piglatin)"), - _("Esperanto (eo)"), _("Estonian (et)"), _("Farsi (fa)"), _("Finnish (fi)"), - _("French (fr)"), _("Irish (ga)"), _("Galician (gl)"), _("Gujarati (gu)"), _("Hebrew (he)"), _("Hindi (hi)"), _("Hungarian (hu)"), - _("Indonesian (id)"), _("Icelandic (is)"), _("Italian (it)"), _("Japanese (ja)"), _("Khmer (km)"), _("Kinyarwanda (rw)"), _("Korean (ko)"), _("Lithuanian (lt)"), _("Latvian (lv)"), _("Macedonian (mk)"), _("Malayalam (ml)"), _("Marathi (mr)"), - _("Mongolian (mn)"), _("Nepali (ne)"), _("Norwegian BokmĆ„l (nb)"), _("Norwegian Nynorsk (nn)"), _("Odia (or)"), _("Panjabi (pa)"), - _("Polish (pl)"), _("Portuguese (pt)"), _("Portuguese/Brazil (pt_BR)"), _("Romanian (ro)"), _("Russian (ru)"), _("Sanskrit (sa)"), _("Santali (sat)"), _("Santali in Devanagari script (sat@deva)"), - _("Serbian (sr)"), _("Serbian in Latin script (sr@latin)"), _("Sindhi (sd)"), _("Sindhi in Devanagari script (sd@deva)"), _("Slovak (sk)"), _("Slovenian (sl)"), _("Spanish (es)"), _("Spanish/Mexico (es_MX)"), - _("Swedish (sv)"), _("Tamil (ta)"), _("Telugu (te)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Urdu (ur)"), _("Vietnamese (vi)")}; - Glib::ustring langValues[] = {"", "sq", "am", "ar", "hy", "as", "az", "eu", "be", "bg", "bn", "bn_BD", "brx", "br", "ca", "ca@valencia", "zh_CN", "zh_TW", "hr", "cs", "da", "doi", "nl", - "dz", "de", "el", "en", "en_AU", "en_CA", "en_GB", "en_US@piglatin", "eo", "et", "fa", "fi", "fr", "ga", - "gl", "gu", "he", "hi", "hu", "id", "is", "it", "ja", "km", "rw", "ko", "lt", "lv", "mk", "ml", "mr", "mn", "ne", "nb", "nn", "or", "pa", - "pl", "pt", "pt_BR", "ro", "ru", "sa", "sat", "sat@deva", "sr", "sr@latin", "sd", "sd@deva", "sk", "sl", "es", "es_MX", "sv", "ta", "te", "th", "tr", "uk", "ur", "vi" }; + Glib::ustring languages[] = {_("System default"), + _("Albanian (sq)"), _("Amharic (am)"), _("Arabic (ar)"), _("Armenian (hy)"), _("Assamese (as)"), _("Azerbaijani (az)"), + _("Basque (eu)"), _("Belarusian (be)"), _("Bulgarian (bg)"), _("Bengali (bn)"), _("Bengali/Bangladesh (bn_BD)"), _("Bodo (brx)"), _("Breton (br)"), + _("Catalan (ca)"), _("Valencian Catalan (ca@valencia)"), _("Chinese/China (zh_CN)"), _("Chinese/Taiwan (zh_TW)"), _("Croatian (hr)"), _("Czech (cs)"), + _("Danish (da)"), _("Dogri (doi)"), _("Dutch (nl)"), _("Dzongkha (dz)"), + _("German (de)"), _("Greek (el)"), + _("English (en)"), _("English/Australia (en_AU)"), _("English/Canada (en_CA)"), _("English/Great Britain (en_GB)"), _("Pig Latin (en_US@piglatin)"), _("Esperanto (eo)"), _("Estonian (et)"), + _("Farsi (fa)"), _("Finnish (fi)"), _("French (fr)"), + _("Galician (gl)"), _("Gujarati (gu)"), + _("Hebrew (he)"), _("Hindi (hi)"), _("Hungarian (hu)"), + _("Icelandic (is)"), _("Indonesian (id)"), _("Irish (ga)"), _("Italian (it)"), + _("Japanese (ja)"), + _("Kannada (kn)"), _("Kashmiri in Peso-Arabic script (ks@aran)"), _("Kashmiri in Devanagari script (ks@deva)"), _("Khmer (km)"), _("Kinyarwanda (rw)"), _("Konkani (kok)"), _("Konkani in Latin script (kok@latin)"), _("Korean (ko)"), + _("Latvian (lv)"), _("Lithuanian (lt)"), + _("Macedonian (mk)"), _("Maithili (mai)"), _("Malayalam (ml)"), _("Manipuri (mni)"), _("Manipuri in Bengali script (mni@beng)"), _("Marathi (mr)"), _("Mongolian (mn)"), + _("Nepali (ne)"), _("Norwegian BokmĆ„l (nb)"), _("Norwegian Nynorsk (nn)"), + _("Odia (or)"), + _("Panjabi (pa)"), _("Polish (pl)"), _("Portuguese (pt)"), _("Portuguese/Brazil (pt_BR)"), + _("Romanian (ro)"), _("Russian (ru)"), + _("Sanskrit (sa)"), _("Santali (sat)"), _("Santali in Devanagari script (sat@deva)"), _("Serbian (sr)"), _("Serbian in Latin script (sr@latin)"), + _("Sindhi (sd)"), _("Sindhi in Devanagari script (sd@deva)"), _("Slovak (sk)"), _("Slovenian (sl)"), _("Spanish (es)"), _("Spanish/Mexico (es_MX)"), _("Swedish (sv)"), + _("Tamil (ta)"), _("Telugu (te)"), _("Thai (th)"), _("Turkish (tr)"), + _("Ukrainian (uk)"), _("Urdu (ur)"), + _("Vietnamese (vi)")}; + Glib::ustring langValues[] = {"", + "sq", "am", "ar", "hy", "as", "az", + "eu", "be", "bg", "bn", "bn_BD", "brx", "br", + "ca", "ca@valencia", "zh_CN", "zh_TW", "hr", "cs", + "da", "doi", "nl", "dz", + "de", "el", + "en", "en_AU", "en_CA", "en_GB", "en_US@piglatin", "eo", "et", + "fa", "fi", "fr", + "gl", "gu", + "he", "hi", "hu", + "is", "id", "ga", "it", + "ja", + "kn", "ks@aran", "ks@deva", "km", "rw", "kok", "kok@latin", "ko", + "lv", "lt", + "mk", "mai", "ml", "mni", "mni@beng", "mr", "mn", + "ne", "nb", "nn", + "or", + "pa", "pl", "pt", "pt_BR", + "ro", "ru", + "sa", "sat", "sat@deva", "sr", "sr@latin", + "sd", "sd@deva", "sk", "sl", "es", "es_MX", "sv", + "ta", "te", "th", "tr", + "uk", "ur", + "vi" }; { // sorting languages according to translated name -- cgit v1.2.3 From 6cdb4d6ac36c9d99f3b5e9b262719b480c97bcf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Luis=20Boya=20Garc=C3=ADa?= Date: Thu, 13 Aug 2015 04:47:33 +0200 Subject: Add inkview to the CMake build. (bzr r14293.1.1) --- src/CMakeLists.txt | 55 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c416b0dea..ed93d5f14 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -509,8 +509,14 @@ set(inkscape_SRC #add_inkscape_lib(sp_LIB "${sp_SRC}") #add_inkscape_lib(inkscape_LIB "${inkscape_SRC}") -# make executable for INKSCAPE -add_executable(inkscape ${main_SRC} ${inkscape_SRC} ${sp_SRC}) +# Build everything except main and inkview.c in a CMake "object" library. +# An object library is just a bunch of .o files. Linking them with main.c or inkview.c +# we get the inkscape and inkview executables respectively. +add_library(inkscape_base OBJECT ${inkscape_SRC} ${sp_SRC}) + +# make executables for inkscape and inkview +add_executable(inkscape ${main_SRC} $) +add_executable(inkview inkview.cpp $) if(UNIX) # message after building. @@ -523,31 +529,28 @@ endif() add_dependencies(inkscape inkscape_version) -target_link_libraries(inkscape - # order from automake - #sp_LIB - #nrtype_LIB - - #inkscape_LIB - #sp_LIB # annoying, we need both! - nrtype_LIB # annoying, we need both! +set(INKSCAPE_TARGET_LIBS + # order from automake + #sp_LIB + #nrtype_LIB - croco_LIB - avoid_LIB - gdl_LIB - cola_LIB - vpsc_LIB - livarot_LIB - uemf_LIB - 2geom_LIB - depixelize_LIB - util_LIB - gc_LIB + #inkscape_LIB + #sp_LIB # annoying, we need both! + nrtype_LIB # annoying, we need both! - ${INKSCAPE_LIBS} + croco_LIB + avoid_LIB + gdl_LIB + cola_LIB + vpsc_LIB + livarot_LIB + uemf_LIB + 2geom_LIB + depixelize_LIB + util_LIB + gc_LIB + ${INKSCAPE_LIBS} ) -# TODO -# make executable for INKVIEW -#add_executable(inkview inkview.cpp) -# ... +target_link_libraries(inkscape ${INKSCAPE_TARGET_LIBS}) +target_link_libraries(inkview ${INKSCAPE_TARGET_LIBS}) -- cgit v1.2.3 From 28df07c0cb1cee7ea32f9723add50f57fd30dd81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Luis=20Boya=20Garc=C3=ADa?= Date: Thu, 13 Aug 2015 15:17:22 +0200 Subject: Do not add .def files to the build list (bzr r14293.1.2) --- src/svg/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/svg/CMakeLists.txt b/src/svg/CMakeLists.txt index f9d0bc52d..ff4bb63ab 100644 --- a/src/svg/CMakeLists.txt +++ b/src/svg/CMakeLists.txt @@ -2,7 +2,7 @@ set(svg_SRC css-ostringstream.cpp path-string.cpp - sp-svg.def + #sp-svg.def stringstream.cpp strip-trailing-zeros.cpp svg-affine.cpp -- cgit v1.2.3 From 9616befcd379cc7173356998ff4c7b055b21e361 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 13 Aug 2015 17:48:12 +0200 Subject: 2Geom: update to r2422. Fixes LP #1482806: crash on Pattern along Path with horizontal segments. This was caused by empty SBasis objects. After the changes in 2Geom, empty SBasis objects should no longer be created. Fixed bugs: - https://launchpad.net/bugs/1482806 (bzr r14299) --- src/2geom/d2-sbasis.cpp | 20 ++++------- src/2geom/numeric/fitting-model.h | 1 - src/2geom/sbasis-geometric.cpp | 2 +- src/2geom/sbasis-roots.cpp | 6 ++-- src/2geom/sbasis-to-bezier.cpp | 4 +-- src/2geom/sbasis.h | 73 +++++++++++++++++++++------------------ 6 files changed, 51 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/2geom/d2-sbasis.cpp b/src/2geom/d2-sbasis.cpp index ebec16fdd..4f00ff6a5 100644 --- a/src/2geom/d2-sbasis.cpp +++ b/src/2geom/d2-sbasis.cpp @@ -147,12 +147,12 @@ Piecewise > force_continuity(Piecewise > const &f, double SBasis &prev_sb=result.segs[prev][dim]; SBasis &cur_sb =result.segs[cur][dim]; Coord const c=pt0[dim]; - if (prev_sb.empty()) { + if (prev_sb.isZero(0)) { prev_sb = SBasis(Linear(0.0, c)); } else { prev_sb[0][1] = c; } - if (cur_sb.empty()) { + if (cur_sb.isZero(0)) { cur_sb = SBasis(Linear(c, 0.0)); } else { cur_sb[0][0] = c; @@ -198,30 +198,22 @@ Point unitTangentAt(D2 const & a, Coord t, unsigned n) return Point (0,0); } -static void set_first_point(Piecewise > &f, Point a){ +static void set_first_point(Piecewise > &f, Point const &a){ if ( f.empty() ){ f.concat(Piecewise >(D2(SBasis(Linear(a[X])), SBasis(Linear(a[Y]))))); return; } for (unsigned dim=0; dim<2; dim++){ - if (f.segs.front()[dim].size() == 0){ - f.segs.front()[dim] = SBasis(Linear(a[dim],0)); - }else{ - f.segs.front()[dim][0][0] = a[dim]; - } + f.segs.front()[dim][0][0] = a[dim]; } } -static void set_last_point(Piecewise > &f, Point a){ +static void set_last_point(Piecewise > &f, Point const &a){ if ( f.empty() ){ f.concat(Piecewise >(D2(SBasis(Linear(a[X])), SBasis(Linear(a[Y]))))); return; } for (unsigned dim=0; dim<2; dim++){ - if (f.segs.back()[dim].size() == 0){ - f.segs.back()[dim] = SBasis(Linear(0,a[dim])); - }else{ - f.segs.back()[dim][0][1] = a[dim]; - } + f.segs.back()[dim][0][1] = a[dim]; } } diff --git a/src/2geom/numeric/fitting-model.h b/src/2geom/numeric/fitting-model.h index fb96d1d2a..b2ca92ad8 100644 --- a/src/2geom/numeric/fitting-model.h +++ b/src/2geom/numeric/fitting-model.h @@ -372,7 +372,6 @@ class LFMSBasis void instance(SBasis & sb, ConstVectorView const& raw_data) const { - sb.clear(); sb.resize(m_order+1); for (unsigned int i = 0, k = 0; i < raw_data.size(); i+=2, ++k) { diff --git a/src/2geom/sbasis-geometric.cpp b/src/2geom/sbasis-geometric.cpp index 4c474f7f0..8aaa15144 100644 --- a/src/2geom/sbasis-geometric.cpp +++ b/src/2geom/sbasis-geometric.cpp @@ -228,7 +228,7 @@ Geom::unitVector(D2 const &V_in, double tol, unsigned order){ // -This done, unitVector will have jumps at zeros: fill the gaps with arcs of circles. D2 V = RescaleForNonVanishingEnds(V_in); - if (V[0].empty() && V[1].empty()) + if (V[0].isZero(0) && V[1].isZero(0)) return Piecewise >(D2(Linear(1),SBasis())); SBasis x = V[0], y = V[1]; SBasis r_eqn1, r_eqn2; diff --git a/src/2geom/sbasis-roots.cpp b/src/2geom/sbasis-roots.cpp index 57bef4c0f..e3e5e4441 100644 --- a/src/2geom/sbasis-roots.cpp +++ b/src/2geom/sbasis-roots.cpp @@ -222,7 +222,7 @@ static void multi_roots_internal(SBasis const &f, double b, double fb){ - if (f.size()==0){ + if (f.isZero(0)){ int idx; idx=upper_level(levels,0,vtol); if (idx<(int)levels.size()&&fabs(levels.at(idx))<=vtol){ @@ -414,7 +414,7 @@ static void level_sets_internal(SBasis const &f, double fb, double tol=1e-5){ - if (f.size()==0){ + if (f.isZero(0)){ unsigned idx; idx=upper_level( levels, 0. ); if (idx roots1(SBasis const & s, Interval const ivl) { std::vector roots(SBasis const & s) { switch(s.size()) { case 0: + assert(false); return std::vector(); case 1: return roots1(s); @@ -628,6 +629,7 @@ std::vector roots(SBasis const & s) { std::vector roots(SBasis const & s, Interval const ivl) { switch(s.size()) { case 0: + assert(false); return std::vector(); case 1: return roots1(s, ivl); diff --git a/src/2geom/sbasis-to-bezier.cpp b/src/2geom/sbasis-to-bezier.cpp index 09fbb03ef..d9a90aace 100644 --- a/src/2geom/sbasis-to-bezier.cpp +++ b/src/2geom/sbasis-to-bezier.cpp @@ -100,9 +100,7 @@ int sgn(unsigned int j, unsigned int k) */ void sbasis_to_bezier (Bezier & bz, SBasis const& sb, size_t sz) { - if (sb.size() == 0) { - THROW_RANGEERROR("size of sb is too small"); - } + assert(sb.size() > 0); size_t q, n; bool even; diff --git a/src/2geom/sbasis.h b/src/2geom/sbasis.h index 787e8b722..6923017be 100644 --- a/src/2geom/sbasis.h +++ b/src/2geom/sbasis.h @@ -83,49 +83,52 @@ public: const_iterator end() const { return d.end();} iterator begin() { return d.begin();} iterator end() { return d.end();} - bool empty() const {return d.empty();} + bool empty() const { return d.size() == 1 && d[0][0] == 0 && d[0][1] == 0; } Linear &back() {return d.back();} Linear const &back() const {return d.back();} - void pop_back() { d.pop_back();} - void resize(unsigned n) { d.resize(n);} - void resize(unsigned n, Linear const& l) { d.resize(n, l);} + void pop_back() { + if (d.size() > 1) { + d.pop_back(); + } else { + d[0][0] = 0; + d[0][1] = 0; + } + } + void resize(unsigned n) { d.resize(std::max(n, 1));} + void resize(unsigned n, Linear const& l) { d.resize(std::max(n, 1), l);} void reserve(unsigned n) { d.reserve(n);} - void clear() {d.clear();} + void clear() { + d.resize(1); + d[0][0] = 0; + d[0][1] = 0; + } void insert(iterator before, const_iterator src_begin, const_iterator src_end) { d.insert(before, src_begin, src_end);} Linear& at(unsigned i) { return d.at(i);} //void insert(Linear* before, int& n, Linear const &l) { d.insert(std::vector::iterator(before), n, l);} bool operator==(SBasis const&B) const { return d == B.d;} bool operator!=(SBasis const&B) const { return d != B.d;} - operator std::vector() { return d;} - - SBasis() {} + SBasis() + : d(1, Linear(0, 0)) + {} explicit SBasis(double a) - : d(1) - { - d[0][0] = a; - d[0][1] = a; - } + : d(1, Linear(a, a)) + {} explicit SBasis(double a, double b) - : d(1) - { - d[0][0] = a; - d[0][1] = b; - } - SBasis(SBasis const & a) : - d(a.d) + : d(1, Linear(a, b)) {} - SBasis(std::vector const & ls) : - d(ls) + SBasis(SBasis const &a) + : d(a.d) + {} + SBasis(std::vector const &ls) + : d(ls) + {} + SBasis(Linear const &bo) + : d(1, bo) + {} + SBasis(Linear* bo) + : d(1, bo ? *bo : Linear(0, 0)) {} - SBasis(Linear const & bo) { - push_back(bo); - } - SBasis(Linear* bo) { - if (bo) { - push_back(*bo); - } - } explicit SBasis(size_t n, Linear const&l) : d(n, l) {} SBasis(Coord c0, Coord c1, Coord c2, Coord c3) @@ -179,6 +182,7 @@ public: template SBasis(Iter first, Iter last) { assert(std::distance(first, last) % 2 == 0); + assert(std::distance(first, last) >= 2); for (; first != last; ++first) { --last; push_back(Linear(*first, *last)); @@ -188,14 +192,14 @@ public: //IMPL: FragmentConcept typedef double output_type; inline bool isZero(double eps=EPSILON) const { - if(empty()) return true; + assert(size() > 0); for(unsigned i = 0; i < size(); i++) { if(!(*this)[i].isZero(eps)) return false; } return true; } inline bool isConstant(double eps=EPSILON) const { - if (empty()) return true; + assert(size() > 0); if(!(*this)[0].isConstant(eps)) return false; for (unsigned i = 1; i < size(); i++) { if(!(*this)[i].isZero(eps)) return false; @@ -212,6 +216,7 @@ public: int degreesOfFreedom() const { return size()*2;} double valueAt(double t) const { + assert(size() > 0); double s = t*(1-t); double p0 = 0, p1 = 0; for(unsigned k = size(); k > 0; k--) { @@ -239,11 +244,11 @@ public: //MUTATOR PRISON //remove extra zeros void normalize() { - while(!empty() && 0 == back()[0] && 0 == back()[1]) + while(size() > 1 && back().isZero(0)) pop_back(); } - void truncate(unsigned k) { if(k < size()) resize(k); } + void truncate(unsigned k) { if(k < size()) resize(std::max(k, 1)); } private: void derive(); // in place version }; -- cgit v1.2.3 From 0932ef5feb3707d94b527890bab29ed67d20b384 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Aug 2015 01:23:05 +0200 Subject: Refactor of BSPline code attemping to fix the duplicate end node bug, not sure if fixed jet (bzr r14300) --- src/ui/tool/node.cpp | 97 ++++++++++++++++------------------------ src/ui/tool/path-manipulator.cpp | 19 ++++---- src/ui/tool/path-manipulator.h | 4 +- src/ui/tools/pen-tool.cpp | 5 ++- 4 files changed, 51 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index eaec4477a..08ca13038 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -61,8 +61,8 @@ namespace Inkscape { namespace UI { /*const double handleCubicGap = 0.01;*/ -const double noPower = 0.0; -const double defaultStartPower = 0.3334; +const double NO_POWER = 0.0; +const double DEFAULT_START_POWER = 0.3334; /*const double defaultEndPower = 0.6667;*/ ControlPoint::ColorSet Node::node_colors = { @@ -142,6 +142,7 @@ void Handle::move(Geom::Point const &new_pos) Node *node_away = _parent->nodeAwayFrom(this); // node in the opposite direction Handle *towards = node_towards ? node_towards->handleAwayFrom(_parent) : NULL; Handle *towards_second = node_towards ? node_towards->handleToward(_parent) : NULL; + double bspline_weight = 0.0; if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. @@ -176,8 +177,9 @@ void Handle::move(Geom::Point const &new_pos) //move the handler and its oposite the same proportion if(_pm()._isBSpline()){ - setPosition(_pm()._bsplineHandleReposition(this, this)); - this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), this)); + setPosition(_pm()._bsplineHandleReposition(this, false)); + bspline_weight = _pm()._bsplineHandlePosition(this, false); + this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), bspline_weight)); } return; } @@ -193,8 +195,9 @@ void Handle::move(Geom::Point const &new_pos) //move the handler and its oposite the same proportion if(_pm()._isBSpline()){ - setPosition(_pm()._bsplineHandleReposition(this, this)); - this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), this)); + setPosition(_pm()._bsplineHandleReposition(this, false)); + bspline_weight = _pm()._bsplineHandlePosition(this, false); + this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), bspline_weight)); } return; @@ -219,8 +222,9 @@ void Handle::move(Geom::Point const &new_pos) // moves the handler and its oposite the same proportion if(_pm()._isBSpline()){ - setPosition(_pm()._bsplineHandleReposition(this, this)); - this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), this)); + setPosition(_pm()._bsplineHandleReposition(this, false)); + bspline_weight = _pm()._bsplineHandlePosition(this, false); + this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), bspline_weight)); } } @@ -299,7 +303,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven default: break; } break; - // new double click event to set the handlers of a node to the default proportion, defaultStartPower% + // new double click event to set the handlers of a node to the default proportion, DEFAULT_START_POWER% case GDK_2BUTTON_PRESS: handle_2button_press(); break; @@ -310,11 +314,11 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven return ControlPoint::_eventHandler(event_context, event); } -//this function moves the handler and its oposite to the default proportion of defaultStartPower +//this function moves the handler and its oposite to the default proportion of DEFAULT_START_POWER void Handle::handle_2button_press(){ if(_pm()._isBSpline()){ - setPosition(_pm()._bsplineHandleReposition(this, defaultStartPower)); - this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), defaultStartPower)); + setPosition(_pm()._bsplineHandleReposition(this, DEFAULT_START_POWER)); + this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), DEFAULT_START_POWER)); _pm().update(); } } @@ -375,7 +379,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) if(_pm()._isBSpline()){ setPosition(new_pos); int steps = _pm()._bsplineGetSteps(); - new_pos=_pm()._bsplineHandleReposition(this,ceilf(_pm()._bsplineHandlePosition(this, this)*steps)/steps); + new_pos=_pm()._bsplineHandleReposition(this,ceilf(_pm()._bsplineHandlePosition(this, false)*steps)/steps); } } @@ -549,7 +553,7 @@ Glib::ustring Handle::_getTip(unsigned state) const "Auto node handle: drag to convert to smooth node (%s)"), more); }else{ return format_tip(C_("Path handle tip", - "BSpline node handle: Shift to drag, double click to reset (%s). %g power"),more,_pm()._bsplineHandlePosition(h, NULL)); + "BSpline node handle: Shift to drag, double click to reset (%s). %g power"),more,_pm()._bsplineHandlePosition(h)); } } } @@ -627,22 +631,18 @@ void Node::move(Geom::Point const &new_pos) Geom::Point delta = new_pos - position(); // save the previous nodes strength to apply it again once the node is moved - double nodeWeight = noPower; - double nextNodeWeight = noPower; - double prevNodeWeight = noPower; + double nodeWeight = NO_POWER; + double nextNodeWeight = NO_POWER; + double prevNodeWeight = NO_POWER; Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); - nodeWeight = fmax(_pm()._bsplineHandlePosition(n->front()),_pm()._bsplineHandlePosition(n->back())); + nodeWeight = fmax(_pm()._bsplineHandlePosition(n->front(), false),_pm()._bsplineHandlePosition(n->back(), false)); if(prevNode){ - if(prevNode->isEndNode()){ - prevNodeWeight = _pm()._bsplineHandlePosition(prevNode->front(), prevNode->front()); - } + prevNodeWeight = _pm()._bsplineHandlePosition(prevNode->front()); } if(nextNode){ - if(nextNode->isEndNode()){ - nextNodeWeight = _pm()._bsplineHandlePosition(nextNode->back(), nextNode->back()); - } + nextNodeWeight = _pm()._bsplineHandlePosition(nextNode->back()); } setPosition(new_pos); @@ -659,18 +659,10 @@ void Node::move(Geom::Point const &new_pos) _front.setPosition(_pm()._bsplineHandleReposition(this->front(),nodeWeight)); _back.setPosition(_pm()._bsplineHandleReposition(this->back(),nodeWeight)); if(prevNode){ - if(prevNode->isEndNode()){ - prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(), prevNodeWeight)); - }else{ - prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(), prevNode->back())); - } + prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(), prevNodeWeight)); } if(nextNode){ - if(nextNode->isEndNode()){ - nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(), nextNodeWeight)); - }else{ - nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(), nextNode->front())); - } + nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(), nextNodeWeight)); } } } @@ -681,22 +673,18 @@ void Node::transform(Geom::Affine const &m) Geom::Point old_pos = position(); // save the previous nodes strength to apply it again once the node is moved - double nodeWeight = noPower; - double nextNodeWeight = noPower; - double prevNodeWeight = noPower; + double nodeWeight = NO_POWER; + double nextNodeWeight = NO_POWER; + double prevNodeWeight = NO_POWER; Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); nodeWeight = _pm()._bsplineHandlePosition(n->front()); if(prevNode){ - if(prevNode->isEndNode()){ - prevNodeWeight = _pm()._bsplineHandlePosition(prevNode->front(), prevNode->front()); - } + prevNodeWeight = _pm()._bsplineHandlePosition(prevNode->front()); } if(nextNode){ - if(nextNode->isEndNode()){ - nextNodeWeight = _pm()._bsplineHandlePosition(nextNode->back(), nextNode->back()); - } + nextNodeWeight = _pm()._bsplineHandlePosition(nextNode->back()); } setPosition(position() * m); @@ -712,18 +700,10 @@ void Node::transform(Geom::Affine const &m) _front.setPosition(_pm()._bsplineHandleReposition(this->front(), nodeWeight)); _back.setPosition(_pm()._bsplineHandleReposition(this->back(), nodeWeight)); if(prevNode){ - if(prevNode->isEndNode()){ - prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(), prevNodeWeight)); - }else{ - prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(), prevNode->back())); - } + prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(), prevNodeWeight)); } if(nextNode){ - if(nextNode->isEndNode()){ - nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(), nextNodeWeight)); - }else{ - nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(), nextNode->front())); - } + nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(), nextNodeWeight)); } } } @@ -913,12 +893,12 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - /* in node type changes, about bspline traces, we can mantain them with noPower power in border mode, + /* in node type changes, about bspline traces, we can mantain them with NO_POWER power in border mode, or we give them the default power in curve mode */ if(_pm()._isBSpline()){ - double weight = noPower; - if(_pm()._bsplineHandlePosition(this->front()) != noPower ){ - weight = defaultStartPower; + double weight = NO_POWER; + if(_pm()._bsplineHandlePosition(this->front()) != NO_POWER ){ + weight = DEFAULT_START_POWER; } _front.setPosition(_pm()._bsplineHandleReposition(this->front(), weight)); _back.setPosition(_pm()._bsplineHandleReposition(this->back(), weight)); @@ -1435,7 +1415,6 @@ Glib::ustring Node::_getTip(unsigned state) const { bool isBSpline = _pm()._isBSpline(); Handle *h = const_cast(&_front); - Handle *h2 = const_cast(&_back); if (state_held_shift(state)) { bool can_drag_out = (_next() && _front.isDegenerate()) || (_prev() && _back.isDegenerate()); if (can_drag_out) { @@ -1464,7 +1443,7 @@ Glib::ustring Node::_getTip(unsigned state) const // No modifiers: assemble tip from node type char const *nodetype = node_type_to_localized_string(_type); - double power = _pm()._bsplineHandlePosition(h,h2); + double power = _pm()._bsplineHandlePosition(h); if (_selection.transformHandlesEnabled() && selected()) { if (_selection.size() == 1 && !isBSpline) { return format_tip(C_("Path node tip", diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 848b10373..7c9fb5841 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -58,7 +58,7 @@ enum PathChange { } // anonymous namespace const double HANDLE_CUBIC_GAP = 0.01; const double NO_POWER = 0.0; -const double defaultStartPower = 0.3334; +const double DEFAULT_START_POWER = 0.3334; /** @@ -1033,7 +1033,7 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d line_inside_nodes->moveto(n->position()); line_inside_nodes->lineto(second->position()); sbasis_inside_nodes = line_inside_nodes->first_segment()->toSBasis(); - Geom::Point next = sbasis_inside_nodes.valueAt(defaultStartPower); + Geom::Point next = sbasis_inside_nodes.valueAt(DEFAULT_START_POWER); next = Geom::Point(next[Geom::X] + HANDLE_CUBIC_GAP,next[Geom::Y] + HANDLE_CUBIC_GAP); line_inside_nodes->reset(); n->front()->setPosition(next); @@ -1044,7 +1044,7 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d line_inside_nodes->moveto(n->position()); line_inside_nodes->lineto(first->position()); sbasis_inside_nodes = line_inside_nodes->first_segment()->toSBasis(); - Geom::Point previous = sbasis_inside_nodes.valueAt(defaultStartPower); + Geom::Point previous = sbasis_inside_nodes.valueAt(DEFAULT_START_POWER); previous = Geom::Point(previous[Geom::X] + HANDLE_CUBIC_GAP,previous[Geom::Y] + HANDLE_CUBIC_GAP); n->back()->setPosition(previous); }else{ @@ -1277,13 +1277,10 @@ bool PathManipulator::_isBSpline() const { } // returns the corresponding strength to the position of the handlers -double PathManipulator::_bsplineHandlePosition(Handle *h, Handle *h2) +double PathManipulator::_bsplineHandlePosition(Handle *h, bool check_other) { using Geom::X; using Geom::Y; - if(h2){ - h = h2; - } double pos = NO_POWER; Node *n = h->parent(); Node * next_node = NULL; @@ -1296,16 +1293,16 @@ double PathManipulator::_bsplineHandlePosition(Handle *h, Handle *h2) pos = Geom::nearest_time(Geom::Point(h->position()[X] - HANDLE_CUBIC_GAP, h->position()[Y] - HANDLE_CUBIC_GAP), *line_inside_nodes->first_segment()); } } - if (pos == NO_POWER && !h2){ - return _bsplineHandlePosition(h, h->other()); + if (pos == NO_POWER && check_other){ + return _bsplineHandlePosition(h->other(), false); } return pos; } // give the location for the handler in the corresponding position -Geom::Point PathManipulator::_bsplineHandleReposition(Handle *h, Handle *h2) +Geom::Point PathManipulator::_bsplineHandleReposition(Handle *h, bool check_other) { - double pos = this->_bsplineHandlePosition(h, h2); + double pos = this->_bsplineHandlePosition(h, check_other); return _bsplineHandleReposition(h,pos); } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 4c6f74ba4..283cb610a 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -111,8 +111,8 @@ private: void _recalculateIsBSpline(); bool _isBSpline() const; - double _bsplineHandlePosition(Handle *h, Handle *h2 = NULL); - Geom::Point _bsplineHandleReposition(Handle *h, Handle *h2 = NULL); + double _bsplineHandlePosition(Handle *h, bool check_other = true); + Geom::Point _bsplineHandleReposition(Handle *h, bool check_other = true); Geom::Point _bsplineHandleReposition(Handle *h, double pos); void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 6a3928f27..69068f2a7 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -382,11 +382,12 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { if( anchor && anchor == this->sa && this->green_curve->is_empty()){ //remove the following line to avoid having one node on top of another _finishSegment(event_dt, bevent.state); - _finish( false); + _finish(true); return true; } return false; } + bool ret = false; if (bevent.button == 1 && !this->space_panning // make sure this is not the last click for a waiting LPE (otherwise we want to finish the path) @@ -860,7 +861,7 @@ bool PenTool::_handleButtonRelease(GdkEventButton const &revent) { bool PenTool::_handle2ButtonPress(GdkEventButton const &bevent) { bool ret = false; // only end on LMB double click. Otherwise horizontal scrolling causes ending of the path - if (this->npoints != 0 && bevent.button == 1) { + if (this->npoints != 0 && bevent.button == 1 && this->state != PenTool::CLOSE) { this->_finish(false); ret = true; } -- cgit v1.2.3 From 439df6b61c37528b2ca6210f77a4bb50aa692906 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Aug 2015 10:20:45 +0200 Subject: A bit more refactor of BSPline tool. Still the bug duplicating end node :( (bzr r14301) --- src/live_effects/lpe-bspline.cpp | 2 +- src/ui/tool/node.cpp | 2 -- src/ui/tool/path-manipulator.cpp | 8 +++++--- src/ui/tools/pen-tool.cpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index d2da33aa9..019584943 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -16,7 +16,7 @@ namespace Inkscape { namespace LivePathEffect { -const double HANDLE_CUBIC_GAP = 0.01; +const double HANDLE_CUBIC_GAP = 0.001; const double NO_POWER = 0.0; const double DEFAULT_START_POWER = 0.3334; const double DEFAULT_END_POWER = 0.6667; diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 08ca13038..55d801c46 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -60,10 +60,8 @@ Inkscape::ControlType nodeTypeToCtrlType(Inkscape::UI::NodeType type) namespace Inkscape { namespace UI { -/*const double handleCubicGap = 0.01;*/ const double NO_POWER = 0.0; const double DEFAULT_START_POWER = 0.3334; -/*const double defaultEndPower = 0.6667;*/ ControlPoint::ColorSet Node::node_colors = { {0xbfbfbf00, 0x000000ff}, // normal fill, stroke diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 7c9fb5841..7b7bc98ee 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -56,7 +56,7 @@ enum PathChange { }; } // anonymous namespace -const double HANDLE_CUBIC_GAP = 0.01; +const double HANDLE_CUBIC_GAP = 0.001; const double NO_POWER = 0.0; const double DEFAULT_START_POWER = 0.3334; @@ -695,10 +695,12 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite // if we are removing, we readjust the handlers if(_isBSpline()){ if(start.prev()){ - start.prev()->front()->setPosition(_bsplineHandleReposition(start.prev()->front(),start.prev()->back())); + double bspline_weight = _bsplineHandlePosition(start.prev()->back(), false); + start.prev()->front()->setPosition(_bsplineHandleReposition(start.prev()->front(), bspline_weight)); } if(end){ - end->back()->setPosition(_bsplineHandleReposition(end->back(),end->front())); + double bspline_weight = _bsplineHandlePosition(end->front(), false); + end->back()->setPosition(_bsplineHandleReposition(end->back(),bspline_weight)); } } diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 69068f2a7..2ed366a7d 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -84,7 +84,7 @@ namespace Tools { static Geom::Point pen_drag_origin_w(0, 0); static bool pen_within_tolerance = false; static int pen_last_paraxial_dir = 0; // last used direction in horizontal/vertical mode; 0 = horizontal, 1 = vertical -const double HANDLE_CUBIC_GAP = 0.01; +const double HANDLE_CUBIC_GAP = 0.001; const std::string& PenTool::getPrefsPath() { return PenTool::prefsPath; -- cgit v1.2.3 From 2f08c2af203444acbea58eb5f521013780626ee5 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 16 Aug 2015 21:11:47 +0200 Subject: fix for ungrouping dynamic offset displacement bug Fixed bugs: - https://launchpad.net/bugs/844909 (bzr r14305) --- src/sp-item-group.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 72cd5d7fa..5d96899b1 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -465,7 +465,7 @@ sp_item_group_ungroup (SPGroup *group, std::vector &children, bool do_d Inkscape::XML::Node *nrepr = child->getRepr()->duplicate(prepr->document()); // Merging transform - Geom::Affine ctrans; + Geom::Affine ctrans = citem->transform * g; // We should not apply the group's transformation to both a linked offset AND to its source if (dynamic_cast(citem)) { // Do we have an offset at hand (whether it's dynamic or linked)? SPItem *source = sp_offset_get_source(dynamic_cast(citem)); @@ -476,13 +476,9 @@ sp_item_group_ungroup (SPGroup *group, std::vector &children, bool do_d source = sp_offset_get_source(dynamic_cast(source)); } if (source != NULL && // If true then we must be dealing with a linked offset ... - group->isAncestorOf(source) == false) { // ... of which the source is not in the same group - ctrans = citem->transform * g; // then we should apply the transformation of the group to the offset - } else { - ctrans = citem->transform; + group->isAncestorOf(source) ) { // ... of which the source is in the same group + ctrans = citem->transform; // then we should apply the transformation of the group to the offset } - } else { - ctrans = citem->transform * g; } // FIXME: constructing a transform that would fully preserve the appearance of a -- cgit v1.2.3 From 2b6e2bc4e7541bcda149f8ed68c2e07336fb573e Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Mon, 17 Aug 2015 01:38:25 +0200 Subject: Fixes doubled transparency computation on bitmaps for some reason Fixed bugs: - https://launchpad.net/bugs/1434122 (bzr r14306) --- src/display/drawing-image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp index 1594614ac..2a943d16c 100644 --- a/src/display/drawing-image.cpp +++ b/src/display/drawing-image.cpp @@ -132,7 +132,7 @@ unsigned DrawingImage::_renderItem(DrawingContext &dc, Geom::IntRect const &/*ar } } - dc.paint(_opacity); + dc.paint(1); } else { // outline; draw a rect instead -- cgit v1.2.3 From fbd80d77d08c63a1e7ad0c3d4701fc1493d0b0bc Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Mon, 17 Aug 2015 02:43:57 +0200 Subject: import images with dpi from file : xscale and yscale were not rounded but floored, which resulted in 0 values for big images, and numerical mayhem ensued ("inf" and "nan"). Fixed bugs: - https://launchpad.net/bugs/1479193 (bzr r14307) --- src/extension/internal/gdkpixbuf-input.cpp | 4 ++-- src/xml/repr-util.cpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index f5fab1fa2..f99c9050d 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -86,8 +86,8 @@ GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri) ir = new ImageResolution(uri); } if (ir && ir->ok()) { - xscale = 960.0 / floor(10.*ir->x() + .5); // round-off to 0.1 dpi - yscale = 960.0 / floor(10.*ir->y() + .5); + xscale = 960.0 / round(10.*ir->x() + .5); // round-off to 0.1 dpi + yscale = 960.0 / round(10.*ir->y() + .5); } else { xscale = 96.0 / defaultxdpi; yscale = 96.0 / defaultxdpi; diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp index f7a437163..ce93bccab 100644 --- a/src/xml/repr-util.cpp +++ b/src/xml/repr-util.cpp @@ -528,6 +528,7 @@ unsigned int sp_repr_set_svg_double(Inkscape::XML::Node *repr, gchar const *key, { g_return_val_if_fail(repr != NULL, FALSE); g_return_val_if_fail(key != NULL, FALSE); + g_return_val_if_fail(val==val, FALSE);//tests for nan Inkscape::SVGOStringStream os; os << val; -- cgit v1.2.3 From 9580930d2c494fa5149399fb5078d8e92e8b8083 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Mon, 17 Aug 2015 03:16:35 +0200 Subject: added a check that is present in surrounding code, but not on this particular line, which is most infortunate, since it led to a crash. Fixed bugs: - https://launchpad.net/bugs/1445204 (bzr r14308) --- src/libnrtype/Layout-TNG-OutIter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index 707897f50..137fe0a0f 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -507,7 +507,7 @@ void Layout::queryCursorShape(iterator const &it, Geom::Point &position, double position[Geom::Y] = span->line(this).baseline_y + span->baseline_shift; } // up to now *position is the baseline point, not the final point which will be the bottom of the descent - double vertical_scale = _glyphs.back().vertical_scale; + double vertical_scale = _glyphs.empty() ? 1.0 : _glyphs.back().vertical_scale; if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { height = vertical_scale * span->line_height.ascent + span->line_height.descent; -- cgit v1.2.3 From 209b7267fe77a04874519b6ac247651102fa1b47 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Wed, 19 Aug 2015 00:56:36 +0200 Subject: Allows for copying clones between inkscape instances. This patch puts the original of clones as children of _clipnode (). Then, on paste, it checks for the presence of an element with the right id (so that it does not breaks copypaste clones in the same doc), then pastes all, and deletes the original if needed (which automagically unlinks the clone if needed). [an alternate solution is to put the original in the defs (which might cause edition problems) and not unlink. Depending on whether people would be more interested in this behavior there could be a preference item to choose] Fixed bugs: - https://launchpad.net/bugs/167907 (bzr r14309) --- src/file.cpp | 25 +++++++++++++++++++++++-- src/ui/clipboard.cpp | 43 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 58 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/file.cpp b/src/file.cpp index 984bf7e08..ed9caacf1 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -1068,6 +1068,7 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) // copy definitions desktop->doc()->importDefs(clipdoc); + Inkscape::XML::Node* clipboard; // copy objects std::vector pasted_objects; for (Inkscape::XML::Node *obj = root->firstChild() ; obj ; obj = obj->next()) { @@ -1082,6 +1083,7 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) continue; } if (!strcmp(obj->name(), "inkscape:clipboard")) { + clipboard = obj; continue; } Inkscape::XML::Node *obj_copy = obj->duplicate(target_document->getReprDoc()); @@ -1090,12 +1092,31 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) pasted_objects.push_back(obj_copy); } - // Change the selection to the freshly pasted objects + + /* take that stuff into account: + * if( use && selection->includes(use->get_original()) ){//we are copying something whose parent is also copied (!) + * transform = ((SPItem*)(use->get_original()->parent))->i2doc_affine().inverse() * transform; + * } + * + */ + std::vector pasted_objects_not; + for (Inkscape::XML::Node *obj = clipboard->firstChild() ; obj ; obj = obj->next()) { + if(target_document->getObjectById(obj->attribute("id"))) continue; + Inkscape::XML::Node *obj_copy = obj->duplicate(target_document->getReprDoc()); + target_parent->appendChild(obj_copy); + Inkscape::GC::release(obj_copy); + pasted_objects_not.push_back(obj_copy); + } Inkscape::Selection *selection = desktop->getSelection(); + selection->setReprList(pasted_objects_not); + Geom::Affine doc2parent = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false); + sp_selection_delete(desktop); + + // Change the selection to the freshly pasted objects selection->setReprList(pasted_objects); // Apply inverse of parent transform - Geom::Affine doc2parent = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false); // Update (among other things) all curves in paths, for bounds() to work diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index d6cf1f980..816daf2e5 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -154,6 +154,7 @@ private: Inkscape::XML::Node *_root; ///< Reference to the clipboard's root node Inkscape::XML::Node *_clipnode; ///< The node that holds extra information Inkscape::XML::Document *_doc; ///< Reference to the clipboard's Inkscape::XML::Document + std::set cloned_elements; // we need a way to copy plain text AND remember its style; // the standard _clipnode is only available in an SVG tree, hence this special storage @@ -239,7 +240,7 @@ void ClipboardManagerImpl::copy(SPDesktop *desktop) // Special case for when the color picker ("dropper") is active - copies color under cursor if (tools_isactive(desktop, TOOLS_DROPPER)) { //_setClipboardColor(sp_dropper_context_get_color(desktop->event_context)); - _setClipboardColor(SP_DROPPER_CONTEXT(desktop->event_context)->get_color()); + _setClipboardColor(SP_DROPPER_CONTEXT(desktop->event_context)->get_color()); _discardInternalClipboard(); return; } @@ -523,7 +524,7 @@ bool ClipboardManagerImpl::pasteSize(SPDesktop *desktop, bool separately, bool a // resize each object in the selection if (separately) { - std::vector itemlist=selection->itemList(); + std::vector itemlist=selection->itemList(); for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ SPItem *item = *i; if (item) { @@ -630,7 +631,7 @@ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) // at the first object to be or . // but that could then return the id of the object's // clip path or mask, not the original path! - + SPDocument *tempdoc = _retrieveClipboard(); // any target will do here if ( tempdoc == NULL ) { _userWarn(desktop, _("Nothing on the clipboard.")); @@ -662,7 +663,8 @@ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) { // copy the defs used by all items - std::vector itemlist=selection->itemList(); + std::vector itemlist=selection->itemList(); + cloned_elements.clear(); for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ SPItem *item = *i; if (item) { @@ -673,14 +675,33 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) } // copy the representation of the items - std::vector sorted_items(itemlist); + std::vector sorted_items; + for(std::vector::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); - for(std::vector::const_iterator i=sorted_items.begin();i!=sorted_items.end();i++){ - SPItem *item = *i; + //remove already copied elements from cloned_elements + std::vectortr; + for(std::set::iterator it = cloned_elements.begin();it!=cloned_elements.end();it++){ + if(std::find(sorted_items.begin(),sorted_items.end(),*it)!=sorted_items.end()) + tr.push_back(*it); + } + for(std::vector::iterator it = tr.begin();it!=tr.end();it++){ + cloned_elements.erase(*it); + } + + sorted_items.insert(sorted_items.end(),cloned_elements.begin(),cloned_elements.end()); + + for(std::vector::const_iterator i=sorted_items.begin();i!=sorted_items.end();i++){ + SPItem *item = dynamic_cast(*i); if (item) { Inkscape::XML::Node *obj = item->getRepr(); - Inkscape::XML::Node *obj_copy = _copyNode(obj, _doc, _root); + Inkscape::XML::Node *obj_copy; + if(cloned_elements.find(item)==cloned_elements.end()) + obj_copy = _copyNode(obj, _doc, _root); + else + obj_copy = _copyNode(obj, _doc, _clipnode); + // copy complete inherited style SPCSSAttr *css = sp_repr_css_attr_inherited(obj, "style"); @@ -737,6 +758,12 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) */ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) { + SPUse *use=dynamic_cast(item); + if(use){ + if(cloned_elements.insert(use->get_original()).second) + _copyUsedDefs(use->get_original()); + } + // copy fill and stroke styles (patterns and gradients) SPStyle *style = item->style; -- cgit v1.2.3 From e988d0857f6313c196437d8ed60c01d38217738a Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 20 Aug 2015 10:10:44 +0200 Subject: UI. Fix for Bug #1485831 (Preview of bitmap image in file chooser no longer displays its dimensions). Fixed bugs: - https://launchpad.net/bugs/1485831 (bzr r14310) --- src/ui/dialog/filedialogimpl-gtkmm.cpp | 68 ++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 17cf835cd..042637d22 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -199,37 +199,9 @@ void SVGPreview::showImage(Glib::ustring &theFileName) // files so we assume they are well formed. // std::cout << "SVGPreview::showImage: " << theFileName << std::endl; - std::ifstream input(theFileName.c_str()); - std::string width; std::string height; - if( !input ) { - std::cerr << "SVGPreview::showImage: Failed to open file: " << theFileName << std::endl; - } else { - - std::string token; - - Glib::MatchInfo match_info; - Glib::RefPtr regex1 = Glib::Regex::create("width=\"(.*)\""); - Glib::RefPtr regex2 = Glib::Regex::create("height=\"(.*)\""); - - while( !input.eof() && (height.empty() || width.empty()) ) { - - input >> token; - // std::cout << "|" << token << "|" << std::endl; - - if (regex1->match(token, match_info)) { - width = match_info.fetch(1).raw(); - } - - if (regex2->match(token, match_info)) { - height = match_info.fetch(1).raw(); - } - - } - } - /*##################################### # LET'S HAVE SOME FUN WITH SVG! # Instead of just loading an image, why @@ -265,6 +237,46 @@ void SVGPreview::showImage(Glib::ustring &theFileName) gint imgWidth = img->get_width(); gint imgHeight = img->get_height(); + + Glib::ustring svg = ".svg"; + if (hasSuffix(fileName, svg)) { + std::ifstream input(theFileName.c_str()); + if( !input ) { + std::cerr << "SVGPreview::showImage: Failed to open file: " << theFileName << std::endl; + } else { + + std::string token; + + Glib::MatchInfo match_info; + Glib::RefPtr regex1 = Glib::Regex::create("width=\"(.*)\""); + Glib::RefPtr regex2 = Glib::Regex::create("height=\"(.*)\""); + + while( !input.eof() && (height.empty() || width.empty()) ) { + + input >> token; + // std::cout << "|" << token << "|" << std::endl; + + if (regex1->match(token, match_info)) { + width = match_info.fetch(1).raw(); + } + + if (regex2->match(token, match_info)) { + height = match_info.fetch(1).raw(); + } + + } + } + } + + // TODO: replace int to string conversion with std::to_string when fully C++11 compliant + if (height.empty() || width.empty()) { + std::ostringstream s_width; + std::ostringstream s_height; + s_width << imgWidth; + s_height << imgHeight; + width = s_width.str(); + height = s_height.str(); + } // Find the minimum scale to fit the image inside the preview area double scaleFactorX = (0.9 * (double)previewWidth) / ((double)imgWidth); -- cgit v1.2.3 From c8b00b1e5db4cbb22e180b75efaa529cc7605c9a Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Thu, 20 Aug 2015 13:48:43 +0200 Subject: small fix for pasting svg that were not copied in inkscape Fixed bugs: - https://launchpad.net/bugs/1486927 (bzr r14311) --- src/file.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/file.cpp b/src/file.cpp index ed9caacf1..7ae7d238a 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -1068,7 +1068,7 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) // copy definitions desktop->doc()->importDefs(clipdoc); - Inkscape::XML::Node* clipboard; + Inkscape::XML::Node* clipboard = NULL; // copy objects std::vector pasted_objects; for (Inkscape::XML::Node *obj = root->firstChild() ; obj ; obj = obj->next()) { @@ -1100,6 +1100,7 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) * */ std::vector pasted_objects_not; + if(clipboard) for (Inkscape::XML::Node *obj = clipboard->firstChild() ; obj ; obj = obj->next()) { if(target_document->getObjectById(obj->attribute("id"))) continue; Inkscape::XML::Node *obj_copy = obj->duplicate(target_document->getReprDoc()); -- cgit v1.2.3 From 566d637e6b8d3544d8763a82c8caae2595455157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Corr=C3=AAa=20da=20Silva=20Sanches?= Date: Fri, 21 Aug 2015 17:25:37 -0300 Subject: indentation and whitespace fixes (bzr r14314) --- src/sp-lpe-item.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 902271430..c35ad8411 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -26,21 +26,21 @@ class SPCurve; class SPDesktop; namespace Inkscape{ -namespace Display { - class TemporaryItem; -} -namespace LivePathEffect{ - class LPEObjectReference; - class Effect; -} + namespace Display { + class TemporaryItem; + } + namespace LivePathEffect{ + class LPEObjectReference; + class Effect; + } } typedef std::list PathEffectList; class SPLPEItem : public SPItem { public: - SPLPEItem(); - virtual ~SPLPEItem(); + SPLPEItem(); + virtual ~SPLPEItem(); int path_effects_enabled; @@ -54,20 +54,20 @@ public: std::vector const &new_lpeobjs ); - virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); - virtual void release(); + virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); + virtual void release(); - virtual void set(unsigned int key, char const* value); + virtual void set(unsigned int key, char const* value); - virtual void update(SPCtx* ctx, unsigned int flags); - virtual void modified(unsigned int flags); + virtual void update(SPCtx* ctx, unsigned int flags); + virtual void modified(unsigned int flags); - virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); - virtual void remove_child(Inkscape::XML::Node* child); + virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); + virtual void remove_child(Inkscape::XML::Node* child); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); - virtual void update_patheffect(bool write); + virtual void update_patheffect(bool write); bool performPathEffect(SPCurve *curve); -- cgit v1.2.3 From 87dcc5957e93f5cf891bc2032c759b98df44f17f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 22 Aug 2015 19:07:52 +0200 Subject: Simplify a bit BSpline code (bzr r14316) --- src/live_effects/lpe-bspline.cpp | 83 +++++++++++----------------------------- 1 file changed, 22 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 019584943..0cae1dcb6 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -365,91 +365,52 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) point_at0 = in->first_segment()->initialPoint(); point_at3 = in->first_segment()->finalPoint(); sbasis_in = in->first_segment()->toSBasis(); - if (!only_selected) { - if (cubic) { - if (!ignore_cusp || !Geom::are_near((*cubic)[1], point_at0)) { + if (cubic) { + if (!ignore_cusp || !Geom::are_near((*cubic)[1], point_at0)) { + if (isNodePointSelected(point_at0) || !only_selected) { point_at1 = sbasis_in.valueAt(weight_ammount); if (weight_ammount != NO_POWER) { point_at1 = Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP); } } else { - point_at1 = in->first_segment()->initialPoint(); - } - if (!ignore_cusp || !Geom::are_near((*cubic)[2], point_at3)) { - point_at2 = sbasis_in.valueAt(1 - weight_ammount); - if (weight_ammount != NO_POWER) { - point_at2 = - Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP); - } - } else { - point_at2 = in->first_segment()->finalPoint(); + point_at1 = (*cubic)[1]; } } else { - if (!ignore_cusp && weight_ammount != NO_POWER) { - point_at1 = sbasis_in.valueAt(weight_ammount); - if (weight_ammount != NO_POWER) { - point_at1 = - Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP); - } + point_at1 = in->first_segment()->initialPoint(); + } + if (!ignore_cusp || !Geom::are_near((*cubic)[2], point_at3)) { + if (isNodePointSelected(point_at3) || !only_selected) { point_at2 = sbasis_in.valueAt(1 - weight_ammount); if (weight_ammount != NO_POWER) { point_at2 = Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP); } } else { - point_at1 = in->first_segment()->initialPoint(); - point_at2 = in->first_segment()->finalPoint(); + point_at2 = (*cubic)[2]; } + } else { + point_at2 = in->first_segment()->finalPoint(); } } else { - if (cubic) { - if (!ignore_cusp || !Geom::are_near((*cubic)[1], point_at0)) { - if (isNodePointSelected(point_at0)) { - point_at1 = sbasis_in.valueAt(weight_ammount); - if (weight_ammount != NO_POWER) { - point_at1 = - Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP); - } - } else { - point_at1 = (*cubic)[1]; - } + if (!ignore_cusp && weight_ammount != NO_POWER) { + if (isNodePointSelected(point_at0) || !only_selected) { + point_at1 = sbasis_in.valueAt(weight_ammount); + point_at1 = + Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP); } else { point_at1 = in->first_segment()->initialPoint(); } - if (!ignore_cusp || !Geom::are_near((*cubic)[2], point_at3)) { - if (isNodePointSelected(point_at3)) { - point_at2 = sbasis_in.valueAt(1 - weight_ammount); - if (weight_ammount != NO_POWER) { - point_at2 = - Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP); - } - } else { - point_at2 = (*cubic)[2]; - } + if (isNodePointSelected(point_at3) || !only_selected) { + point_at2 = sbasis_in.valueAt(weight_ammount); + point_at2 = + Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP); } else { point_at2 = in->first_segment()->finalPoint(); } } else { - if (!ignore_cusp && weight_ammount != NO_POWER) { - if (isNodePointSelected(point_at0)) { - point_at1 = sbasis_in.valueAt(weight_ammount); - point_at1 = - Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP); - } else { - point_at1 = in->first_segment()->initialPoint(); - } - if (isNodePointSelected(point_at3)) { - point_at2 = sbasis_in.valueAt(weight_ammount); - point_at2 = - Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP); - } else { - point_at2 = in->first_segment()->finalPoint(); - } - } else { - point_at1 = in->first_segment()->initialPoint(); - point_at2 = in->first_segment()->finalPoint(); - } + point_at1 = in->first_segment()->initialPoint(); + point_at2 = in->first_segment()->finalPoint(); } } in->reset(); -- cgit v1.2.3 From cc324ba00091f187d237a38241c6687a18a75d6b Mon Sep 17 00:00:00 2001 From: su_v Date: Sun, 23 Aug 2015 09:03:34 +0200 Subject: Remove remnants of r4454 (ige-mac-menu), no longer needed after r10950. (bzr r14317) --- src/Makefile.am | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 7a37f13e8..04e33c471 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,7 +46,6 @@ all_libs = \ $(FREETYPE_LIBS) \ $(kdeldadd) \ $(win32ldflags) \ - $(CARBON_LDFLAGS) \ $(LIBWPG_LIBS) \ $(LIBVISIO_LIBS) \ $(LIBCDR_LIBS) \ -- cgit v1.2.3 From 6f182411f0349e1ccc4df8fd0ca3a609331ab90b Mon Sep 17 00:00:00 2001 From: su_v Date: Sun, 23 Aug 2015 09:08:26 +0200 Subject: Add 'inkscape:_templateinfo' back to sp-factory.cpp (got lost in r13940). (bzr r14318) --- src/sp-factory.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/sp-factory.cpp b/src/sp-factory.cpp index 84329eaaf..20472d425 100644 --- a/src/sp-factory.cpp +++ b/src/sp-factory.cpp @@ -294,6 +294,8 @@ SPObject *SPFactory::createObject(std::string const& id) {} else if (id == "inkscape:clipboard") // SP node not necessary {} + else if (id == "inkscape:_templateinfo") // ? + {} else if (id.empty()) // comments {} else { -- cgit v1.2.3 From 3ceea01eb205a49ac27103b1d21a362dd46dc223 Mon Sep 17 00:00:00 2001 From: su_v Date: Sun, 23 Aug 2015 09:56:51 +0200 Subject: Revert custom gdl patch (focus indicator of docked dialogs) for Quartz backend (bug #1363998) Fixed bugs: - https://launchpad.net/bugs/1363998 (bzr r14319) --- src/libgdl/gdl-dock-item-grip.c | 3 +++ src/libgdl/gdl-dock-item.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/libgdl/gdl-dock-item-grip.c b/src/libgdl/gdl-dock-item-grip.c index d23eb7f98..9b3810c20 100644 --- a/src/libgdl/gdl-dock-item-grip.c +++ b/src/libgdl/gdl-dock-item-grip.c @@ -149,6 +149,8 @@ gdl_dock_item_grip_expose (GtkWidget *widget, } +/* see bug #950556: may contribute to regression with GTK2/Quartz */ +#if !defined(GDK_WINDOWING_QUARTZ) if (gdl_dock_item_or_child_has_focus(grip->item)) { gtk_paint_focus (gtk_widget_get_style (widget), @@ -157,6 +159,7 @@ gdl_dock_item_grip_expose (GtkWidget *widget, &event->area, widget, NULL, 0, 0, -1, -1); } +#endif //GDK_WINDOWING_QUARTZ return GTK_WIDGET_CLASS (gdl_dock_item_grip_parent_class)->expose_event (widget, event); } diff --git a/src/libgdl/gdl-dock-item.c b/src/libgdl/gdl-dock-item.c index afcd4dfcb..af630e681 100644 --- a/src/libgdl/gdl-dock-item.c +++ b/src/libgdl/gdl-dock-item.c @@ -1064,8 +1064,11 @@ gdl_dock_item_paint (GtkWidget *widget, "dockitem", 0, 0, -1, -1); +/* see bug #950556: avoid regression with GTK2/Quartz */ +#if !defined(GDK_WINDOWING_QUARTZ) if (GTK_IS_WIDGET(item->_priv->grip)) gtk_widget_queue_draw (GTK_WIDGET(item->_priv->grip)); +#endif } static gint -- cgit v1.2.3 From af121b63c22bde5929a2706285bbc3814fb0ed90 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 24 Aug 2015 23:21:51 +0200 Subject: Fix a big on apply on closed path Transform By two knots (bzr r14322) --- src/live_effects/lpe-transform_2pts.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index d2c2cfc0e..b70b68968 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -67,6 +67,9 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) if(!pathvector.empty()) { point_a = pathvector.initialPoint(); point_b = pathvector.finalPoint(); + if(are_near(point_a,point_b)){ + point_b = pathvector.back().finalCurve().initialPoint(); + } size_t nnodes = nodeCount(pathvector); last_knot.param_set_value(nnodes); } @@ -98,6 +101,7 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) point_a = pointAtNodeIndex(pathvector,(size_t)first_knot-1); point_b = pointAtNodeIndex(pathvector,(size_t)last_knot-1); size_t nnodes = nodeCount(pathvector); + std::cout << nnodes << "nnodes\n"; first_knot.param_set_range(1, last_knot-1); last_knot.param_set_range(first_knot+1, nnodes); from_original_width.param_setValue(false); -- cgit v1.2.3 From 3fd24692ccb9f3531839799feaffdf82f243b0d6 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 25 Aug 2015 14:52:24 +0200 Subject: Prevent crash when "vector" doesn't exist (i.e. for mesh gradient). (bzr r14324) --- src/sp-paint-server.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-paint-server.cpp b/src/sp-paint-server.cpp index c3416c6c8..d445ca0a7 100644 --- a/src/sp-paint-server.cpp +++ b/src/sp-paint-server.cpp @@ -39,7 +39,9 @@ SPPaintServer::~SPPaintServer() { bool SPPaintServer::isSwatch() const { - return swatch; + if( this ) // Protect against assumption that "vector" always exists. + return swatch; + return( false ); } -- cgit v1.2.3 From e540144050e6caf543adb6299e56f6cbee396e77 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 27 Aug 2015 01:34:34 +0200 Subject: Added fixed and elastic modes to transform by two knots (bzr r14325) --- src/live_effects/lpe-transform_2pts.cpp | 94 ++++++++++++++++++++++++++++++--- src/live_effects/lpe-transform_2pts.h | 6 +++ 2 files changed, 92 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index b70b68968..1f1cccd89 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -18,6 +18,7 @@ #include <2geom/pathvector.h> #include "sp-path.h" #include "ui/icon-names.h" +#include "svg/svg.h" #include @@ -26,25 +27,42 @@ namespace LivePathEffect { LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : Effect(lpeobject), + elastic(_("Elastic"), _("Elastic transform mode"), "elastic", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + fixed(_("Fixed"), _("No scale, only move and rotate"), "fixed", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), from_original_width(_("From original width"), _("From original width"), "from_original_width", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), start(_("Start"), _("Start point"), "start", &wr, this, "Start point"), end(_("End"), _("End point"), "end", &wr, this, "End point"), + fixed_width(_("Fixed width"), _("Fixed width"), "fixed_width", &wr, this, 1), first_knot(_("First Knot"), _("First Knot"), "first_knot", &wr, this, 1), last_knot(_("Last Knot"), _("Last Knot"), "last_knot", &wr, this, 1), + helper_size(_("Helper size:"), _("Rotation helper size"), "helper_size", &wr, this, 10), from_original_width_toggler(false), point_a(Geom::Point()), point_b(Geom::Point()), pathvector(), - append_path(false) + append_path(false), + previous_angle(Geom::deg_to_rad(0)), + previous_start(Geom::Point()) { registerParameter(&start); registerParameter(&end); + registerParameter(&fixed_width); registerParameter(&first_knot); registerParameter(&last_knot); + registerParameter(&helper_size); + registerParameter(&elastic); + registerParameter(&fixed); registerParameter(&from_original_width); first_knot.param_make_integer(true); last_knot.param_make_integer(true); + helper_size.param_set_range(0, 999); + helper_size.param_set_increments(1, 1); + helper_size.param_set_digits(0); + + fixed_width.param_set_range(0.0, 99999.0); + fixed_width.param_set_increments(1, 1); + fixed_width.param_set_digits(4); } LPETransform2Pts::~LPETransform2Pts() @@ -73,6 +91,8 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) size_t nnodes = nodeCount(pathvector); last_knot.param_set_value(nnodes); } + + fixed_width.param_set_value(Geom::distance(point_a,point_b)); start.param_update_default(point_a); start.param_set_default(); end.param_update_default(point_b); @@ -101,7 +121,6 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) point_a = pointAtNodeIndex(pathvector,(size_t)first_knot-1); point_b = pointAtNodeIndex(pathvector,(size_t)last_knot-1); size_t nnodes = nodeCount(pathvector); - std::cout << nnodes << "nnodes\n"; first_knot.param_set_range(1, last_knot-1); last_knot.param_set_range(first_knot+1, nnodes); from_original_width.param_setValue(false); @@ -113,6 +132,15 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) from_original_width.param_setValue(true); append_path = false; } + if(fixed){ + Geom::Ray transformed((Geom::Point)start,(Geom::Point)end); + if(previous_start == start || previous_angle == Geom::deg_to_rad(0)){ + previous_angle = transformed.angle(); + } + Geom::Point end_point = Geom::Point::polar(previous_angle, fixed_width) + (Geom::Point)start; + end.param_setValue(end_point); + } + previous_start = start; splpeitem->apply_to_clippath(splpeitem); splpeitem->apply_to_mask(splpeitem); } @@ -125,7 +153,10 @@ LPETransform2Pts::updateIndex() if (sp_path) { pathvector = sp_path->get_original_curve()->get_pathvector(); } - if(!pathvector.empty() && !from_original_width) { + if(pathvector.empty()){ + return; + } + if(!from_original_width) { point_a = pointAtNodeIndex(pathvector,(size_t)first_knot-1); point_b = pointAtNodeIndex(pathvector,(size_t)last_knot-1); start.param_update_default(point_a); @@ -136,7 +167,11 @@ LPETransform2Pts::updateIndex() end.param_update_default(point_b); start.param_set_default(); end.param_set_default(); + } else { + point_a = Geom::Point(boundingbox_X.min(), boundingbox_Y.middle()); + point_b = Geom::Point(boundingbox_X.max(), boundingbox_Y.middle()); } + fixed_width.param_set_value(Geom::distance(point_a,point_b)); } //todo migrate to PathVector class? size_t @@ -197,6 +232,7 @@ LPETransform2Pts::reset() first_knot.param_set_value(1); last_knot.param_set_value(2); } + fixed_width.param_set_value(Geom::distance(point_a,point_b)); start.param_update_default(point_a); end.param_update_default(point_b); start.param_set_default(); @@ -215,6 +251,7 @@ Gtk::Widget *LPETransform2Pts::newWidget() std::vector::iterator it = param_vector.begin(); Gtk::HBox * button = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::HBox * button2 = Gtk::manage(new Gtk::HBox(true,0)); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { Parameter *param = *it; @@ -238,6 +275,28 @@ Gtk::Widget *LPETransform2Pts::newWidget() } } } else if (param->param_key == "from_original_width") { + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + button2->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } else if (param->param_key == "elastic") { + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + button->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } else if (param->param_key == "fixed") { Glib::ustring * tip = param->param_getTooltip(); if (widg) { button->pack_start(*widg, true, true, 2); @@ -263,8 +322,9 @@ Gtk::Widget *LPETransform2Pts::newWidget() } Gtk::Button *reset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset")))); reset->signal_clicked().connect(sigc::mem_fun(*this, &LPETransform2Pts::reset)); - button->pack_start(*reset, true, true, 2); + button2->pack_start(*reset, true, true, 2); vbox->pack_start(*button, true, true, 2); + vbox->pack_start(*button2, true, true, 2); return dynamic_cast(vbox); } @@ -280,10 +340,19 @@ LPETransform2Pts::doEffect_pwd2 (Geom::Piecewise > const helper.start(point_a); helper.appendNew(point_b); Geom::Affine m; - m *= Geom::Scale(sca); - m *= Geom::Rotate(rot); - helper *= m; - m *= Geom::Translate((Geom::Point)start - helper.initialPoint()); + if(elastic){ + Geom::Angle original_angle = original.angle(); + m *= Geom::Rotate(-original_angle); + m *= Geom::Scale(sca, 1.0); + m *= Geom::Rotate(transformed.angle()); + helper *= m; + m *= Geom::Translate((Geom::Point)start - helper.initialPoint()); + } else { + m *= Geom::Scale(sca); + m *= Geom::Rotate(rot); + helper *= m; + m *= Geom::Translate((Geom::Point)start - helper.initialPoint()); + } output.concat(pwd2_in * m); return output; @@ -299,6 +368,15 @@ LPETransform2Pts::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector< hp.appendNew((Geom::Point)end); Geom::PathVector pathv; pathv.push_back(hp); + if(fixed){ + double r = helper_size*.1; + char const * svgd; + svgd = "m 7.07,7.07 c -3.9,3.91 -10.24,3.91 -14.14,0 -3.91,-3.9 -3.91,-10.24 0,-14.14 3.9,-3.91 10.24,-3.91 14.14,0 l -2.83,-4.24 -0.7,2.12"; + PathVector pathv_turn = sp_svg_read_pathv(svgd); + pathv_turn *= Geom::Rotate(previous_angle); + pathv_turn *= Affine(r,0,0,r,0,0) * Translate(Geom::Point(start)); + hp_vec.push_back(pathv_turn); + } hp_vec.push_back(pathv); } diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index 855780a7a..44163427e 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -49,16 +49,22 @@ protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); private: + ToggleButtonParam elastic; + ToggleButtonParam fixed; ToggleButtonParam from_original_width; PointParam start; PointParam end; + ScalarParam fixed_width; ScalarParam first_knot; ScalarParam last_knot; + ScalarParam helper_size; bool from_original_width_toggler; Geom::Point point_a; Geom::Point point_b; Geom::PathVector pathvector; bool append_path; + Geom::Angle previous_angle; + Geom::Point previous_start; LPETransform2Pts(const LPETransform2Pts&); LPETransform2Pts& operator=(const LPETransform2Pts&); }; -- cgit v1.2.3 From 45f0472b3761eb0d68d59c4fc52cc9ebc2d5acee Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 27 Aug 2015 09:05:40 +0200 Subject: Changed from fixed width to lock width, removed one widget to the transform by 2 pts (bzr r14326) --- src/live_effects/lpe-transform_2pts.cpp | 43 ++++++++++++++------------------- src/live_effects/lpe-transform_2pts.h | 8 +++--- 2 files changed, 22 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 1f1cccd89..2aa02039d 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -28,11 +28,10 @@ namespace LivePathEffect { LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : Effect(lpeobject), elastic(_("Elastic"), _("Elastic transform mode"), "elastic", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), - fixed(_("Fixed"), _("No scale, only move and rotate"), "fixed", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + lock_width(_("Lock width"), _("Lock width to current distance"), "lock_width", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), from_original_width(_("From original width"), _("From original width"), "from_original_width", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), start(_("Start"), _("Start point"), "start", &wr, this, "Start point"), end(_("End"), _("End point"), "end", &wr, this, "End point"), - fixed_width(_("Fixed width"), _("Fixed width"), "fixed_width", &wr, this, 1), first_knot(_("First Knot"), _("First Knot"), "first_knot", &wr, this, 1), last_knot(_("Last Knot"), _("Last Knot"), "last_knot", &wr, this, 1), helper_size(_("Helper size:"), _("Rotation helper size"), "helper_size", &wr, this, 10), @@ -42,16 +41,16 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : pathvector(), append_path(false), previous_angle(Geom::deg_to_rad(0)), - previous_start(Geom::Point()) + previous_start(Geom::Point()), + previous_width(-1) { registerParameter(&start); registerParameter(&end); - registerParameter(&fixed_width); registerParameter(&first_knot); registerParameter(&last_knot); registerParameter(&helper_size); registerParameter(&elastic); - registerParameter(&fixed); + registerParameter(&lock_width); registerParameter(&from_original_width); first_knot.param_make_integer(true); @@ -59,10 +58,6 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : helper_size.param_set_range(0, 999); helper_size.param_set_increments(1, 1); helper_size.param_set_digits(0); - - fixed_width.param_set_range(0.0, 99999.0); - fixed_width.param_set_increments(1, 1); - fixed_width.param_set_digits(4); } LPETransform2Pts::~LPETransform2Pts() @@ -85,14 +80,14 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) if(!pathvector.empty()) { point_a = pathvector.initialPoint(); point_b = pathvector.finalPoint(); - if(are_near(point_a,point_b)){ + if(are_near(point_a,point_b)) { point_b = pathvector.back().finalCurve().initialPoint(); } size_t nnodes = nodeCount(pathvector); last_knot.param_set_value(nnodes); } - fixed_width.param_set_value(Geom::distance(point_a,point_b)); + previous_width = Geom::distance(point_a,point_b); start.param_update_default(point_a); start.param_set_default(); end.param_update_default(point_b); @@ -132,13 +127,15 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) from_original_width.param_setValue(true); append_path = false; } - if(fixed){ + if(lock_width && previous_width != -1) { Geom::Ray transformed((Geom::Point)start,(Geom::Point)end); - if(previous_start == start || previous_angle == Geom::deg_to_rad(0)){ + if(previous_start == start || previous_angle == Geom::deg_to_rad(0)) { previous_angle = transformed.angle(); } - Geom::Point end_point = Geom::Point::polar(previous_angle, fixed_width) + (Geom::Point)start; + Geom::Point end_point = Geom::Point::polar(previous_angle, previous_width) + (Geom::Point)start; end.param_setValue(end_point); + } else { + previous_width = Geom::distance(Geom::Point(start), Geom::Point(end)); } previous_start = start; splpeitem->apply_to_clippath(splpeitem); @@ -153,7 +150,7 @@ LPETransform2Pts::updateIndex() if (sp_path) { pathvector = sp_path->get_original_curve()->get_pathvector(); } - if(pathvector.empty()){ + if(pathvector.empty()) { return; } if(!from_original_width) { @@ -167,11 +164,7 @@ LPETransform2Pts::updateIndex() end.param_update_default(point_b); start.param_set_default(); end.param_set_default(); - } else { - point_a = Geom::Point(boundingbox_X.min(), boundingbox_Y.middle()); - point_b = Geom::Point(boundingbox_X.max(), boundingbox_Y.middle()); } - fixed_width.param_set_value(Geom::distance(point_a,point_b)); } //todo migrate to PathVector class? size_t @@ -190,7 +183,7 @@ LPETransform2Pts::pointAtNodeIndex(Geom::PathVector pathvector, size_t index) co size_t n = 0; for (Geom::PathVector::iterator pv_it = pathvector.begin(); pv_it != pathvector.end(); ++pv_it) { for (Geom::Path::iterator curve_it = pv_it->begin(); curve_it != pv_it->end_closed(); ++curve_it) { - if(index == n){ + if(index == n) { return curve_it->initialPoint(); } n++; @@ -205,7 +198,7 @@ LPETransform2Pts::pathAtNodeIndex(Geom::PathVector pathvector, size_t index) con size_t n = 0; for (Geom::PathVector::iterator pv_it = pathvector.begin(); pv_it != pathvector.end(); ++pv_it) { for (Geom::Path::iterator curve_it = pv_it->begin(); curve_it != pv_it->end_closed(); ++curve_it) { - if(index == n){ + if(index == n) { return *pv_it; } n++; @@ -232,7 +225,7 @@ LPETransform2Pts::reset() first_knot.param_set_value(1); last_knot.param_set_value(2); } - fixed_width.param_set_value(Geom::distance(point_a,point_b)); + previous_width = Geom::distance(point_a, point_b); start.param_update_default(point_a); end.param_update_default(point_b); start.param_set_default(); @@ -296,7 +289,7 @@ Gtk::Widget *LPETransform2Pts::newWidget() widg->set_has_tooltip(false); } } - } else if (param->param_key == "fixed") { + } else if (param->param_key == "lock_width") { Glib::ustring * tip = param->param_getTooltip(); if (widg) { button->pack_start(*widg, true, true, 2); @@ -340,7 +333,7 @@ LPETransform2Pts::doEffect_pwd2 (Geom::Piecewise > const helper.start(point_a); helper.appendNew(point_b); Geom::Affine m; - if(elastic){ + if(elastic) { Geom::Angle original_angle = original.angle(); m *= Geom::Rotate(-original_angle); m *= Geom::Scale(sca, 1.0); @@ -368,7 +361,7 @@ LPETransform2Pts::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector< hp.appendNew((Geom::Point)end); Geom::PathVector pathv; pathv.push_back(hp); - if(fixed){ + if(lock_width) { double r = helper_size*.1; char const * svgd; svgd = "m 7.07,7.07 c -3.9,3.91 -10.24,3.91 -14.14,0 -3.91,-3.9 -3.91,-10.24 0,-14.14 3.9,-3.91 10.24,-3.91 14.14,0 l -2.83,-4.24 -0.7,2.12"; diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index 44163427e..bafe02477 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -38,9 +38,9 @@ public: void updateIndex(); size_t nodeCount(Geom::PathVector pathvector) const; - + Geom::Point pointAtNodeIndex(Geom::PathVector pathvector, size_t index) const; - + Geom::Path pathAtNodeIndex(Geom::PathVector pathvector, size_t index) const; void reset(); @@ -50,11 +50,10 @@ protected: private: ToggleButtonParam elastic; - ToggleButtonParam fixed; + ToggleButtonParam lock_width; ToggleButtonParam from_original_width; PointParam start; PointParam end; - ScalarParam fixed_width; ScalarParam first_knot; ScalarParam last_knot; ScalarParam helper_size; @@ -65,6 +64,7 @@ private: bool append_path; Geom::Angle previous_angle; Geom::Point previous_start; + double previous_width; LPETransform2Pts(const LPETransform2Pts&); LPETransform2Pts& operator=(const LPETransform2Pts&); }; -- cgit v1.2.3 From f7e10f65e9df1bc9138e4fd625936098c4333fad Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 27 Aug 2015 22:03:17 +0200 Subject: Add lock angle to transform by two points LPE (bzr r14328) --- src/live_effects/lpe-transform_2pts.cpp | 73 +++++++++++++++++++-------------- src/live_effects/lpe-transform_2pts.h | 5 ++- 2 files changed, 45 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 2aa02039d..83c24dc0c 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -28,13 +28,14 @@ namespace LivePathEffect { LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : Effect(lpeobject), elastic(_("Elastic"), _("Elastic transform mode"), "elastic", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), - lock_width(_("Lock width"), _("Lock width to current distance"), "lock_width", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), from_original_width(_("From original width"), _("From original width"), "from_original_width", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + lock_lenght(_("Lock lenght"), _("Lock lenght to current distance"), "lock_lenght", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + lock_angle(_("Lock angle"), _("Lock angle"), "lock_angle", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), start(_("Start"), _("Start point"), "start", &wr, this, "Start point"), end(_("End"), _("End point"), "end", &wr, this, "End point"), first_knot(_("First Knot"), _("First Knot"), "first_knot", &wr, this, 1), last_knot(_("Last Knot"), _("Last Knot"), "last_knot", &wr, this, 1), - helper_size(_("Helper size:"), _("Rotation helper size"), "helper_size", &wr, this, 10), + helper_size(_("Helper size:"), _("Rotation helper size"), "helper_size", &wr, this, 3), from_original_width_toggler(false), point_a(Geom::Point()), point_b(Geom::Point()), @@ -42,7 +43,7 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : append_path(false), previous_angle(Geom::deg_to_rad(0)), previous_start(Geom::Point()), - previous_width(-1) + previous_lenght(-1) { registerParameter(&start); registerParameter(&end); @@ -50,8 +51,9 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : registerParameter(&last_knot); registerParameter(&helper_size); registerParameter(&elastic); - registerParameter(&lock_width); registerParameter(&from_original_width); + registerParameter(&lock_lenght); + registerParameter(&lock_angle); first_knot.param_make_integer(true); last_knot.param_make_integer(true); @@ -87,7 +89,9 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) last_knot.param_set_value(nnodes); } - previous_width = Geom::distance(point_a,point_b); + previous_lenght = Geom::distance(point_a,point_b); + Geom::Ray transformed(point_a,point_b); + previous_angle = transformed.angle(); start.param_update_default(point_a); start.param_set_default(); end.param_update_default(point_b); @@ -127,16 +131,23 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) from_original_width.param_setValue(true); append_path = false; } - if(lock_width && previous_width != -1) { + if(lock_lenght && !lock_angle && previous_lenght != -1) { Geom::Ray transformed((Geom::Point)start,(Geom::Point)end); if(previous_start == start || previous_angle == Geom::deg_to_rad(0)) { previous_angle = transformed.angle(); } - Geom::Point end_point = Geom::Point::polar(previous_angle, previous_width) + (Geom::Point)start; + } else if(lock_angle && !lock_lenght && previous_angle != Geom::deg_to_rad(0)) { + if(previous_start == start){ + previous_lenght = Geom::distance((Geom::Point)start, (Geom::Point)end); + } + } + if(lock_lenght || lock_angle ) { + Geom::Point end_point = Geom::Point::polar(previous_angle, previous_lenght) + (Geom::Point)start; end.param_setValue(end_point); - } else { - previous_width = Geom::distance(Geom::Point(start), Geom::Point(end)); } + Geom::Ray transformed((Geom::Point)start,(Geom::Point)end); + previous_angle = transformed.angle(); + previous_lenght = Geom::distance((Geom::Point)start, (Geom::Point)end); previous_start = start; splpeitem->apply_to_clippath(splpeitem); splpeitem->apply_to_mask(splpeitem); @@ -225,7 +236,9 @@ LPETransform2Pts::reset() first_knot.param_set_value(1); last_knot.param_set_value(2); } - previous_width = Geom::distance(point_a, point_b); + Geom::Ray transformed(point_a, point_b); + previous_angle = transformed.angle(); + previous_lenght = Geom::distance(point_a, point_b); start.param_update_default(point_a); end.param_update_default(point_b); start.param_set_default(); @@ -243,8 +256,9 @@ Gtk::Widget *LPETransform2Pts::newWidget() vbox->set_spacing(6); std::vector::iterator it = param_vector.begin(); - Gtk::HBox * button = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::HBox * button1 = Gtk::manage(new Gtk::HBox(true,0)); Gtk::HBox * button2 = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::HBox * button3 = Gtk::manage(new Gtk::HBox(true,0)); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { Parameter *param = *it; @@ -267,10 +281,10 @@ Gtk::Widget *LPETransform2Pts::newWidget() widg->set_has_tooltip(false); } } - } else if (param->param_key == "from_original_width") { + } else if (param->param_key == "from_original_width" || param->param_key == "elastic") { Glib::ustring * tip = param->param_getTooltip(); if (widg) { - button2->pack_start(*widg, true, true, 2); + button1->pack_start(*widg, true, true, 2); if (tip) { widg->set_tooltip_text(*tip); } else { @@ -278,21 +292,10 @@ Gtk::Widget *LPETransform2Pts::newWidget() widg->set_has_tooltip(false); } } - } else if (param->param_key == "elastic") { + } else if (param->param_key == "lock_angle" || param->param_key == "lock_lenght") { Glib::ustring * tip = param->param_getTooltip(); if (widg) { - button->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } else if (param->param_key == "lock_width") { - Glib::ustring * tip = param->param_getTooltip(); - if (widg) { - button->pack_start(*widg, true, true, 2); + button2->pack_start(*widg, true, true, 2); if (tip) { widg->set_tooltip_text(*tip); } else { @@ -315,9 +318,10 @@ Gtk::Widget *LPETransform2Pts::newWidget() } Gtk::Button *reset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset")))); reset->signal_clicked().connect(sigc::mem_fun(*this, &LPETransform2Pts::reset)); - button2->pack_start(*reset, true, true, 2); - vbox->pack_start(*button, true, true, 2); + button3->pack_start(*reset, true, true, 2); + vbox->pack_start(*button1, true, true, 2); vbox->pack_start(*button2, true, true, 2); + vbox->pack_start(*button3, true, true, 2); return dynamic_cast(vbox); } @@ -361,13 +365,20 @@ LPETransform2Pts::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector< hp.appendNew((Geom::Point)end); Geom::PathVector pathv; pathv.push_back(hp); - if(lock_width) { - double r = helper_size*.1; + double r = helper_size*.1; + if(lock_lenght || lock_angle ) { + char const * svgd; + svgd = "M -5.39,8.78 -9.13,5.29 -10.38,10.28 Z M -7.22,7.07 -3.43,3.37 m -1.95,-12.16 -3.74,3.5 -1.26,-5 z m -1.83,1.71 3.78,3.7 M 5.24,8.78 8.98,5.29 10.24,10.28 Z M 7.07,7.07 3.29,3.37 M 5.24,-8.78 l 3.74,3.5 1.26,-5 z M 7.07,-7.07 3.29,-3.37"; + PathVector pathv_move = sp_svg_read_pathv(svgd); + pathv_move *= Affine(r,0,0,r,0,0) * Translate(Geom::Point(start)); + hp_vec.push_back(pathv_move); + } + if(!lock_angle && lock_lenght) { char const * svgd; svgd = "m 7.07,7.07 c -3.9,3.91 -10.24,3.91 -14.14,0 -3.91,-3.9 -3.91,-10.24 0,-14.14 3.9,-3.91 10.24,-3.91 14.14,0 l -2.83,-4.24 -0.7,2.12"; PathVector pathv_turn = sp_svg_read_pathv(svgd); pathv_turn *= Geom::Rotate(previous_angle); - pathv_turn *= Affine(r,0,0,r,0,0) * Translate(Geom::Point(start)); + pathv_turn *= Affine(r,0,0,r,0,0) * Translate(Geom::Point(end)); hp_vec.push_back(pathv_turn); } hp_vec.push_back(pathv); diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index bafe02477..947243c82 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -50,8 +50,9 @@ protected: private: ToggleButtonParam elastic; - ToggleButtonParam lock_width; ToggleButtonParam from_original_width; + ToggleButtonParam lock_lenght; + ToggleButtonParam lock_angle; PointParam start; PointParam end; ScalarParam first_knot; @@ -64,7 +65,7 @@ private: bool append_path; Geom::Angle previous_angle; Geom::Point previous_start; - double previous_width; + double previous_lenght; LPETransform2Pts(const LPETransform2Pts&); LPETransform2Pts& operator=(const LPETransform2Pts&); }; -- cgit v1.2.3 From 8ceb1ada94fa58656a3a40bef7c7d1b8232d5a09 Mon Sep 17 00:00:00 2001 From: jtx Date: Fri, 28 Aug 2015 12:32:00 +0200 Subject: Improve elastic mode in transform by two points LPE (bzr r14329) --- src/live_effects/lpe-transform_2pts.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 83c24dc0c..79ffd74de 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -340,7 +340,11 @@ LPETransform2Pts::doEffect_pwd2 (Geom::Piecewise > const if(elastic) { Geom::Angle original_angle = original.angle(); m *= Geom::Rotate(-original_angle); - m *= Geom::Scale(sca, 1.0); + if(sca > 1){ + m *= Geom::Scale(sca, 1.0); + } else { + m *= Geom::Scale(sca, 1.0-((1.0-sca)/2.0)); + } m *= Geom::Rotate(transformed.angle()); helper *= m; m *= Geom::Translate((Geom::Point)start - helper.initialPoint()); -- cgit v1.2.3 From 24cdeecb6af278d2bb321dad6561a2dbe55e3960 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Fri, 28 Aug 2015 15:14:36 +0200 Subject: typo ? (bzr r14330) --- src/ui/widget/color-entry.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/widget/color-entry.h b/src/ui/widget/color-entry.h index edabe1980..08537f26d 100644 --- a/src/ui/widget/color-entry.h +++ b/src/ui/widget/color-entry.h @@ -9,7 +9,7 @@ */ #ifndef SEEN_COLOR_ENTRY_H -#define SEEN_COLOR_ENTRY_H_ +#define SEEN_COLOR_ENTRY_H #include #include "ui/selected-color.h" -- cgit v1.2.3 From cfbc6a2191e7ffe34036dfda81f5fbdc16897108 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 29 Aug 2015 02:21:28 +0200 Subject: Fix a bug on ToogleButton Parameter when call a function without showing the parameter widget (bzr r14331) --- src/live_effects/parameter/togglebutton.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index c5da8b858..47a8b5615 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -119,6 +119,10 @@ ToggleButtonParam::param_newWidget() void ToggleButtonParam::refresh_button() { + if (!_toggled_connection.connected()) { + return; + } + if(!checkwdg){ return; } -- cgit v1.2.3 From 04d1dc5111b134e8618dd306149dc7a768838c77 Mon Sep 17 00:00:00 2001 From: Bryce Harrington Date: Sat, 29 Aug 2015 16:30:03 -0700 Subject: Ensure strncpy'd strings are null terminated (bzr r14332) --- src/extension/internal/metafile-print.cpp | 4 ++-- src/extension/internal/pdfinput/svg-builder.cpp | 1 + src/io/streamtest.cpp | 1 + src/libuemf/uemf.c | 6 +++++- 4 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/extension/internal/metafile-print.cpp b/src/extension/internal/metafile-print.cpp index 2fb36be85..47ba5971c 100644 --- a/src/extension/internal/metafile-print.cpp +++ b/src/extension/internal/metafile-print.cpp @@ -285,8 +285,8 @@ void PrintMetafile::brush_classify(SPObject *parent, int depth, Inkscape::Pixbuf return; } char temp[32]; // large enough - temp[31] = '\0'; - strncpy(temp, pat_i->getAttribute("id"), 31); // Some names may be longer than [EW]MFhatch#_###### + strncpy(temp, pat_i->getAttribute("id"), sizeof(temp)-1); // Some names may be longer than [EW]MFhatch#_###### + temp[sizeof(temp)-1] = '\0'; hatch_classify(temp, hatchType, hatchColor, bkColor); if (*hatchType != -1) { return; diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp index 58e2030d9..a448be639 100644 --- a/src/extension/internal/pdfinput/svg-builder.cpp +++ b/src/extension/internal/pdfinput/svg-builder.cpp @@ -498,6 +498,7 @@ void SvgBuilder::addShadedFill(GfxShading *shading, double *matrix, GfxPath *pat // Obtain clipping path's id from the URL gchar clip_path_id[32]; strncpy(clip_path_id, clip_path_url + 5, strlen(clip_path_url) - 6); + clip_path_id[sizeof (clip_path_id) - 1] = '\0'; SPObject *clip_obj = _doc->getObjectById(clip_path_id); if (clip_obj) { clip_obj->deleteObject(); diff --git a/src/io/streamtest.cpp b/src/io/streamtest.cpp index 2030e6a85..ec59ac4a6 100644 --- a/src/io/streamtest.cpp +++ b/src/io/streamtest.cpp @@ -202,6 +202,7 @@ void path_init(char *path, char *name) exit(1); } strncpy(ptr+1,name,strlen(name)+1); + path[PATH_MAX-1] = '\0'; printf("'%s'\n",path); } diff --git a/src/libuemf/uemf.c b/src/libuemf/uemf.c index 3180c757c..afa116e75 100644 --- a/src/libuemf/uemf.c +++ b/src/libuemf/uemf.c @@ -1858,8 +1858,8 @@ U_LOGCOLORSPACEA logcolorspacea_set( lcsa.lcsIntent = lcsIntent; lcsa.lcsEndpoints = lcsEndpoints; lcsa.lcsGammaRGB = lcsGammaRGB; - memset(lcsa.lcsFilename,0,U_MAX_PATH); // zero out the Filename field strncpy(lcsa.lcsFilename,lcsFilename,U_MAX_PATH); + lcsa.lcsFilename[U_MAX_PATH-1] = '\0'; return(lcsa); } @@ -1889,6 +1889,7 @@ U_LOGCOLORSPACEW logcolorspacew_set( lcsa.lcsEndpoints = lcsEndpoints; lcsa.lcsGammaRGB = lcsGammaRGB; wchar16strncpypad(lcsa.lcsFilename,lcsFilename,U_MAX_PATH); + lcsa.lcsFilename[U_MAX_PATH-1] = '\0'; return(lcsa); } @@ -1983,6 +1984,7 @@ U_LOGFONT logfont_set( lf.lfQuality = lfQuality; lf.lfPitchAndFamily = lfPitchAndFamily; wchar16strncpypad(lf.lfFaceName, lfFaceName, U_LF_FACESIZE); // pad this one as the intial structure was not set to zero + lf.lfFaceName[U_LF_FACESIZE-1] = '\0'; return(lf); } @@ -2006,7 +2008,9 @@ U_LOGFONT_PANOSE logfont_panose_set( U_LOGFONT_PANOSE lfp; memset(&lfp,0,sizeof(U_LOGFONT_PANOSE)); // all fields zero unless needed. Many should be ignored or must be 0. wchar16strncpy(lfp.elfFullName, elfFullName, U_LF_FULLFACESIZE); + lfp.elfFullName[U_LF_FULLFACESIZE-1] = '\0'; wchar16strncpy(lfp.elfStyle, elfStyle, U_LF_FACESIZE); + lfp.elfStyle[U_LF_FACESIZE-1] = '\0'; lfp.elfLogFont = elfLogFont; lfp.elfStyleSize = elfStyleSize; lfp.elfPanose = elfPanose; -- cgit v1.2.3 From 952f240eb043f626eab87dcf1348d778d96ca363 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Sun, 30 Aug 2015 07:37:24 -0400 Subject: lpe-powerstroke. validity check on data. (Bug 1487424) Fixed bugs: - https://launchpad.net/bugs/1487424 (bzr r14333) --- src/live_effects/lpe-powerstroke.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index f90d67d4e..03102a84a 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -102,12 +102,15 @@ static Circle touching_circle( D2 const &curve, double t, double tol=0.0 { //Piecewise k = curvature(curve, tol); D2 dM=derivative(curve); - if ( are_near(L2sq(dM(t)),0.) ) { + if ( are_near(L2sq(dM(t)),0.) && (dM[0].size() > 1) && (dM[1].size() > 1) ) { dM=derivative(dM); } - if ( are_near(L2sq(dM(t)),0.) ) { // try second time + if ( are_near(L2sq(dM(t)),0.) && (dM[0].size() > 1) && (dM[1].size() > 1) ) { // try second time dM=derivative(dM); } + if ( are_near(L2sq(dM(t)),0.) && (dM[0].size() > 1) && (dM[1].size() > 1) ) { // admit defeat + return Geom::Circle(Geom::Point(0., 0.), 0.); + } Piecewise > unitv = unitVector(dM,tol); Piecewise dMlength = dot(Piecewise >(dM),unitv); Piecewise k = cross(derivative(unitv),unitv); -- cgit v1.2.3 From b72f37fbc96879418572c01b682d0403c3e36b18 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 30 Aug 2015 19:55:25 +0200 Subject: Why would anyone make a sorting function that is not antisymmetric ? That makes std::sort crash, and makes me sad. Fixed bugs: - https://launchpad.net/bugs/1490196 (bzr r14334) --- src/ui/dialog/grid-arrange-tab.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp index ccd23a572..086cbe45f 100644 --- a/src/ui/dialog/grid-arrange-tab.cpp +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -75,16 +75,10 @@ static bool sp_compare_x_position(SPItem *first, SPItem *second) a_in_b_vert = false; } - if (!a_in_b_vert) { - return true; - } - if (a_in_b_vert && a->min()[X] > b->min()[X]) { - return false; + if (!a_in_b_vert) { // a and b are not in the same row + return (a->min()[Y] < b->min()[Y]); } - if (a_in_b_vert && a->min()[X] < b->min()[X]) { - return true; - } - return false; + return (a->min()[X] < b->min()[X]); } /* -- cgit v1.2.3 From 77ac1ad74b1be04d7356c7676df0c863569f4163 Mon Sep 17 00:00:00 2001 From: su_v Date: Tue, 1 Sep 2015 01:14:13 +0200 Subject: Fix restoring previous state of 'Objects' and 'Selection sets' dialogs (bzr r14335) --- src/desktop.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/desktop.cpp b/src/desktop.cpp index 02df50c6b..7b20bcb9f 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -1876,6 +1876,8 @@ SPDesktop::show_dialogs() mapVerbPreference.insert(std::make_pair ("ObjectProperties", "/dialogs/object") ); mapVerbPreference.insert(std::make_pair ("SpellCheck", "/dialogs/spellcheck") ); mapVerbPreference.insert(std::make_pair ("Symbols", "/dialogs/symbols") ); + mapVerbPreference.insert(std::make_pair ("ObjectsPanel", "/dialogs/objects") ); + mapVerbPreference.insert(std::make_pair ("TagsPanel", "/dialogs/tags") ); for (std::map::const_iterator iter = mapVerbPreference.begin(); iter != mapVerbPreference.end(); ++iter) { Glib::ustring pref = iter->second; -- cgit v1.2.3 From 6dd9965594784716e56646d385b9a81063290353 Mon Sep 17 00:00:00 2001 From: jtx Date: Tue, 1 Sep 2015 12:45:09 +0200 Subject: Improvements to BSPline widgets: Now the "Change Weight" is % based insteas 0-1 interval Removed "Ignore cusp nodes" and substituted by: "Apply on cusp nodes" and "Apply on non cusp nodes" (bzr r14337) --- src/live_effects/lpe-bspline.cpp | 44 +++++++++++++++++++++++----------------- src/live_effects/lpe-bspline.h | 3 ++- src/ui/tool/node.cpp | 2 +- src/ui/tool/path-manipulator.cpp | 2 +- 4 files changed, 29 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 0cae1dcb6..08ef7ca1b 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -18,8 +18,8 @@ namespace LivePathEffect { const double HANDLE_CUBIC_GAP = 0.001; const double NO_POWER = 0.0; -const double DEFAULT_START_POWER = 0.3334; -const double DEFAULT_END_POWER = 0.6667; +const double DEFAULT_START_POWER = 0.333334; +const double DEFAULT_END_POWER = 0.666667; Geom::PathVector hp; void sp_bspline_drawHandle(Geom::Point p, double helper_size); @@ -27,17 +27,19 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : Effect(lpeobject), steps(_("Steps with CTRL:"), _("Change number of steps with CTRL pressed"), "steps", &wr, this, 2), helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 0), - ignore_cusp(_("Ignore cusp nodes"), _("Change ignoring cusp nodes"), "ignore_cusp", &wr, this, true), + apply_cusp(_("Apply on cusp nodes"), _("Apply on cusp nodes"), "apply_cusp", &wr, this, true), + apply_non_cusp(_("Apply on non cusp nodes"), _("Apply on non cusp nodes"), "apply_non_cusp", &wr, this, true), only_selected(_("Change only selected nodes"), _("Change only selected nodes"), "only_selected", &wr, this, false), - weight(_("Change weight:"), _("Change weight of the effect"), "weight", &wr, this, DEFAULT_START_POWER) + weight(_("Change weight %:"), _("Change weight percent of the effect"), "weight", &wr, this, DEFAULT_START_POWER * 100) { registerParameter(&weight); registerParameter(&steps); registerParameter(&helper_size); - registerParameter(&ignore_cusp); + registerParameter(&apply_cusp); + registerParameter(&apply_non_cusp); registerParameter(&only_selected); - weight.param_set_range(NO_POWER, 1); + weight.param_set_range(NO_POWER, 100.0); weight.param_set_increments(0.1, 0.1); weight.param_set_digits(4); @@ -111,15 +113,10 @@ Gtk::Widget *LPEBSpline::newWidget() Gtk::HBox * hbox_weight_steps = dynamic_cast(widg); std::vector< Gtk::Widget* > childList = hbox_weight_steps->get_children(); Gtk::Entry* entry_widget = dynamic_cast(childList[1]); - entry_widget->set_width_chars(6); + entry_widget->set_width_chars(9); } } - if (param->param_key == "only_selected") { - Gtk::CheckButton *widg_registered = - Gtk::manage(dynamic_cast(widg)); - widg = dynamic_cast(widg_registered); - } - if (param->param_key == "ignore_cusp") { + if (param->param_key == "only_selected" || param->param_key == "apply_cusp" || param->param_key == "apply_non_cusp") { Gtk::CheckButton *widg_registered = Gtk::manage(dynamic_cast(widg)); widg = dynamic_cast(widg_registered); @@ -161,7 +158,7 @@ void LPEBSpline::changeWeight(double weight_ammount) SPPath *path = dynamic_cast(sp_lpe_item); if(path) { SPCurve *curve = path->get_curve_for_edit(); - doBSplineFromWidget(curve, weight_ammount); + doBSplineFromWidget(curve, weight_ammount/100.0); gchar *str = sp_svg_write_path(curve->get_pathvector()); path->getRepr()->setAttribute("inkscape:original-d", str); } @@ -366,7 +363,10 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) point_at3 = in->first_segment()->finalPoint(); sbasis_in = in->first_segment()->toSBasis(); if (cubic) { - if (!ignore_cusp || !Geom::are_near((*cubic)[1], point_at0)) { + if ((apply_cusp && apply_non_cusp) || + (apply_cusp && Geom::are_near((*cubic)[1], point_at0)) || + (apply_non_cusp && !Geom::are_near((*cubic)[1], point_at0))) + { if (isNodePointSelected(point_at0) || !only_selected) { point_at1 = sbasis_in.valueAt(weight_ammount); if (weight_ammount != NO_POWER) { @@ -377,9 +377,12 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) point_at1 = (*cubic)[1]; } } else { - point_at1 = in->first_segment()->initialPoint(); + point_at1 = (*cubic)[1]; } - if (!ignore_cusp || !Geom::are_near((*cubic)[2], point_at3)) { + if ((apply_cusp && apply_non_cusp) || + (apply_cusp && Geom::are_near((*cubic)[2], point_at3)) || + (apply_non_cusp && !Geom::are_near((*cubic)[2], point_at3))) + { if (isNodePointSelected(point_at3) || !only_selected) { point_at2 = sbasis_in.valueAt(1 - weight_ammount); if (weight_ammount != NO_POWER) { @@ -390,10 +393,13 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) point_at2 = (*cubic)[2]; } } else { - point_at2 = in->first_segment()->finalPoint(); + point_at2 = (*cubic)[2]; } } else { - if (!ignore_cusp && weight_ammount != NO_POWER) { + if ((apply_cusp && apply_non_cusp) || + (apply_cusp && weight_ammount == NO_POWER) || + (apply_non_cusp && weight_ammount != NO_POWER)) + { if (isNodePointSelected(point_at0) || !only_selected) { point_at1 = sbasis_in.valueAt(weight_ammount); point_at1 = diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 033e85cf0..b9cd336a9 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -38,7 +38,8 @@ public: private: ScalarParam helper_size; - BoolParam ignore_cusp; + BoolParam apply_cusp; + BoolParam apply_non_cusp; BoolParam only_selected; ScalarParam weight; diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 55d801c46..06e49dc7f 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -61,7 +61,7 @@ namespace Inkscape { namespace UI { const double NO_POWER = 0.0; -const double DEFAULT_START_POWER = 0.3334; +const double DEFAULT_START_POWER = 0.333334; ControlPoint::ColorSet Node::node_colors = { {0xbfbfbf00, 0x000000ff}, // normal fill, stroke diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 7b7bc98ee..fb9e2c070 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -58,7 +58,7 @@ enum PathChange { } // anonymous namespace const double HANDLE_CUBIC_GAP = 0.001; const double NO_POWER = 0.0; -const double DEFAULT_START_POWER = 0.3334; +const double DEFAULT_START_POWER = 0.333334; /** -- cgit v1.2.3 From c784ad5d3cf8ba7d6ea82529757717cf62d9227e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 1 Sep 2015 23:08:41 +0200 Subject: Changed some strings to BSPLine widgets (bzr r14339) --- src/live_effects/lpe-bspline.cpp | 28 ++++++++++++++-------------- src/live_effects/lpe-bspline.h | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 08ef7ca1b..b17caa0f6 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -27,16 +27,16 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : Effect(lpeobject), steps(_("Steps with CTRL:"), _("Change number of steps with CTRL pressed"), "steps", &wr, this, 2), helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 0), - apply_cusp(_("Apply on cusp nodes"), _("Apply on cusp nodes"), "apply_cusp", &wr, this, true), - apply_non_cusp(_("Apply on non cusp nodes"), _("Apply on non cusp nodes"), "apply_non_cusp", &wr, this, true), + apply_no_weight(_("Apply changes if weight = 0%"), _("Apply changes if weight = 0%"), "apply_no_weight", &wr, this, true), + apply_with_weight(_("Apply changes if weight > 0%"), _("Apply changes if weight > 0%"), "apply_with_weight", &wr, this, true), only_selected(_("Change only selected nodes"), _("Change only selected nodes"), "only_selected", &wr, this, false), weight(_("Change weight %:"), _("Change weight percent of the effect"), "weight", &wr, this, DEFAULT_START_POWER * 100) { registerParameter(&weight); registerParameter(&steps); registerParameter(&helper_size); - registerParameter(&apply_cusp); - registerParameter(&apply_non_cusp); + registerParameter(&apply_no_weight); + registerParameter(&apply_with_weight); registerParameter(&only_selected); weight.param_set_range(NO_POWER, 100.0); @@ -116,7 +116,7 @@ Gtk::Widget *LPEBSpline::newWidget() entry_widget->set_width_chars(9); } } - if (param->param_key == "only_selected" || param->param_key == "apply_cusp" || param->param_key == "apply_non_cusp") { + if (param->param_key == "only_selected" || param->param_key == "apply_no_weight" || param->param_key == "apply_with_weight") { Gtk::CheckButton *widg_registered = Gtk::manage(dynamic_cast(widg)); widg = dynamic_cast(widg_registered); @@ -363,9 +363,9 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) point_at3 = in->first_segment()->finalPoint(); sbasis_in = in->first_segment()->toSBasis(); if (cubic) { - if ((apply_cusp && apply_non_cusp) || - (apply_cusp && Geom::are_near((*cubic)[1], point_at0)) || - (apply_non_cusp && !Geom::are_near((*cubic)[1], point_at0))) + if ((apply_no_weight && apply_with_weight) || + (apply_no_weight && Geom::are_near((*cubic)[1], point_at0)) || + (apply_with_weight && !Geom::are_near((*cubic)[1], point_at0))) { if (isNodePointSelected(point_at0) || !only_selected) { point_at1 = sbasis_in.valueAt(weight_ammount); @@ -379,9 +379,9 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) } else { point_at1 = (*cubic)[1]; } - if ((apply_cusp && apply_non_cusp) || - (apply_cusp && Geom::are_near((*cubic)[2], point_at3)) || - (apply_non_cusp && !Geom::are_near((*cubic)[2], point_at3))) + if ((apply_no_weight && apply_with_weight) || + (apply_no_weight && Geom::are_near((*cubic)[2], point_at3)) || + (apply_with_weight && !Geom::are_near((*cubic)[2], point_at3))) { if (isNodePointSelected(point_at3) || !only_selected) { point_at2 = sbasis_in.valueAt(1 - weight_ammount); @@ -396,9 +396,9 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) point_at2 = (*cubic)[2]; } } else { - if ((apply_cusp && apply_non_cusp) || - (apply_cusp && weight_ammount == NO_POWER) || - (apply_non_cusp && weight_ammount != NO_POWER)) + if ((apply_no_weight && apply_with_weight) || + (apply_no_weight && weight_ammount == NO_POWER) || + (apply_with_weight && weight_ammount != NO_POWER)) { if (isNodePointSelected(point_at0) || !only_selected) { point_at1 = sbasis_in.valueAt(weight_ammount); diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index b9cd336a9..7823f00f0 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -38,8 +38,8 @@ public: private: ScalarParam helper_size; - BoolParam apply_cusp; - BoolParam apply_non_cusp; + BoolParam apply_no_weight; + BoolParam apply_with_weight; BoolParam only_selected; ScalarParam weight; -- cgit v1.2.3 From 99ef61fee7fb164bd095bffd87d2e1a3b8bccd51 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sat, 5 Sep 2015 22:29:58 +0200 Subject: Fix z-order in creating symbols (bzr r14342) --- src/selection-chemistry.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 3999156db..cfd76c758 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -3056,6 +3056,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) doc->ensureUpToDate(); std::vector items(selection->list()); + sort(items.begin(),items.end(),sp_object_compare_position_bool); // Keep track of parent, this is where will be inserted. Inkscape::XML::Node *the_first_repr = items[0]->getRepr(); @@ -3122,7 +3123,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) } // Move selected items to new - for (std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();i++){ Inkscape::XML::Node *repr = (*i)->getRepr(); repr->parent()->removeChild(repr); symbol_repr->addChild(repr,NULL); -- cgit v1.2.3 From ab24d531e2f4ba6b9547df7ec2b23742e9d260f9 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sat, 5 Sep 2015 23:35:18 +0200 Subject: better ordering of setting the ids in the group to symbol code Fixed bugs: - https://launchpad.net/bugs/1492615 (bzr r14343) --- src/selection-chemistry.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index cfd76c758..c26a5bc4a 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -3106,6 +3106,8 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) symbol_repr->setAttribute("style", the_group->getAttribute("style")); symbol_repr->setAttribute("class", the_group->getAttribute("class")); + Glib::ustring id = the_group->getAttribute("id"); + the_group->setAttribute("id", id + "_transform"); symbol_repr->setAttribute("id", the_group->getAttribute("id") ); // This should eventually be replaced by 'refX' and 'refY' once SVG WG approves it. @@ -3116,9 +3118,6 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) the_group->getAttribute("inkscape:transform-center-y")); the_group->setAttribute("style", NULL); - Glib::ustring id = symbol_repr->attribute("id"); - id += "_transform"; - the_group->setAttribute("id", id); } -- cgit v1.2.3 From 54b236cad1a35f3b572e11da3f34eb4e2476dd49 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sat, 5 Sep 2015 23:48:55 +0200 Subject: Quick fix for previous fix (i cannot understand why the previous fix still works fine, but it will be cleaner with this anyway) (bzr r14344) --- src/selection-chemistry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index c26a5bc4a..85b62957c 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -3108,7 +3108,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) symbol_repr->setAttribute("class", the_group->getAttribute("class")); Glib::ustring id = the_group->getAttribute("id"); the_group->setAttribute("id", id + "_transform"); - symbol_repr->setAttribute("id", the_group->getAttribute("id") ); + symbol_repr->setAttribute("id", id); // This should eventually be replaced by 'refX' and 'refY' once SVG WG approves it. // It is done here for round-tripping -- cgit v1.2.3 From 3822efebe63b5d367a80786f8c3ce38113c22184 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 6 Sep 2015 01:21:37 +0200 Subject: Attempt to fix 1417173 (undo duplicate gradient crash) Fixed bugs: - https://launchpad.net/bugs/1417173 (bzr r14345) --- src/widgets/gradient-selector.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index 402f30846..63599f3f9 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -555,6 +555,10 @@ sp_gradient_selector_add_vector_clicked (GtkWidget */*w*/, SPGradientSelector *s if (gr) { repr = gr->getRepr()->duplicate(xml_doc); + // Rename the new gradients id to be similar to the cloned gradients + Glib::ustring old_id = gr->getId(); + rename_id(gr, old_id); + doc->getDefs()->getRepr()->addChild(repr, NULL); } else { repr = xml_doc->createElement("svg:linearGradient"); Inkscape::XML::Node *stop = xml_doc->createElement("svg:stop"); @@ -567,17 +571,10 @@ sp_gradient_selector_add_vector_clicked (GtkWidget */*w*/, SPGradientSelector *s stop->setAttribute("style", "stop-color:#fff;stop-opacity:1;"); repr->appendChild(stop); Inkscape::GC::release(stop); + doc->getDefs()->getRepr()->addChild(repr, NULL); + gr = SP_GRADIENT(doc->getObjectByRepr(repr)); } - - doc->getDefs()->getRepr()->addChild(repr, NULL); - - Glib::ustring old_id = gr->getId(); - - gr = SP_GRADIENT(doc->getObjectByRepr(repr)); - - // Rename the new gradients id to be similar to the cloned gradients - rename_id(gr, old_id); - + sp_gradient_vector_selector_set_gradient( SP_GRADIENT_VECTOR_SELECTOR (sel->vectors), doc, gr); sel->selectGradientInTree(gr); -- cgit v1.2.3 From 6496542f5a66b053f4f4a73ac9369262205f7dbf Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Sun, 6 Sep 2015 13:27:05 -0400 Subject: for a zero sbasis, set the size to 1. (Bug 1478168) Fixed bugs: - https://launchpad.net/bugs/1478168 (bzr r14346) --- src/2geom/sbasis.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/2geom/sbasis.cpp b/src/2geom/sbasis.cpp index 42d92d7b8..0f4159e94 100644 --- a/src/2geom/sbasis.cpp +++ b/src/2geom/sbasis.cpp @@ -279,9 +279,11 @@ SBasis multiply_add(SBasis const &a, SBasis const &b, SBasis c) { */ SBasis multiply(SBasis const &a, SBasis const &b) { - SBasis c(a.size() + b.size(), Linear(0,0)); - if(a.isZero() || b.isZero()) + if(a.isZero() || b.isZero()) { + SBasis c(1, Linear(0,0)); return c; + } + SBasis c(a.size() + b.size(), Linear(0,0)); return multiply_add(a, b, c); } #endif -- cgit v1.2.3 From 15b9bd1a8987237146b229f6d837d6327f22da19 Mon Sep 17 00:00:00 2001 From: jtx Date: Tue, 8 Sep 2015 18:37:44 +0200 Subject: fixes bug:1492704 in bspline Fixed bugs: - https://launchpad.net/bugs/1492704 (bzr r14347) --- src/live_effects/lpe-bspline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index b17caa0f6..b77de5cb1 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -140,7 +140,7 @@ Gtk::Widget *LPEBSpline::newWidget() void LPEBSpline::toDefaultWeight() { - changeWeight(DEFAULT_START_POWER); + changeWeight(DEFAULT_START_POWER * 100); } void LPEBSpline::toMakeCusp() -- cgit v1.2.3 From 8361587f222bbf3178fa3732607813b96bdf2909 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 8 Sep 2015 21:43:42 +0200 Subject: Fix a bug in BSpline on straight lines when press a default width button (bzr r14350) --- src/live_effects/lpe-bspline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index b77de5cb1..2b4a5c4a7 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -408,7 +408,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) point_at1 = in->first_segment()->initialPoint(); } if (isNodePointSelected(point_at3) || !only_selected) { - point_at2 = sbasis_in.valueAt(weight_ammount); + point_at2 = sbasis_in.valueAt(1 - weight_ammount); point_at2 = Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP); } else { -- cgit v1.2.3 From 602ccc3691b189bee118c08ec2982a6af93a4a3e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 8 Sep 2015 22:59:15 +0200 Subject: Fix for bug 1492711 Fixed bugs: - https://launchpad.net/bugs/1492711 (bzr r14351) --- src/live_effects/parameter/parameter.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 527bc06fe..70adc3084 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -11,6 +11,7 @@ #include "live_effects/effect.h" #include "svg/svg.h" #include "xml/repr.h" +#include "document-undo.h" #include "svg/stringstream.h" @@ -40,6 +41,8 @@ void Parameter::param_write_to_repr(const char * svgd) { param_effect->getRepr()->setAttribute(param_key.c_str(), svgd); + DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Updated value to scalar parameter")); } void Parameter::write_to_SVG(void) -- cgit v1.2.3 From 5eced68ddae648e23fa4419e8032e2b995c1ed22 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 8 Sep 2015 23:04:30 +0200 Subject: Fix for bug 179842 Fixed bugs: - https://launchpad.net/bugs/179842 (bzr r14352) --- src/sp-path.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-path.cpp b/src/sp-path.cpp index cabed0467..c4d24c503 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -294,8 +294,9 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { // Transform the original-d path if this is a valid LPE this, other else the (ordinary) path if (_curve_before_lpe && hasPathEffectRecursive()) { - if (this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL)) { + if (this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) || this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH)) { // if path has the CLONE_ORIGINAL LPE applied, don't write the transform to the pathdata, but write it 'unoptimized' + // also if the effect is type BEND PATH to fix bug #179842 return transform; } else { _curve_before_lpe->transform(transform); -- cgit v1.2.3 From 2c2ba3e0fe8c030229114e38aeadf8cf60acca75 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 9 Sep 2015 00:48:30 +0200 Subject: Better fix for bug 1492711 Fixed bugs: - https://launchpad.net/bugs/1492711 (bzr r14353) --- src/live_effects/parameter/parameter.cpp | 12 +++++++++--- src/live_effects/parameter/parameter.h | 3 +++ 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 70adc3084..64464f200 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -41,8 +41,6 @@ void Parameter::param_write_to_repr(const char * svgd) { param_effect->getRepr()->setAttribute(param_key.c_str(), svgd); - DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, - _("Updated value to scalar parameter")); } void Parameter::write_to_SVG(void) @@ -73,6 +71,7 @@ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, ScalarParam::~ScalarParam() { + _value_changed_connection.disconnect(); } bool @@ -146,6 +145,13 @@ ScalarParam::param_make_integer(bool yes) inc_page = 10; } +void +ScalarParam::on_value_changed() +{ + DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Change scalar parameter")); +} + Gtk::Widget * ScalarParam::param_newWidget() { @@ -162,7 +168,7 @@ ScalarParam::param_newWidget() } rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); - + _value_changed_connection = rsu->signal_value_changed().connect (sigc::mem_fun (*this, &ScalarParam::on_value_changed)); return dynamic_cast (rsu); } diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h index cc2c4f3d6..c24033c42 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -12,6 +12,7 @@ #include #include <2geom/forward.h> #include <2geom/pathvector.h> +#include // In gtk2, this wasn't an issue; we could toss around // G_MAXDOUBLE and not worry about size allocations. But @@ -111,6 +112,7 @@ public: virtual void param_set_default(); void param_set_value(gdouble val); void param_make_integer(bool yes = true); + void on_value_changed(); void param_set_range(gdouble min, gdouble max); void param_set_digits(unsigned digits); void param_set_increments(double step, double page); @@ -122,6 +124,7 @@ public: inline operator gdouble() const { return value; }; protected: + sigc::connection _value_changed_connection; gdouble value; gdouble min; gdouble max; -- cgit v1.2.3 From 9484c04f9676c7b6588f2918742c6cd08fd51f95 Mon Sep 17 00:00:00 2001 From: jtx Date: Fri, 11 Sep 2015 11:12:55 +0200 Subject: fixes bug:1492711 in bspline and fillet chamfer Fixed bugs: - https://launchpad.net/bugs/1492711 (bzr r14356) --- src/live_effects/lpe-bspline.cpp | 7 +++++++ src/live_effects/lpe-fillet-chamfer.cpp | 10 ++++++++++ src/live_effects/parameter/parameter.cpp | 16 +++++++--------- src/live_effects/parameter/parameter.h | 5 ++--- 4 files changed, 26 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 2b4a5c4a7..731b5d645 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -10,6 +10,8 @@ #include "svg/svg.h" #include "xml/repr.h" #include "preferences.h" +#include "document-undo.h" +#include "verbs.h" // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -42,10 +44,12 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) weight.param_set_range(NO_POWER, 100.0); weight.param_set_increments(0.1, 0.1); weight.param_set_digits(4); + weight.param_overwrite_widget(true); steps.param_set_range(1, 10); steps.param_set_increments(1, 1); steps.param_set_digits(0); + steps.param_overwrite_widget(true); helper_size.param_set_range(0.0, 999.0); helper_size.param_set_increments(1, 1); @@ -141,16 +145,19 @@ Gtk::Widget *LPEBSpline::newWidget() void LPEBSpline::toDefaultWeight() { changeWeight(DEFAULT_START_POWER * 100); + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change to default weight")); } void LPEBSpline::toMakeCusp() { changeWeight(NO_POWER); + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change to 0 weight")); } void LPEBSpline::toWeight() { changeWeight(weight); + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); } void LPEBSpline::changeWeight(double weight_ammount) diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index a9a96864a..209805da3 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -76,12 +76,15 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) : radius.param_set_range(0., infinity()); radius.param_set_increments(1, 1); radius.param_set_digits(4); + radius.param_overwrite_widget(true); chamfer_steps.param_set_range(1, 999); chamfer_steps.param_set_increments(1, 1); chamfer_steps.param_set_digits(0); + chamfer_steps.param_overwrite_widget(true); helper_size.param_set_range(0, infinity()); helper_size.param_set_increments(5, 5); helper_size.param_set_digits(0); + helper_size.param_overwrite_widget(true); fillet_chamfer_values.set_chamfer_steps(3); } @@ -226,18 +229,21 @@ void LPEFilletChamfer::updateFillet() } Piecewise > const &pwd2 = fillet_chamfer_values.get_pwd2(); doUpdateFillet(path_from_piecewise(pwd2, tolerance), power); + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); } void LPEFilletChamfer::fillet() { Piecewise > const &pwd2 = fillet_chamfer_values.get_pwd2(); doChangeType(path_from_piecewise(pwd2, tolerance), 1); + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Convert to fillet")); } void LPEFilletChamfer::inverseFillet() { Piecewise > const &pwd2 = fillet_chamfer_values.get_pwd2(); doChangeType(path_from_piecewise(pwd2, tolerance), 2); + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Convert to inverse fillet")); } void LPEFilletChamfer::chamferSubdivisions() @@ -245,6 +251,7 @@ void LPEFilletChamfer::chamferSubdivisions() fillet_chamfer_values.set_chamfer_steps(chamfer_steps); Piecewise > const &pwd2 = fillet_chamfer_values.get_pwd2(); doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 5000); + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); } void LPEFilletChamfer::chamfer() @@ -252,6 +259,7 @@ void LPEFilletChamfer::chamfer() fillet_chamfer_values.set_chamfer_steps(chamfer_steps); Piecewise > const &pwd2 = fillet_chamfer_values.get_pwd2(); doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 3000); + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Convert to chamfer")); } void LPEFilletChamfer::inverseChamfer() @@ -259,6 +267,7 @@ void LPEFilletChamfer::inverseChamfer() fillet_chamfer_values.set_chamfer_steps(chamfer_steps); Piecewise > const &pwd2 = fillet_chamfer_values.get_pwd2(); doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 4000); + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Convert to inverse fillet")); } void LPEFilletChamfer::refreshKnots() @@ -270,6 +279,7 @@ void LPEFilletChamfer::refreshKnots() tools_switch(desktop, TOOLS_SELECT); tools_switch(desktop, TOOLS_NODES); } + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Knots and helper paths refreshed")); } void LPEFilletChamfer::doUpdateFillet(Geom::PathVector const &original_pathv, double power) diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 64464f200..98aab287f 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -11,7 +11,6 @@ #include "live_effects/effect.h" #include "svg/svg.h" #include "xml/repr.h" -#include "document-undo.h" #include "svg/stringstream.h" @@ -65,13 +64,13 @@ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, digits(2), inc_step(0.1), inc_page(1), - add_slider(false) + add_slider(false), + overwrite_widget(false) { } ScalarParam::~ScalarParam() { - _value_changed_connection.disconnect(); } bool @@ -146,10 +145,9 @@ ScalarParam::param_make_integer(bool yes) } void -ScalarParam::on_value_changed() +ScalarParam::param_overwrite_widget(bool overwrite_widget) { - DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, - _("Change scalar parameter")); + this->overwrite_widget = overwrite_widget; } Gtk::Widget * @@ -166,9 +164,9 @@ ScalarParam::param_newWidget() if (add_slider) { rsu->addSlider(); } - - rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); - _value_changed_connection = rsu->signal_value_changed().connect (sigc::mem_fun (*this, &ScalarParam::on_value_changed)); + if(!overwrite_widget){ + rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); + } return dynamic_cast (rsu); } diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h index c24033c42..8cda42a8e 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -12,7 +12,6 @@ #include #include <2geom/forward.h> #include <2geom/pathvector.h> -#include // In gtk2, this wasn't an issue; we could toss around // G_MAXDOUBLE and not worry about size allocations. But @@ -112,19 +111,18 @@ public: virtual void param_set_default(); void param_set_value(gdouble val); void param_make_integer(bool yes = true); - void on_value_changed(); void param_set_range(gdouble min, gdouble max); void param_set_digits(unsigned digits); void param_set_increments(double step, double page); void addSlider(bool add_slider_widget) { add_slider = add_slider_widget; }; + void param_overwrite_widget(bool overwrite_widget); virtual Gtk::Widget * param_newWidget(); inline operator gdouble() const { return value; }; protected: - sigc::connection _value_changed_connection; gdouble value; gdouble min; gdouble max; @@ -134,6 +132,7 @@ protected: double inc_step; double inc_page; bool add_slider; + bool overwrite_widget; private: ScalarParam(const ScalarParam&); -- cgit v1.2.3 From 8bd8486dc468d6c41b84013c60d9592146851ff8 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sat, 12 Sep 2015 08:40:47 +0200 Subject: Export. Fix for bug #170295 (default export image name for not-saved drawings). Fixed bugs: - https://launchpad.net/bugs/170295 (bzr r14357) --- src/ui/dialog/export.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 1edfdfe80..59fab7771 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -474,7 +474,14 @@ void Export::set_default_filename () { doc_export_name = filename_entry.get_text(); } + else if ( SP_ACTIVE_DOCUMENT ) + { + Glib::ustring filename = create_filepath_from_id (_("bitmap"), filename_entry.get_text()); + filename_entry.set_text(filename); + filename_entry.set_position(filename.length()); + doc_export_name = filename_entry.get_text(); + } } #if WITH_GTKMM_3_0 -- cgit v1.2.3 From da33293ac34f6e05d62b1ea3d3e0e78887e7cfd1 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Sat, 12 Sep 2015 15:05:21 -0400 Subject: set node tool rubberband shadow. (Bug 1494445) Fixed bugs: - https://launchpad.net/bugs/1494445 (bzr r14358) --- src/ui/tool/selector.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ui/tool/selector.cpp b/src/ui/tool/selector.cpp index 051cb41ae..9acf7de88 100644 --- a/src/ui/tool/selector.cpp +++ b/src/ui/tool/selector.cpp @@ -39,6 +39,7 @@ public: setVisible(false); _rubber = static_cast(sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRLRECT, NULL)); + _rubber->setShadow(1, 0xffffffff); sp_canvas_item_hide(_rubber); } -- cgit v1.2.3 From 25900540fbb26b44933ce1ead2240893769cd60f Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sun, 13 Sep 2015 19:50:28 +0200 Subject: Refactoring of the code that handles transformations and snapping in the selector tool and the node tool. Splitting large chunks of code into some small classes, and eliminating some wrapper methods which were all just too similar (bzr r14363) --- src/CMakeLists.txt | 2 + src/Makefile_insert | 1 + src/pure-transform.cpp | 359 ++++++++++++++++++++++++++ src/pure-transform.h | 230 +++++++++++++++++ src/seltrans.cpp | 203 ++++++++------- src/snap.cpp | 486 +++++------------------------------ src/snap.h | 168 ++---------- src/snapped-point.cpp | 5 - src/snapped-point.h | 4 - src/snapper.h | 2 + src/ui/tool/transform-handle-set.cpp | 48 ++-- 11 files changed, 804 insertions(+), 704 deletions(-) create mode 100644 src/pure-transform.cpp create mode 100644 src/pure-transform.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ed93d5f14..ec7713464 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -240,6 +240,7 @@ set(inkscape_SRC print.cpp profile-manager.cpp proj_pt.cpp + pure-transform.cpp rdf.cpp removeoverlap.cpp resource-manager.cpp @@ -367,6 +368,7 @@ set(inkscape_SRC print.h profile-manager.h proj_pt.h + pure-transform.h rdf.h remove-last.h removeoverlap.h diff --git a/src/Makefile_insert b/src/Makefile_insert index 800752df4..b9723ac42 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -88,6 +88,7 @@ ink_common_sources += \ print.cpp print.h \ profile-manager.cpp profile-manager.h \ proj_pt.cpp proj_pt.h \ + pure-transform.cpp pure-transform.h \ removeoverlap.cpp removeoverlap.h \ rdf.cpp rdf.h \ resource-manager.cpp resource-manager.h \ diff --git a/src/pure-transform.cpp b/src/pure-transform.cpp new file mode 100644 index 000000000..aa89c8a8e --- /dev/null +++ b/src/pure-transform.cpp @@ -0,0 +1,359 @@ +/* + * Class for pure transformations, such as translating, scaling, stretching, skewing, and rotating + * + * Authors: + * Diederik van Lierop + * + * Copyright (C) 2015 Diederik van Lierop + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "pure-transform.h" +#include "snap.h" + +namespace Inkscape + +{ + +void PureTransform::snap(::SnapManager *sm, std::vector const &points, Geom::Point const &pointer) { + std::vector transformed_points; + Geom::Rect bbox; + + long source_num = 0; + for (std::vector::const_iterator i = points.begin(); i != points.end(); ++i) { + + /* Work out the transformed version of this point */ + Geom::Point transformed = getTransformedPoint(*i); // _transformPoint(*i, transformation_type, transformation, origin, dim, uniform); + + // add the current transformed point to the box hulling all transformed points + if (i == points.begin()) { + bbox = Geom::Rect(transformed, transformed); + } else { + bbox.expandTo(transformed); + } + + transformed_points.push_back(Inkscape::SnapCandidatePoint(transformed, (*i).getSourceType(), source_num, Inkscape::SNAPTARGET_UNDEFINED, Geom::OptRect())); + source_num++; + } + + /* The current best metric for the best transformation; lower is better, whereas Geom::infinity() + ** means that we haven't snapped anything. + */ + Inkscape::SnapCandidatePoint best_original_point; + g_assert(best_snapped_point.getAlwaysSnap() == false); // Check initialization of snapped point + g_assert(best_snapped_point.getAtIntersection() == false); + g_assert(best_snapped_point.getSnapped() == false); // Check initialization to catch any regression + + std::vector::iterator j = transformed_points.begin(); + + // std::cout << std::endl; + bool first_free_snap = true; + + for (std::vector::const_iterator i = points.begin(); i != points.end(); ++i) { + + // If we have a collection of SnapCandidatePoints, with mixed constrained snapping and free snapping + // requirements (this can happen when scaling, see PureScale::snap()), then freeSnap might never see the + // SnapCandidatePoint with source_num == 0. The freeSnap() method in the object snapper depends on this, + // because only for source-num == 0 the target nodes will be collected. Therefore we enforce that the first + // SnapCandidatePoint that is to be freeSnapped always has source_num == 0; + // TODO: This is a bit ugly so fix this; do we need sourcenum for anything else? if we don't then get rid + // of it and explicitly communicate to the object snapper that this is a first point + if (first_free_snap) { + (*j).setSourceNum(0); + first_free_snap = false; + } + Inkscape::SnappedPoint snapped_point = snap(sm, *j, (*i).getPoint(), bbox); + + // std::cout << "dist = " << snapped_point.getSnapDistance() << std::endl; + snapped_point.setPointerDistance(Geom::L2(pointer - (*i).getPoint())); + + /*Find the transformation that describes where the snapped point has + ** ended up, and also the metric for this transformation. + */ + + bool store_best_snap = false; + if (snapped_point.getSnapped()) { + // We snapped; keep track of the best snap + if (best_snapped_point.isOtherSnapBetter(snapped_point, true)) { + store_best_snap = true; + } + } else { + // So we didn't snap for this point + if (!best_snapped_point.getSnapped()) { + // ... and none of the points before snapped either + // We might still need to apply a constraint though, if we tried a constrained snap. And + // in case of a free snap we might have use for the transformed point, so let's return that + // point, whether it's constrained or not + if (best_snapped_point.isOtherSnapBetter(snapped_point, true) || points.size() == 1) { + // .. so we must keep track of the best non-snapped constrained point + store_best_snap = true; + } + } + } + + if (store_best_snap) { + best_original_point = (*i); + best_snapped_point = snapped_point; + } + + ++j; + } + + /* The current best transformation */ + //Geom::Point best_transformation = getResult(best_original_point, best_snapped_point); + storeTransform(best_original_point, best_snapped_point); + + Geom::Coord best_metric = best_snapped_point.getSnapDistance(); + + // Using " < 1e6" instead of " < Geom::infinity()" for catching some rounding errors + // These rounding errors might be caused by NRRects, see bug #1584301 + best_snapped_point.setSnapDistance(best_metric < 1e6 ? best_metric : Geom::infinity()); +} + + + + + +Geom::Point PureTranslate::getTransformedPoint(SnapCandidatePoint const &p) const { + return p.getPoint() + _vector; +} + +void PureTranslate::storeTransform(SnapCandidatePoint const original_point, SnappedPoint const snapped_point) { + /* Consider the case in which a box is almost aligned with a grid in both + * horizontal and vertical directions. The distance to the intersection of + * the grid lines will always be larger then the distance to a single grid + * line. If we prefer snapping to an intersection over to a single + * grid line, then we cannot use "metric = Geom::L2(result)". Therefore the + * snapped distance will be used as a metric. Please note that the snapped + * distance to an intersection is defined as the distance to the nearest line + * of the intersection, and not to the intersection itself! + */ + // Only for translations, the relevant metric will be the real snapped distance, + // so we don't have to do anything special here + _vector_snapped = snapped_point.getPoint() - original_point.getPoint(); +} + +SnappedPoint PureTranslate::snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point /*pt_orig*/, Geom::OptRect const &bbox_to_snap) const { + return sm->freeSnap(p, bbox_to_snap); +} + +SnappedPoint PureTranslateConstrained::snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const { + // Calculate a constraint dedicated for this specific point + // When doing a constrained translation, all points will move in the same direction, i.e. + // either horizontally or vertically. The lines along which they move are therefore all + // parallel, but might not be co-linear. Therefore we will have to specify the point through + // which the constraint-line runs here, for each point individually. + Snapper::SnapConstraint dedicated_constraint = Snapper::SnapConstraint(pt_orig, _direction); + return sm->constrainedSnap(p, dedicated_constraint, bbox_to_snap); +} + + + + + +Geom::Point PureScale::getTransformedPoint(SnapCandidatePoint const &p) const { + return (p.getPoint() - _origin) * _scale + _origin; +} + +void PureScale::storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point) { + _scale_snapped = Geom::Scale(Geom::infinity(), Geom::infinity()); + // If this point *i is horizontally or vertically aligned with + // the origin of the scaling, then it will scale purely in X or Y + // We can therefore only calculate the scaling in this direction + // and the scaling factor for the other direction should remain + // untouched (unless scaling is uniform of course) + Geom::Point const a = snapped_point.getPoint() - _origin; // vector to snapped point + Geom::Point const b = original_point.getPoint() - _origin; // vector to original point (not the transformed point!) + for (int index = 0; index < 2; index++) { + if (fabs(b[index]) > 1e-4) { // if SCALING CAN occur in this direction + if (fabs(fabs(a[index]/b[index]) - fabs(_scale[index])) > 1e-7) { // if SNAPPING DID occur in this direction + _scale_snapped[index] = a[index] / b[index]; // then calculate it! + // _scale_snapped will be (1,1) if we haven't snapped, because the snapped point equals the original point + } + // we might have left result[1-index] = Geom::infinity() if scaling didn't occur in the other direction + } + } + if (_uniform) { + // Lock the scaling the be uniform, but keep the sign such that we don't change which quadrant we have dragged into + if (fabs(_scale_snapped[0]) < fabs(_scale_snapped[1])) { + _scale_snapped[1] = fabs(_scale_snapped[0]) * Geom::sgn(_scale[1]); + } else { + _scale_snapped[0] = fabs(_scale_snapped[1]) * Geom::sgn(_scale[0]); + } + } + + // Don't ever exit with one of scaling components uninitialized + for (int index = 0; index < 2; index++) { + if (_scale_snapped[index] == Geom::infinity()) { + _scale_snapped[index] = _scale[index]; + } + } + + // Compare the resulting scaling with the desired scaling + Geom::Point scale_metric = _scale_snapped.vector() - _scale.vector(); + snapped_point.setSnapDistance(Geom::L2(scale_metric)); + snapped_point.setSecondSnapDistance(Geom::infinity()); +} + +// When scaling, a point aligned either horizontally or vertically with the origin can only +// move in that specific direction; therefore it should only snap in that direction, so this +// then becomes a constrained snap; otherwise we can use a free snap; +SnappedPoint PureScale::snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const { + Geom::Point const b = (pt_orig - _origin); // vector to original point (not the transformed point!) + bool const c1 = fabs(b[Geom::X]) < 1e-6; + bool const c2 = fabs(b[Geom::Y]) < 1e-6; + if ((c1 || c2) && !(c1 && c2)) { + Geom::Point cvec; cvec[c1] = 1.; + Snapper::SnapConstraint dedicated_constraint = Inkscape::Snapper::SnapConstraint(_origin, cvec); + return sm->constrainedSnap(p, dedicated_constraint, bbox_to_snap); + } else { + return sm->freeSnap(p, bbox_to_snap); + } +} + +SnappedPoint PureScaleConstrained::snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const { + // When constrained scaling, only uniform scaling is supported. + // When uniformly scaling, each point will have its own unique constraint line, + // running from the scaling origin to the original untransformed point. We will + // calculate that line here as a dedicated constraint + Geom::Point b = pt_orig - _origin; + Snapper::SnapConstraint dedicated_constraint = Inkscape::Snapper::SnapConstraint(_origin, b); + return sm->constrainedSnap(p, dedicated_constraint, bbox_to_snap); +} + + + + + +Geom::Point PureStretchConstrained::getTransformedPoint(SnapCandidatePoint const &p) const { + Geom::Scale s(1, 1); + if (_uniform) + s[Geom::X] = s[Geom::Y] = _magnitude; + else { + s[_direction] = _magnitude; + s[1 - _direction] = 1; + } + return ((p.getPoint() - _origin) * s) + _origin; +} + +SnappedPoint PureStretchConstrained::snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const { + Snapper::SnapConstraint dedicated_constraint; + if (_uniform) { + // When uniformly stretching, each point will have its own unique constraint line, + // running from the scaling origin to the original untransformed point. We will + // calculate that line here + Geom::Point b = pt_orig - _origin; + dedicated_constraint = Inkscape::Snapper::SnapConstraint(_origin, b); // dedicated constraint + } else { + Geom::Point cvec; cvec[_direction] = 1.; + dedicated_constraint = Inkscape::Snapper::SnapConstraint(pt_orig, cvec); + } + + return sm->constrainedSnap(p, dedicated_constraint, bbox_to_snap); +} + +void PureStretchConstrained::storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point) { + Geom::Point const a = snapped_point.getPoint() - _origin; // vector to snapped point + Geom::Point const b = original_point.getPoint() - _origin; // vector to original point (not the transformed point!) + + _stretch_snapped = Geom::Scale(Geom::infinity(), Geom::infinity()); + if (fabs(b[_direction]) > 1e-6) { // if STRETCHING will occur for this point + _stretch_snapped[_direction] = a[_direction] / b[_direction]; + _stretch_snapped[1-_direction] = _uniform ? _stretch_snapped[_direction] : 1; + } else { // STRETCHING might occur for this point, but only when the stretching is uniform + if (_uniform && fabs(b[1-_direction]) > 1e-6) { + _stretch_snapped[1-_direction] = a[1-_direction] / b[1-_direction]; + _stretch_snapped[_direction] = _stretch_snapped[1-_direction]; + } + } + + // _stretch_snapped might have one or both components at infinity! + + // Store the metric for this transformation as a virtual distance + snapped_point.setSnapDistance(std::abs(_stretch_snapped[_direction] - _magnitude)); + snapped_point.setSecondSnapDistance(Geom::infinity()); +} + + + + + +Geom::Point PureSkewConstrained::getTransformedPoint(SnapCandidatePoint const &p) const { + Geom::Point transformed; + // Apply the skew factor + transformed[_direction] = (p.getPoint())[_direction] + _skew * ((p.getPoint())[1 - _direction] - _origin[1 - _direction]); + // While skewing, mirroring and scaling (by integer multiples) in the opposite direction is also allowed. + // Apply that scale factor here + transformed[1-_direction] = (p.getPoint() - _origin)[1 - _direction] * _scale + _origin[1 - _direction]; + return transformed; +} + +SnappedPoint PureSkewConstrained::snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const { + // Snapping the nodes of the bounding box of a selection that is being transformed, will only work if + // the transformation of the bounding box is equal to the transformation of the individual nodes. This is + // NOT the case for example when rotating or skewing. The bounding box itself cannot possibly rotate or skew, + // so it's corners have a different transformation. The snappers cannot handle this, therefore snapping + // of bounding boxes is not allowed here. + g_assert(!(p.getSourceType() & Inkscape::SNAPSOURCE_BBOX_CATEGORY)); + + Geom::Point constraint_vector; + constraint_vector[1-_direction] = 0.0; + constraint_vector[_direction] = 1.0; + + return sm->constrainedSnap(p, Inkscape::Snapper::SnapConstraint(constraint_vector), bbox_to_snap); +} + +void PureSkewConstrained::storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point) { + Geom::Point const b = original_point.getPoint() - _origin; // vector to original point (not the transformed point!) + _skew_snapped = (snapped_point.getPoint()[_direction] - (original_point.getPoint())[_direction]) / b[1 - _direction]; // skew factor + + // Store the metric for this transformation as a virtual distance + snapped_point.setSnapDistance(std::abs(_skew_snapped - _skew)); + snapped_point.setSecondSnapDistance(Geom::infinity()); +} + + + + +Geom::Point PureRotateConstrained::getTransformedPoint(SnapCandidatePoint const &p) const { + return (p.getPoint() - _origin) * Geom::Rotate(_angle) + _origin; +} + +SnappedPoint PureRotateConstrained::snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const { + // Snapping the nodes of the bounding box of a selection that is being transformed, will only work if + // the transformation of the bounding box is equal to the transformation of the individual nodes. This is + // NOT the case for example when rotating or skewing. The bounding box itself cannot possibly rotate or skew, + // so it's corners have a different transformation. The snappers cannot handle this, therefore snapping + // of bounding boxes is not allowed here. + g_assert(!(p.getSourceType() & Inkscape::SNAPSOURCE_BBOX_CATEGORY)); + + // Calculate a constraint dedicated for this specific point + Geom::Point b = pt_orig - _origin; + Geom::Coord r = Geom::L2(b); // the radius of the circular constraint + Snapper::SnapConstraint dedicated_constraint = Inkscape::Snapper::SnapConstraint(_origin, b, r); + return sm->constrainedSnap(p, dedicated_constraint, bbox_to_snap); +} + +void PureRotateConstrained::storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point) { + Geom::Point const a = snapped_point.getPoint() - _origin; // vector to snapped point + Geom::Point const b = (original_point.getPoint() - _origin); // vector to original point (not the transformed point!) + // a is vector to snapped point; b is vector to original point; now lets calculate angle between a and b + _angle_snapped = atan2(Geom::dot(Geom::rot90(b), a), Geom::dot(b, a)); + if (Geom::L2(b) < 1e-9) { // points too close to the rotation center will not move. Don't try to snap these + // as they will always yield a perfect snap result if they're already snapped beforehand (e.g. + // when the transformation center has been snapped to a grid intersection in the selector tool) + snapped_point.setSnapDistance(Geom::infinity()); + // PS1: Apparently we don't have to do this for skewing, but why? + // PS2: We cannot easily filter these points upstream, e.g. in the grab() method (seltrans.cpp) + // because the rotation center will change when pressing shift, and grab() won't be recalled. + // Filtering could be done in handleRequest() (again in seltrans.cpp), by iterating through + // the snap candidates. But hey, we're iterating here anyway. + } else { + snapped_point.setSnapDistance(fabs(_angle_snapped - _angle)); + } + snapped_point.setSecondSnapDistance(Geom::infinity()); + +} + +} diff --git a/src/pure-transform.h b/src/pure-transform.h new file mode 100644 index 000000000..8ea74ce76 --- /dev/null +++ b/src/pure-transform.h @@ -0,0 +1,230 @@ +/* + * Class for pure transformations, such as translating, scaling, stretching, skewing, and rotating. Pure means that they cannot + * be combined. This is what makes them different from affine transformations. Pure transformations are being used in the selector + * tool and node tool + * + * Authors: + * Diederik van Lierop + * + * Copyright (C) 2015 Diederik van Lierop + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_PURE_TRANSFORM_H +#define SEEN_PURE_TRANSFORM_H + +#include // for g_warning +#include "snapper.h" // for SnapConstraint + +class SnapManager; + +namespace Inkscape { + +class PureTransform { + +protected: + virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const = 0; + virtual Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const = 0; + virtual void storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point) = 0; + +public: + //PureTransform(); + virtual ~PureTransform() {}; +// virtual PureTransform * clone () const = 0; // https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Virtual_Constructor + + // Snap a group of points + SnappedPoint best_snapped_point; + void snap(::SnapManager *sm, std::vector const &points, Geom::Point const &pointer); +}; + +// ************************************************************************************************************** + +class PureTranslate: public PureTransform { + +protected: + Geom::Point _vector; + Geom::Point _vector_snapped; + + virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const; + virtual Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const; + virtual void storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point); + +public: +// PureTranslate(); // Default constructor +// PureTranslate(PureTranslate const &); // Copy constructor + virtual ~PureTranslate() {}; + PureTranslate(Geom::Point vector = Geom::Point()) { + _vector = vector; + _vector_snapped = vector; + } + + Geom::Point getTranslationSnapped() {return _vector_snapped;} +// PureTranslate * clone () const {return new PureTranslate(*this);} +}; + + +class PureTranslateConstrained: public PureTranslate { + +protected: + Geom::Dim2 _direction; + virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const; + +public: + virtual ~PureTranslateConstrained() {}; + PureTranslateConstrained(Geom::Coord displacement, Geom::Dim2 direction): + PureTranslate() { + _vector[direction] = displacement; + _vector[1-direction] = 0.0; + _direction = direction; + } + // PureTranslateConstrained * clone () const {return new PureTranslateConstrained(*this);} +}; + +// ************************************************************************************************************** + +class PureScale: public PureTransform { + +protected: + Geom::Scale _scale; + Geom::Scale _scale_snapped; + Geom::Point _origin; + bool _uniform; + + virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const; + virtual Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const; + virtual void storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point); + +public: +// PureScale(); // Default constructor +// PureScale(PureScale const &); // Copy constructor + virtual ~PureScale() {}; + + PureScale(Geom::Scale scale, Geom::Point origin, bool uniform) { + _scale = scale; + _scale_snapped = scale; + _origin = origin; + _uniform = uniform; + } + + Geom::Scale getScaleSnapped() {return _scale_snapped;} +// PureScale * clone () const {return new PureScale (*this);} +}; + +class PureScaleConstrained: public PureScale { +//Magnitude of the scale components will be the same, but the sign could still be different () +protected: + virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const; + +public: + virtual ~PureScaleConstrained() {}; + PureScaleConstrained(Geom::Scale scale, Geom::Point origin): + PureScale(scale, origin, true) {}; // Non-uniform constrained scaling is not supported + +// PureScaleConstrained * clone () const {return new PureScaleConstrained(*this);} +}; + +// ************************************************************************************************************** + +class PureStretchConstrained: public PureTransform { +// A stretch is always implicitly constrained + +protected: + Geom::Coord _magnitude; + Geom::Scale _stretch_snapped; + Geom::Point _origin; + Geom::Dim2 _direction; + bool _uniform; + + virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const; + virtual Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const; + virtual void storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point); + +public: + virtual ~PureStretchConstrained() {}; + PureStretchConstrained(Geom::Coord magnitude, Geom::Point origin, Geom::Dim2 direction, bool uniform) { + _magnitude = magnitude; + _origin = origin; + _direction = direction; + _uniform = uniform; + _stretch_snapped = Geom::Scale(magnitude, magnitude); + if (not uniform) { + _stretch_snapped[1-direction] = 1.0; + } + } + + Geom::Scale getStretchSnapped() {return _stretch_snapped;} + Geom::Coord getMagnitude() {return _magnitude;} + Geom::Coord getMagnitudeSnapped() {return _stretch_snapped[_direction];} + +// PureStretchConstrained * clone () const {return new PureStretchConstrained(*this);} +}; + +// ************************************************************************************************************** + +class PureSkewConstrained: public PureTransform { +// A skew is always implicitly constrained + +protected: + Geom::Coord _skew; + Geom::Coord _skew_snapped; + Geom::Coord _scale; + Geom::Point _origin; + Geom::Dim2 _direction; + + virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const; + Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const; + virtual void storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point); + +public: + virtual ~PureSkewConstrained() {}; + PureSkewConstrained(Geom::Coord skew, Geom::Coord scale, Geom::Point origin, Geom::Dim2 direction) { + _skew = skew; + _skew_snapped = skew; + _scale = scale; + _origin = origin; + _direction = direction; + }; + + Geom::Coord getSkewSnapped() {return _skew_snapped;} + +// PureSkewConstrained * clone () const {return new PureSkewConstrained(*this);} +}; + +// ************************************************************************************************************** + +class PureRotateConstrained: public PureTransform { +// A rotation is always implicitly constrained, so we will hide the constructor by making it protected; devs should use PureRotateConstrained instead +// It's _constraint member variable though will be empty + +protected: + double _angle; // in radians + double _angle_snapped; + Geom::Point _origin; + bool _uniform; + + virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const; + virtual Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const; + virtual void storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point); + +public: +// PureRotate(); // Default constructor +// PureRotate(PureRotate const &); // Copy constructor + virtual ~PureRotateConstrained() {}; + + PureRotateConstrained(double angle, Geom::Point origin) { + _origin = origin; + _angle = angle; // in radians! + _angle_snapped = angle; + _uniform = true; // We do not yet allow for simultaneous rotation and scaling + } + + double getAngleSnapped() {return _angle_snapped;} + +// PureRotate * clone () const {return new PureRotate(*this);} +}; + +} + +#endif // !SEEN_PURE_TRANSFORM_H + diff --git a/src/seltrans.cpp b/src/seltrans.cpp index f7562923f..17d704975 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -31,6 +31,7 @@ #include "knot.h" #include "message-stack.h" #include "snap.h" +#include "pure-transform.h" #include "selection.h" #include "ui/tools/select-tool.h" #include "sp-item.h" @@ -897,10 +898,7 @@ gboolean Inkscape::SelTrans::scaleRequest(Geom::Point &pt, guint state) // When scaling by an integer, snapping is not needed } else { // In all other cases we should try to snap now - SnapManager &m = _desktop->namedview->snap_manager; - m.setup(_desktop, false, _items_const); - - Inkscape::SnappedPoint bb, sn; + Inkscape::PureScale *bb, *sn; if ((state & GDK_CONTROL_MASK) || _desktop->isToolboxButtonActive ("lock")) { // Scale is locked to a 1:1 aspect ratio, so that s[X] must be made to equal s[Y]. @@ -915,30 +913,37 @@ gboolean Inkscape::SelTrans::scaleRequest(Geom::Point &pt, guint state) } // Snap along a suitable constraint vector from the origin. - bb = m.constrainedSnapScale(_bbox_points, _point, default_scale, _origin_for_bboxpoints); - sn = m.constrainedSnapScale(_snap_points, _point, geom_scale, _origin_for_specpoints); + + bb = new Inkscape::PureScaleConstrained(default_scale, _origin_for_bboxpoints); + sn = new Inkscape::PureScaleConstrained(geom_scale, _origin_for_specpoints); } else { /* Scale aspect ratio is unlocked */ - bb = m.freeSnapScale(_bbox_points, _point, default_scale, _origin_for_bboxpoints); - sn = m.freeSnapScale(_snap_points, _point, geom_scale, _origin_for_specpoints); + bb = new Inkscape::PureScale(default_scale, _origin_for_bboxpoints, false); + sn = new Inkscape::PureScale(geom_scale, _origin_for_specpoints, false); } + SnapManager &m = _desktop->namedview->snap_manager; + m.setup(_desktop, false, _items_const); + m.snapTransformed(_bbox_points, _point, (*bb)); + m.snapTransformed(_snap_points, _point, (*sn)); + m.unSetup(); // These lines below are duplicated in stretchRequest - if (bb.getSnapped() || sn.getSnapped()) { - if (bb.getSnapped()) { - if (!bb.isOtherSnapBetter(sn, false)) { + //TODO: Eliminate this code duplication + if (bb->best_snapped_point.getSnapped() || sn->best_snapped_point.getSnapped()) { + if (bb->best_snapped_point.getSnapped()) { + if (!bb->best_snapped_point.isOtherSnapBetter(sn->best_snapped_point, false)) { // We snapped the bbox (which is either visual or geometric) - _desktop->snapindicator->set_new_snaptarget(bb); - default_scale = Geom::Scale(bb.getTransformation()); + _desktop->snapindicator->set_new_snaptarget(bb->best_snapped_point); + default_scale = bb->getScaleSnapped(); // Calculate the new transformation and update the handle position pt = _calcAbsAffineDefault(default_scale); } - } else if (sn.getSnapped()) { - _desktop->snapindicator->set_new_snaptarget(sn); + } else if (sn->best_snapped_point.getSnapped()) { + _desktop->snapindicator->set_new_snaptarget(sn->best_snapped_point); // We snapped the special points (e.g. nodes), which are not at the visual bbox // The handle location however (pt) might however be at the visual bbox, so we // will have to calculate pt taking the stroke width into account - geom_scale = Geom::Scale(sn.getTransformation()); + geom_scale = sn->getScaleSnapped(); pt = _calcAbsAffineGeom(geom_scale); } } else { @@ -946,7 +951,9 @@ gboolean Inkscape::SelTrans::scaleRequest(Geom::Point &pt, guint state) _calcAbsAffineDefault(default_scale); _desktop->snapindicator->remove_snaptarget(); } - m.unSetup(); + + delete bb; + delete sn; } /* Status text */ @@ -1003,21 +1010,22 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, Geom SnapManager &m = _desktop->namedview->snap_manager; m.setup(_desktop, false, _items_const); - Inkscape::SnappedPoint bb, sn; - g_assert(bb.getSnapped() == false); // Check initialization to catch any regression - bool symmetrical = state & GDK_CONTROL_MASK; - bb = m.constrainedSnapStretch(_bbox_points, _point, Geom::Coord(default_scale[axis]), _origin_for_bboxpoints, Geom::Dim2(axis), symmetrical); - sn = m.constrainedSnapStretch(_snap_points, _point, Geom::Coord(geom_scale[axis]), _origin_for_specpoints, Geom::Dim2(axis), symmetrical); + Inkscape::PureStretchConstrained bb = Inkscape::PureStretchConstrained(Geom::Coord(default_scale[axis]), _origin_for_bboxpoints, Geom::Dim2(axis), symmetrical); + Inkscape::PureStretchConstrained sn = Inkscape::PureStretchConstrained(Geom::Coord(geom_scale[axis]), _origin_for_specpoints, Geom::Dim2(axis), symmetrical); - if (bb.getSnapped()) { + m.snapTransformed(_bbox_points, _point, bb); + m.snapTransformed(_snap_points, _point, sn); + m.unSetup(); + + if (bb.best_snapped_point.getSnapped()) { // We snapped the bbox (which is either visual or geometric) - default_scale[axis] = bb.getTransformation()[axis]; + default_scale[axis] = bb.getMagnitude(); } - if (sn.getSnapped()) { - geom_scale[axis] = sn.getTransformation()[axis]; + if (sn.best_snapped_point.getSnapped()) { + geom_scale[axis] = sn.getMagnitude(); } if (symmetrical) { @@ -1028,21 +1036,21 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, Geom } // These lines below are duplicated in scaleRequest - if (bb.getSnapped() || sn.getSnapped()) { - if (bb.getSnapped()) { - if (!bb.isOtherSnapBetter(sn, false)) { + if (bb.best_snapped_point.getSnapped() || sn.best_snapped_point.getSnapped()) { + if (bb.best_snapped_point.getSnapped()) { + if (!bb.best_snapped_point.isOtherSnapBetter(sn.best_snapped_point, false)) { // We snapped the bbox (which is either visual or geometric) - _desktop->snapindicator->set_new_snaptarget(bb); - default_scale = Geom::Scale(bb.getTransformation()); + _desktop->snapindicator->set_new_snaptarget(bb.best_snapped_point); + default_scale = bb.getStretchSnapped(); // Calculate the new transformation and update the handle position pt = _calcAbsAffineDefault(default_scale); } - } else if (sn.getSnapped()) { - _desktop->snapindicator->set_new_snaptarget(sn); + } else if (sn.best_snapped_point.getSnapped()) { + _desktop->snapindicator->set_new_snaptarget(sn.best_snapped_point); // We snapped the special points (e.g. nodes), which are not at the visual bbox // The handle location however (pt) might however be at the visual bbox, so we // will have to calculate pt taking the stroke width into account - geom_scale = Geom::Scale(sn.getTransformation()); + geom_scale = sn.getStretchSnapped(); pt = _calcAbsAffineGeom(geom_scale); } } else { @@ -1050,8 +1058,6 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, Geom _calcAbsAffineDefault(default_scale); _desktop->snapindicator->remove_snaptarget(); } - - m.unSetup(); } // status text @@ -1156,16 +1162,14 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, Geom::P SnapManager &m = _desktop->namedview->snap_manager; m.setup(_desktop, false, _items_const); - Geom::Point cvec; cvec[dim_b] = 1.; - Inkscape::Snapper::SnapConstraint const constraint(cvec); - // When skewing, we cannot snap the corners of the bounding box, see the comment in "constrainedSnapSkew" for details - Geom::Point const s(skew[dim_a], scale[dim_a]); - Inkscape::SnappedPoint sn = m.constrainedSnapSkew(_snap_points, _point, constraint, s, _origin, Geom::Dim2(dim_b)); + // When skewing, we cannot snap the corners of the bounding box, see the comment in PureSkewConstrained for details + Inkscape::PureSkewConstrained sn = Inkscape::PureSkewConstrained(skew[dim_a], scale[dim_a], _origin, Geom::Dim2(dim_b)); + m.snapTransformed(_snap_points, _point, sn); - if (sn.getSnapped()) { + if (sn.best_snapped_point.getSnapped()) { // We snapped something, so change the skew to reflect it - skew[dim_a] = sn.getTransformation()[0]; - _desktop->snapindicator->set_new_snaptarget(sn); + skew[dim_a] = sn.getSkewSnapped(); + _desktop->snapindicator->set_new_snaptarget(sn.best_snapped_point); } else { _desktop->snapindicator->remove_snaptarget(); } @@ -1243,13 +1247,14 @@ gboolean Inkscape::SelTrans::rotateRequest(Geom::Point &pt, guint state) SnapManager &m = _desktop->namedview->snap_manager; m.setup(_desktop, false, _items_const); // When rotating, we cannot snap the corners of the bounding box, see the comment in "constrainedSnapRotate" for details - Inkscape::SnappedPoint sn = m.constrainedSnapRotate(_snap_points, _point, radians, _origin); + Inkscape::PureRotateConstrained sn = Inkscape::PureRotateConstrained(radians, _origin); + m.snapTransformed(_snap_points, _point, sn); m.unSetup(); - if (sn.getSnapped()) { - _desktop->snapindicator->set_new_snaptarget(sn); + if (sn.best_snapped_point.getSnapped()) { + _desktop->snapindicator->set_new_snaptarget(sn.best_snapped_point); // We snapped something, so change the rotation to reflect it - radians = sn.getTransformation()[0]; + radians = sn.getAngleSnapped(); r1 = Geom::Rotate(0); r2 = Geom::Rotate(radians); } else { @@ -1352,30 +1357,19 @@ void Inkscape::SelTrans::moveTo(Geom::Point const &xy, guint state) bool const control = (state & GDK_CONTROL_MASK); bool const shift = (state & GDK_SHIFT_MASK); - if (alt) { - - // Alt pressed means: move only by integer multiples of the grid spacing - - if (control) { // ... if also constrained to the orthogonal axes - if (fabs(dxy[Geom::X]) > fabs(dxy[Geom::Y])) { - dxy[Geom::Y] = 0; - } else { - dxy[Geom::X] = 0; - } + if (control) { // constrained to the orthogonal axes + if (fabs(dxy[Geom::X]) > fabs(dxy[Geom::Y])) { + dxy[Geom::Y] = 0; + } else { + dxy[Geom::X] = 0; } + } + + if (alt) {// Alt pressed means: move only by integer multiples of the grid spacing m.setup(_desktop, true, _items_const); dxy = m.multipleOfGridPitch(dxy, _point); m.unSetup(); - } else if (shift) { - if (control) { // shift & control: constrained movement without snapping - if (fabs(dxy[Geom::X]) > fabs(dxy[Geom::Y])) { - dxy[Geom::Y] = 0; - } else { - dxy[Geom::X] = 0; - } - } - } else { //!shift: with snapping - + } else if (!shift) { //!shift: with snapping /* We're snapping to things, possibly with a constraint to horizontal or ** vertical movement. Obtain a list of possible translations and then ** pick the smallest. @@ -1386,52 +1380,55 @@ void Inkscape::SelTrans::moveTo(Geom::Point const &xy, guint state) /* This will be our list of possible translations */ std::list s; + Inkscape::PureTranslate *bb, *sn; + if (control) { // constrained movement with snapping /* Snap to things, and also constrain to horizontal or vertical movement */ - unsigned int dim = fabs(dxy[Geom::X]) > fabs(dxy[Geom::Y]) ? Geom::X : Geom::Y; + Geom::Dim2 dim = fabs(dxy[Geom::X]) > fabs(dxy[Geom::Y]) ? Geom::X : Geom::Y; // When doing a constrained translation, all points will move in the same direction, i.e. // either horizontally or vertically. Therefore we only have to specify the direction of // the constraint-line once. The constraint lines are parallel, but might not be colinear. // Therefore we will have to set the point through which the constraint-line runs - // individually for each point to be snapped; this will be handled however by _snapTransformed() - Geom::Point cvec; cvec[dim] = 1.; - s.push_back(m.constrainedSnapTranslate(_bbox_points, - _point, - Inkscape::Snapper::SnapConstraint(cvec), - dxy)); - - s.push_back(m.constrainedSnapTranslate(_snap_points, - _point, - Inkscape::Snapper::SnapConstraint(cvec), - dxy)); + // individually for each point to be snapped; this will be handled however by snapTransformed() + bb = new Inkscape::PureTranslateConstrained(dxy[dim], dim); + sn = new Inkscape::PureTranslateConstrained(dxy[dim], dim); } else { // !control - - // Let's leave this timer code here for a while. I'll probably need it in the near future (Diederik van Lierop) - /* GTimeVal starttime; - GTimeVal endtime; - g_get_current_time(&starttime); */ - /* Snap to things with no constraint */ - s.push_back(m.freeSnapTranslate(_bbox_points, _point, dxy)); - s.push_back(m.freeSnapTranslate(_snap_points, _point, dxy)); - - /*g_get_current_time(&endtime); - double elapsed = ((((double)endtime.tv_sec - starttime.tv_sec) * G_USEC_PER_SEC + (endtime.tv_usec - starttime.tv_usec))) / 1000.0; - std::cout << "Time spent snapping: " << elapsed << std::endl; */ + bb = new Inkscape::PureTranslate(dxy); + sn = new Inkscape::PureTranslate(dxy); } + // Let's leave this timer code here for a while. I'll probably need it in the near future (Diederik van Lierop) + /* GTimeVal starttime; + GTimeVal endtime; + g_get_current_time(&starttime); */ + + m.snapTransformed(_bbox_points, _point, (*bb)); + m.snapTransformed(_snap_points, _point, (*sn)); m.unSetup(); + /*g_get_current_time(&endtime); + double elapsed = ((((double)endtime.tv_sec - starttime.tv_sec) * G_USEC_PER_SEC + (endtime.tv_usec - starttime.tv_usec))) / 1000.0; + std::cout << "Time spent snapping: " << elapsed << std::endl; */ + /* Pick one */ Inkscape::SnappedPoint best_snapped_point; - for (std::list::const_iterator i = s.begin(); i != s.end(); ++i) { - if (i->getSnapped()) { - if (best_snapped_point.isOtherSnapBetter(*i, true)) { - best_snapped_point = *i; - dxy = i->getTransformation(); - } - } + + bool sn_is_best = sn->best_snapped_point.getSnapped(); + bool bb_is_best = bb->best_snapped_point.getSnapped(); + + if (bb_is_best && sn_is_best) { + sn_is_best = bb->best_snapped_point.isOtherSnapBetter(sn->best_snapped_point, true); + bb_is_best = !sn_is_best; + } + + if (sn_is_best) { + best_snapped_point = sn->best_snapped_point; + dxy = sn->getTranslationSnapped(); + } else if (bb_is_best) { + best_snapped_point = bb->best_snapped_point; + dxy = bb->getTranslationSnapped(); } if (best_snapped_point.getSnapped()) { @@ -1609,7 +1606,7 @@ void Inkscape::SelTrans::_keepClosestPointOnly(Geom::Point const &p) } } - +// TODO: This code is duplicated in transform-handle-set.cpp; fix this! void Inkscape::SelTrans::getNextClosestPoint(bool reverse) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -1635,6 +1632,12 @@ void Inkscape::SelTrans::getNextClosestPoint(bool reverse) } else { _snap_points.push_back(*_all_snap_sources_iter); } + + // Show the updated snap source now; otherwise it won't be shown until the selection is being moved again + SnapManager &m = _desktop->namedview->snap_manager; + m.setup(_desktop); + m.displaySnapsource(*_all_snap_sources_iter); + m.unSetup(); } } } diff --git a/src/snap.cpp b/src/snap.cpp index 5a308777c..5a4a047b2 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -23,6 +23,7 @@ #include "snap-enums.h" #include "snapped-line.h" #include "snapped-curve.h" +#include "pure-transform.h" #include "display/canvas-grid.h" #include "display/snap-indicator.h" @@ -442,16 +443,11 @@ void SnapManager::guideConstrainedSnap(Geom::Point &p, SPGuide const &guideline) s.getPointIfSnapped(p); } -Inkscape::SnappedPoint SnapManager::_snapTransformed( +void SnapManager::snapTransformed( std::vector const &points, Geom::Point const &pointer, - bool constrained, - Inkscape::Snapper::SnapConstraint const &constraint, - Transformation transformation_type, - Geom::Point const &transformation, - Geom::Point const &origin, - Geom::Dim2 dim, - bool uniform) + Inkscape::PureTransform &transform + ) { /* We have a list of points, which we are proposing to transform in some way. We need to see ** if any of these points, when transformed, snap to anything. If they do, we return the @@ -459,47 +455,8 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( */ if (points.size() == 0) { - return Inkscape::SnappedPoint(pointer); - } - - std::vector transformed_points; - Geom::Rect bbox; - - long source_num = 0; - for (std::vector::const_iterator i = points.begin(); i != points.end(); ++i) { - - /* Work out the transformed version of this point */ - Geom::Point transformed = _transformPoint(*i, transformation_type, transformation, origin, dim, uniform); - - // add the current transformed point to the box hulling all transformed points - if (i == points.begin()) { - bbox = Geom::Rect(transformed, transformed); - } else { - bbox.expandTo(transformed); - } - - transformed_points.push_back(Inkscape::SnapCandidatePoint(transformed, (*i).getSourceType(), source_num, Inkscape::SNAPTARGET_UNDEFINED, Geom::OptRect())); - source_num++; - } - - /* The current best transformation */ - Geom::Point best_transformation = transformation; - - /* The current best metric for the best transformation; lower is better, Geom::infinity() - ** means that we haven't snapped anything. - */ - Inkscape::SnappedPoint best_snapped_point; - g_assert(best_snapped_point.getAlwaysSnap() == false); // Check initialization of snapped point - g_assert(best_snapped_point.getAtIntersection() == false); - - // Warnings for the devs - if (constrained && transformation_type == SCALE && !uniform) { - g_warning("Non-uniform constrained scaling is not supported!"); - } - - if (!constrained && transformation_type == ROTATE) { - // We do not yet allow for simultaneous rotation and scaling - g_warning("Unconstrained rotation is not supported!"); + transform.best_snapped_point = Inkscape::SnappedPoint(pointer); + return; } // We will try to snap a set of points, but we don't want to have a snap indicator displayed @@ -508,349 +465,22 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( bool _orig_snapindicator_status = _snapindicator; _snapindicator = false; - std::vector::iterator j = transformed_points.begin(); - - // std::cout << std::endl; - bool first_free_snap = true; - - for (std::vector::const_iterator i = points.begin(); i != points.end(); ++i) { - - /* Snap it */ - Inkscape::SnappedPoint snapped_point; - Inkscape::Snapper::SnapConstraint dedicated_constraint = constraint; - Geom::Point const b = ((*i).getPoint() - origin); // vector to original point (not the transformed point! required for rotations!) - - if (constrained) { - if (((transformation_type == SCALE || transformation_type == STRETCH) && uniform)) { - // When uniformly scaling, each point will have its own unique constraint line, - // running from the scaling origin to the original untransformed point. We will - // calculate that line here - dedicated_constraint = Inkscape::Snapper::SnapConstraint(origin, b); - } else if (transformation_type == ROTATE) { - Geom::Coord r = Geom::L2(b); // the radius of the circular constraint - dedicated_constraint = Inkscape::Snapper::SnapConstraint(origin, b, r); - } else if (transformation_type == STRETCH) { // when non-uniform stretching { - Geom::Point cvec; cvec[dim] = 1.; - dedicated_constraint = Inkscape::Snapper::SnapConstraint((*i).getPoint(), cvec); - } else if (transformation_type == TRANSLATE) { - // When doing a constrained translation, all points will move in the same direction, i.e. - // either horizontally or vertically. The lines along which they move are therefore all - // parallel, but might not be colinear. Therefore we will have to specify the point through - // which the constraint-line runs here, for each point individually. (we could also have done this - // earlier on, e.g. in seltrans.cpp but we're being lazy there and don't want to add an iteration loop) - dedicated_constraint = Inkscape::Snapper::SnapConstraint((*i).getPoint(), constraint.getDirection()); - } // else: leave the original constraint, e.g. for skewing - snapped_point = constrainedSnap(*j, dedicated_constraint, bbox); - } else { - bool const c1 = fabs(b[Geom::X]) < 1e-6; - bool const c2 = fabs(b[Geom::Y]) < 1e-6; - if (transformation_type == SCALE && (c1 || c2) && !(c1 && c2)) { - // When scaling, a point aligned either horizontally or vertically with the origin can only - // move in that specific direction; therefore it should only snap in that direction, otherwise - // we will get snapped points with an invalid transformation - Geom::Point cvec; cvec[c1] = 1.; - dedicated_constraint = Inkscape::Snapper::SnapConstraint(origin, cvec); - snapped_point = constrainedSnap(*j, dedicated_constraint, bbox); - } else { - // If we have a collection of SnapCandidatePoints, with mixed constrained snapping and free snapping - // requirements, then freeSnap might never see the SnapCandidatePoint with source_num == 0. The freeSnap() - // method in the object snapper depends on this, because only for source-num == 0 the target nodes will - // be collected. Therefore we enforce that the first SnapCandidatePoint that is to be freeSnapped always - // has source_num == 0; - // TODO: This is a bit ugly so fix this; do we need sourcenum for anything else? if we don't then get rid - // of it and explicitly communicate to the object snapper that this is a first point - if (first_free_snap) { - (*j).setSourceNum(0); - first_free_snap = false; - } - snapped_point = freeSnap(*j, bbox); - } - } - // std::cout << "dist = " << snapped_point.getSnapDistance() << std::endl; - snapped_point.setPointerDistance(Geom::L2(pointer - (*i).getPoint())); - - // Allow the snapindicator to be displayed again - _snapindicator = _orig_snapindicator_status; - - Geom::Point result; - - /*Find the transformation that describes where the snapped point has - ** ended up, and also the metric for this transformation. - */ - Geom::Point const a = snapped_point.getPoint() - origin; // vector to snapped point - //Geom::Point const b = (*i - origin); // vector to original point - - switch (transformation_type) { - case TRANSLATE: - result = snapped_point.getPoint() - (*i).getPoint(); - /* Consider the case in which a box is almost aligned with a grid in both - * horizontal and vertical directions. The distance to the intersection of - * the grid lines will always be larger then the distance to a single grid - * line. If we prefer snapping to an intersection over to a single - * grid line, then we cannot use "metric = Geom::L2(result)". Therefore the - * snapped distance will be used as a metric. Please note that the snapped - * distance to an intersection is defined as the distance to the nearest line - * of the intersection, and not to the intersection itself! - */ - // Only for translations, the relevant metric will be the real snapped distance, - // so we don't have to do anything special here - break; - case SCALE: - { - result = Geom::Point(Geom::infinity(), Geom::infinity()); - // If this point *i is horizontally or vertically aligned with - // the origin of the scaling, then it will scale purely in X or Y - // We can therefore only calculate the scaling in this direction - // and the scaling factor for the other direction should remain - // untouched (unless scaling is uniform of course) - for (int index = 0; index < 2; index++) { - if (fabs(b[index]) > 1e-4) { // if SCALING CAN occur in this direction - if (fabs(fabs(a[index]/b[index]) - fabs(transformation[index])) > 1e-7) { // if SNAPPING DID occur in this direction - result[index] = a[index] / b[index]; // then calculate it! - } - // we might have left result[1-index] = Geom::infinity() - // if scaling didn't occur in the other direction - } - } - if (uniform) { - if (fabs(result[0]) < fabs(result[1])) { - result[1] = result[0]; - } else { - result[0] = result[1]; - } - } - - // Compare the resulting scaling with the desired scaling - Geom::Point scale_metric = result - transformation; // One or both of its components might be Geom::infinity() - scale_metric[0] = fabs(scale_metric[0]); - scale_metric[1] = fabs(scale_metric[1]); - if (scale_metric[0] == Geom::infinity() || scale_metric[1] == Geom::infinity()) { - snapped_point.setSnapDistance(std::min(scale_metric[0], scale_metric[1])); - } else { - snapped_point.setSnapDistance(Geom::L2(scale_metric)); - } - snapped_point.setSecondSnapDistance(Geom::infinity()); - break; - } - case STRETCH: - result = Geom::Point(Geom::infinity(), Geom::infinity()); - if (fabs(b[dim]) > 1e-6) { // if STRETCHING will occur for this point - result[dim] = a[dim] / b[dim]; - result[1-dim] = uniform ? result[dim] : 1; - } else { // STRETCHING might occur for this point, but only when the stretching is uniform - if (uniform && fabs(b[1-dim]) > 1e-6) { - result[1-dim] = a[1-dim] / b[1-dim]; - result[dim] = result[1-dim]; - } - } - // Store the metric for this transformation as a virtual distance - snapped_point.setSnapDistance(std::abs(result[dim] - transformation[dim])); - snapped_point.setSecondSnapDistance(Geom::infinity()); - break; - case SKEW: - result[0] = (snapped_point.getPoint()[dim] - ((*i).getPoint())[dim]) / b[1 - dim]; // skew factor - result[1] = transformation[1]; // scale factor - // Store the metric for this transformation as a virtual distance - snapped_point.setSnapDistance(std::abs(result[0] - transformation[0])); - snapped_point.setSecondSnapDistance(Geom::infinity()); - break; - case ROTATE: - // a is vector to snapped point; b is vector to original point; now lets calculate angle between a and b - result[0] = atan2(Geom::dot(Geom::rot90(b), a), Geom::dot(b, a)); - result[1] = result[0]; // dummy value; how else should we store an angle in a point ;-) - if (Geom::L2(b) < 1e-9) { // points too close to the rotation center will not move. Don't try to snap these - // as they will always yield a perfect snap result if they're already snapped beforehand (e.g. - // when the transformation center has been snapped to a grid intersection in the selector tool) - snapped_point.setSnapDistance(Geom::infinity()); - // PS1: Apparently we don't have to do this for skewing, but why? - // PS2: We cannot easily filter these points upstream, e.g. in the grab() method (seltrans.cpp) - // because the rotation center will change when pressing shift, and grab() won't be recalled. - // Filtering could be done in handleRequest() (again in seltrans.cpp), by iterating through - // the snap candidates. But hey, we're iterating here anyway. - } else { - snapped_point.setSnapDistance(std::abs(result[0] - transformation[0])); - } - snapped_point.setSecondSnapDistance(Geom::infinity()); - break; - default: - g_assert_not_reached(); - } - - if (snapped_point.getSnapped()) { - // We snapped; keep track of the best snap - if (best_snapped_point.isOtherSnapBetter(snapped_point, true)) { - best_transformation = result; - best_snapped_point = snapped_point; - } - } else { - // So we didn't snap for this point - if (!best_snapped_point.getSnapped()) { - // ... and none of the points before snapped either - // We might still need to apply a constraint though, if we tried a constrained snap. And - // in case of a free snap we might have use for the transformed point, so let's return that - // point, whether it's constrained or not - if (best_snapped_point.isOtherSnapBetter(snapped_point, true) || points.size() == 1) { - // .. so we must keep track of the best non-snapped constrained point - best_transformation = result; - best_snapped_point = snapped_point; - } - } - } - - ++j; - } - - Geom::Coord best_metric; - if (transformation_type == SCALE) { - // When scaling, don't ever exit with one of scaling components uninitialized - for (int index = 0; index < 2; index++) { - if (fabs(best_transformation[index]) == Geom::infinity()) { - if (uniform && fabs(best_transformation[1-index]) < Geom::infinity()) { - best_transformation[index] = best_transformation[1-index]; - } else { - best_transformation[index] = transformation[index]; - } - } - } - } + transform.snap(this, points, pointer); - best_metric = best_snapped_point.getSnapDistance(); - best_snapped_point.setTransformation(best_transformation); - // Using " < 1e6" instead of " < Geom::infinity()" for catching some rounding errors - // These rounding errors might be caused by NRRects, see bug #1584301 - best_snapped_point.setSnapDistance(best_metric < 1e6 ? best_metric : Geom::infinity()); + // Allow the snapindicator to be displayed again + _snapindicator = _orig_snapindicator_status; if (_snapindicator) { - if (best_snapped_point.getSnapped()) { - _desktop->snapindicator->set_new_snaptarget(best_snapped_point); + if (transform.best_snapped_point.getSnapped()) { + _desktop->snapindicator->set_new_snaptarget(transform.best_snapped_point); } else { _desktop->snapindicator->remove_snaptarget(); } } - return best_snapped_point; -} - - -Inkscape::SnappedPoint SnapManager::freeSnapTranslate(std::vector const &p, - Geom::Point const &pointer, - Geom::Point const &tr) -{ - Inkscape::SnappedPoint result = _snapTransformed(p, pointer, false, Geom::Point(0,0), TRANSLATE, tr, Geom::Point(0,0), Geom::X, false); - - if (p.size() == 1) { - displaySnapsource(Inkscape::SnapCandidatePoint(result.getPoint(), p.at(0).getSourceType())); - } - return result; -} - -Inkscape::SnappedPoint SnapManager::constrainedSnapTranslate(std::vector const &p, - Geom::Point const &pointer, - Inkscape::Snapper::SnapConstraint const &constraint, - Geom::Point const &tr) -{ - Inkscape::SnappedPoint result = _snapTransformed(p, pointer, true, constraint, TRANSLATE, tr, Geom::Point(0,0), Geom::X, false); - - if (p.size() == 1) { - displaySnapsource(Inkscape::SnapCandidatePoint(result.getPoint(), p.at(0).getSourceType())); - } - - return result; -} - - -Inkscape::SnappedPoint SnapManager::freeSnapScale(std::vector const &p, - Geom::Point const &pointer, - Geom::Scale const &s, - Geom::Point const &o) -{ - Inkscape::SnappedPoint result = _snapTransformed(p, pointer, false, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false); - - if (p.size() == 1) { - displaySnapsource(Inkscape::SnapCandidatePoint(result.getPoint(), p.at(0).getSourceType())); - } - - return result; -} - - -Inkscape::SnappedPoint SnapManager::constrainedSnapScale(std::vector const &p, - Geom::Point const &pointer, - Geom::Scale const &s, - Geom::Point const &o) -{ - // When constrained scaling, only uniform scaling is supported. - Inkscape::SnappedPoint result = _snapTransformed(p, pointer, true, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true); - - if (p.size() == 1) { - displaySnapsource(Inkscape::SnapCandidatePoint(result.getPoint(), p.at(0).getSourceType())); - } - - return result; -} - -Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(std::vector const &p, - Geom::Point const &pointer, - Geom::Coord const &s, - Geom::Point const &o, - Geom::Dim2 d, - bool u) -{ - Inkscape::SnappedPoint result = _snapTransformed(p, pointer, true, Geom::Point(0,0), STRETCH, Geom::Point(s, s), o, d, u); - - if (p.size() == 1) { - displaySnapsource(Inkscape::SnapCandidatePoint(result.getPoint(), p.at(0).getSourceType())); - } - - return result; -} - -Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(std::vector const &p, - Geom::Point const &pointer, - Inkscape::Snapper::SnapConstraint const &constraint, - Geom::Point const &s, - Geom::Point const &o, - Geom::Dim2 d) -{ - // "s" contains skew factor in s[0], and scale factor in s[1] - - // Snapping the nodes of the bounding box of a selection that is being transformed, will only work if - // the transformation of the bounding box is equal to the transformation of the individual nodes. This is - // NOT the case for example when rotating or skewing. The bounding box itself cannot possibly rotate or skew, - // so it's corners have a different transformation. The snappers cannot handle this, therefore snapping - // of bounding boxes is not allowed here. - if (!p.empty()) { - g_assert(!(p.at(0).getSourceType() & Inkscape::SNAPSOURCE_BBOX_CATEGORY)); - } - - Inkscape::SnappedPoint result = _snapTransformed(p, pointer, true, constraint, SKEW, s, o, d, false); - - if (p.size() == 1) { - displaySnapsource(Inkscape::SnapCandidatePoint(result.getPoint(), p.at(0).getSourceType())); - } - - return result; -} - -Inkscape::SnappedPoint SnapManager::constrainedSnapRotate(std::vector const &p, - Geom::Point const &pointer, - Geom::Coord const &angle, - Geom::Point const &o) -{ - // Snapping the nodes of the bounding box of a selection that is being transformed, will only work if - // the transformation of the bounding box is equal to the transformation of the individual nodes. This is - // NOT the case for example when rotating or skewing. The bounding box itself cannot possibly rotate or skew, - // so it's corners have a different transformation. The snappers cannot handle this, therefore snapping - // of bounding boxes is not allowed here. - - Inkscape::SnappedPoint result = _snapTransformed(p, pointer, true, Geom::Point(0,0), ROTATE, Geom::Point(angle, angle), o, Geom::X, false); - - if (p.size() == 1) { - displaySnapsource(Inkscape::SnapCandidatePoint(result.getPoint(), p.at(0).getSourceType())); + if (points.size() == 1) { + displaySnapsource(Inkscape::SnapCandidatePoint(transform.best_snapped_point.getPoint(), points.at(0).getSourceType())); } - - return result; - } Inkscape::SnappedPoint SnapManager::findBestSnap(Inkscape::SnapCandidatePoint const &p, @@ -1090,51 +720,51 @@ SPDocument *SnapManager::getDocument() const return _named_view->document; } -Geom::Point SnapManager::_transformPoint(Inkscape::SnapCandidatePoint const &p, - Transformation const transformation_type, - Geom::Point const &transformation, - Geom::Point const &origin, - Geom::Dim2 const dim, - bool const uniform) const -{ - /* Work out the transformed version of this point */ - Geom::Point transformed; - switch (transformation_type) { - case TRANSLATE: - transformed = p.getPoint() + transformation; - break; - case SCALE: - transformed = (p.getPoint() - origin) * Geom::Scale(transformation[Geom::X], transformation[Geom::Y]) + origin; - break; - case STRETCH: - { - Geom::Scale s(1, 1); - if (uniform) - s[Geom::X] = s[Geom::Y] = transformation[dim]; - else { - s[dim] = transformation[dim]; - s[1 - dim] = 1; - } - transformed = ((p.getPoint() - origin) * s) + origin; - break; - } - case SKEW: - // Apply the skew factor - transformed[dim] = (p.getPoint())[dim] + transformation[0] * ((p.getPoint())[1 - dim] - origin[1 - dim]); - // While skewing, mirroring and scaling (by integer multiples) in the opposite direction is also allowed. - // Apply that scale factor here - transformed[1-dim] = (p.getPoint() - origin)[1 - dim] * transformation[1] + origin[1 - dim]; - break; - case ROTATE: - // for rotations: transformation[0] stores the angle in radians - transformed = (p.getPoint() - origin) * Geom::Rotate(transformation[0]) + origin; - break; - default: - g_assert_not_reached(); - } - - return transformed; -} +//Geom::Point SnapManager::_transformPoint(Inkscape::SnapCandidatePoint const &p, +// Transformation const transformation_type, +// Geom::Point const &transformation, +// Geom::Point const &origin, +// Geom::Dim2 const dim, +// bool const uniform) const +//{ +// /* Work out the transformed version of this point */ +// Geom::Point transformed; +// switch (transformation_type) { +// case TRANSLATE: +// transformed = p.getPoint() + transformation; +// break; +// case SCALE: +// transformed = (p.getPoint() - origin) * Geom::Scale(transformation[Geom::X], transformation[Geom::Y]) + origin; +// break; +// case STRETCH: +// { +// Geom::Scale s(1, 1); +// if (uniform) +// s[Geom::X] = s[Geom::Y] = transformation[dim]; +// else { +// s[dim] = transformation[dim]; +// s[1 - dim] = 1; +// } +// transformed = ((p.getPoint() - origin) * s) + origin; +// break; +// } +// case SKEW: +// // Apply the skew factor +// transformed[dim] = (p.getPoint())[dim] + transformation[0] * ((p.getPoint())[1 - dim] - origin[1 - dim]); +// // While skewing, mirroring and scaling (by integer multiples) in the opposite direction is also allowed. +// // Apply that scale factor here +// transformed[1-dim] = (p.getPoint() - origin)[1 - dim] * transformation[1] + origin[1 - dim]; +// break; +// case ROTATE: +// // for rotations: transformation[0] stores the angle in radians +// transformed = (p.getPoint() - origin) * Geom::Rotate(transformation[0]) + origin; +// break; +// default: +// g_assert_not_reached(); +// } +// +// return transformed; +//} /** * Mark the location of the snap source (not the snap target!) on the canvas by drawing a symbol. diff --git a/src/snap.h b/src/snap.h index 944c49b3e..c4dd67b4c 100644 --- a/src/snap.h +++ b/src/snap.h @@ -21,6 +21,8 @@ #include "guide-snapper.h" #include "object-snapper.h" #include "snap-preferences.h" +//#include "pure-transform.h" + // Guides enum SPGuideDragType { // used both here and in desktop-events.cpp @@ -32,6 +34,11 @@ enum SPGuideDragType { // used both here and in desktop-events.cpp class SPGuide; class SPNamedView; + +namespace Inkscape { + class PureTransform; +} + typedef struct _GSList GSList; /** @@ -327,110 +334,6 @@ public: */ void guideConstrainedSnap(Geom::Point &p, SPGuide const &guideline) const; - /** - * Apply a translation to a set of points and try to snap freely in 2 degrees-of-freedom. - * - * @param p Collection of points to snap (snap sources), at their untransformed position, all points undergoing the same transformation. Paired with an identifier of the type of the snap source. - * @param pointer Location of the mouse pointer at the time dragging started (i.e. when the selection was still untransformed). - * @param tr Proposed translation; the final translation can only be calculated after snapping has occurred. - * @return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics. - */ - Inkscape::SnappedPoint freeSnapTranslate(std::vector const &p, - Geom::Point const &pointer, - Geom::Point const &tr); - - /** - * Apply a translation to a set of points and try to snap along a constraint. - * - * @param p Collection of points to snap (snap sources), at their untransformed position, all points undergoing the same transformation. Paired with an identifier of the type of the snap source. - * @param pointer Location of the mouse pointer at the time dragging started (i.e. when the selection was still untransformed). - * @param constraint The direction or line along which snapping must occur. - * @param tr Proposed translation; the final translation can only be calculated after snapping has occurred. - * @return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics. - */ - Inkscape::SnappedPoint constrainedSnapTranslate(std::vector const &p, - Geom::Point const &pointer, - Inkscape::Snapper::SnapConstraint const &constraint, - Geom::Point const &tr); - - /** - * Apply a scaling to a set of points and try to snap freely in 2 degrees-of-freedom. - * - * @param p Collection of points to snap (snap sources), at their untransformed position, all points undergoing the same transformation. Paired with an identifier of the type of the snap source. - * @param pointer Location of the mouse pointer at the time dragging started (i.e. when the selection was still untransformed). - * @param s Proposed scaling; the final scaling can only be calculated after snapping has occurred. - * @param o Origin of the scaling. - * @return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics. - */ - Inkscape::SnappedPoint freeSnapScale(std::vector const &p, - Geom::Point const &pointer, - Geom::Scale const &s, - Geom::Point const &o); - - /** - * Apply a scaling to a set of points and snap such that the aspect ratio of the selection is preserved. - * - * @param p Collection of points to snap (snap sources), at their untransformed position, all points undergoing the same transformation. Paired with an identifier of the type of the snap source. - * @param pointer Location of the mouse pointer at the time dragging started (i.e. when the selection was still untransformed). - * @param s Proposed scaling; the final scaling can only be calculated after snapping has occurred. - * @param o Origin of the scaling. - * @return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics. - */ - Inkscape::SnappedPoint constrainedSnapScale(std::vector const &p, - Geom::Point const &pointer, - Geom::Scale const &s, - Geom::Point const &o); - - /** - * Apply a stretch to a set of points and snap such that the direction of the stretch is preserved. - * - * @param p Collection of points to snap (snap sources), at their untransformed position, all points undergoing the same transformation. Paired with an identifier of the type of the snap source. - * @param pointer Location of the mouse pointer at the time dragging started (i.e. when the selection was still untransformed). - * @param s Proposed stretch; the final stretch can only be calculated after snapping has occurred. - * @param o Origin of the stretching. - * @param d Dimension in which to apply proposed stretch. - * @param u true if the stretch should be uniform (i.e. to be applied equally in both dimensions). - * @return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics. - */ - Inkscape::SnappedPoint constrainedSnapStretch(std::vector const &p, - Geom::Point const &pointer, - Geom::Coord const &s, - Geom::Point const &o, - Geom::Dim2 d, - bool uniform); - - /** - * Apply a skew to a set of points and snap such that the direction of the skew is preserved. - * - * @param p Collection of points to snap (snap sources), at their untransformed position, all points undergoing the same transformation. Paired with an identifier of the type of the snap source. - * @param pointer Location of the mouse pointer at the time dragging started (i.e. when the selection was still untransformed). - * @param constraint The direction or line along which snapping must occur. - * @param s Proposed skew; the final skew can only be calculated after snapping has occurred. - * @param o Origin of the proposed skew. - * @param d Dimension in which to apply proposed skew. - * @return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics. - */ - Inkscape::SnappedPoint constrainedSnapSkew(std::vector const &p, - Geom::Point const &pointer, - Inkscape::Snapper::SnapConstraint const &constraint, - Geom::Point const &s, // s[0] = skew factor, s[1] = scale factor - Geom::Point const &o, - Geom::Dim2 d); - - /** - * Apply a rotation to a set of points and snap, without scaling. - * - * @param p Collection of points to snap (snap sources), at their untransformed position, all points undergoing the same transformation. Paired with an identifier of the type of the snap source. - * @param pointer Location of the mouse pointer at the time dragging started (i.e. when the selection was still untransformed). - * @param angle Proposed rotation (in radians); the final rotation can only be calculated after snapping has occurred. - * @param o Origin of the rotation. - * @return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics. - */ - Inkscape::SnappedPoint constrainedSnapRotate(std::vector const &p, - Geom::Point const &pointer, - Geom::Coord const &angle, - Geom::Point const &o); - Inkscape::GuideSnapper guide; ///< guide snapper Inkscape::ObjectSnapper object; ///< snapper to other objects Inkscape::SnapPreferences snapprefs; @@ -490,17 +393,6 @@ public: */ void displaySnapsource(Inkscape::SnapCandidatePoint const &p) const; -protected: - SPNamedView const *_named_view; - -private: - std::vector _items_to_ignore; ///< Items that should not be snapped to, for example the items that are currently being dragged. Set using the setup() method - std::vector _rotation_center_source_items; // to avoid snapping a rotation center to itself - SPGuide *_guide_to_ignore; ///< A guide that should not be snapped to, e.g. the guide that is currently being dragged - SPDesktop const *_desktop; - bool _snapindicator; ///< When true, an indicator will be drawn at the position that was being snapped to - std::vector *_unselected_nodes; ///< Nodes of the path that is currently being edited and which have not been selected and which will therefore be stationary. Only these nodes will be considered for snapping to. Of each unselected node both the position (Geom::Point) and the type (Inkscape::SnapTargetType) will be stored - /** * Method for snapping sets of points while they are being transformed. * @@ -518,42 +410,22 @@ private: * * @param points Collection of points to snap (snap sources), at their untransformed position, all points undergoing the same transformation. Paired with an identifier of the type of the snap source. * @param pointer Location of the mouse pointer at the time dragging started (i.e. when the selection was still untransformed). - * @param constrained true if the snap is constrained, e.g. for stretching or for purely horizontal translation. - * @param constraint The direction or line along which snapping must occur, if 'constrained' is true; otherwise undefined. - * @param transformation_type Type of transformation to apply to points before trying to snap them. - * @param transformation Description of the transformation; details depend on the type. - * @param origin Origin of the transformation, if applicable. - * @param dim Dimension to which the transformation applies, if applicable. - * @param uniform true if the transformation should be uniform; only applicable for stretching and scaling. - * @return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics. + * @param transform Describes the type of transformation, it's parameters, and any additional constraints */ - Inkscape::SnappedPoint _snapTransformed(std::vector const &points, + void snapTransformed(std::vector const &points, Geom::Point const &pointer, - bool constrained, - Inkscape::Snapper::SnapConstraint const &constraint, - Transformation transformation_type, - Geom::Point const &transformation, - Geom::Point const &origin, - Geom::Dim2 dim, - bool uniform); + Inkscape::PureTransform &transform); - /** - * Takes an untransformed point, applies the given transformation, and returns the transformed point. Eliminates lots of duplicated code. - * - * @param p The untransformed position of the point, paired with an identifier of the type of the snap source. - * @param transformation_type Type of transformation to apply. - * @param transformation Mathematical description of the transformation; details depend on the type. - * @param origin Origin of the transformation, if applicable. - * @param dim Dimension to which the transformation applies, if applicable. - * @param uniform true if the transformation should be uniform; only applicable for stretching and scaling. - * @return The position of the point after transformation. - */ - Geom::Point _transformPoint(Inkscape::SnapCandidatePoint const &p, - Transformation const transformation_type, - Geom::Point const &transformation, - Geom::Point const &origin, - Geom::Dim2 const dim, - bool const uniform) const; +protected: + SPNamedView const *_named_view; + +private: + std::vector _items_to_ignore; ///< Items that should not be snapped to, for example the items that are currently being dragged. Set using the setup() method + std::vector _rotation_center_source_items; // to avoid snapping a rotation center to itself + SPGuide *_guide_to_ignore; ///< A guide that should not be snapped to, e.g. the guide that is currently being dragged + SPDesktop const *_desktop; + bool _snapindicator; ///< When true, an indicator will be drawn at the position that was being snapped to + std::vector *_unselected_nodes; ///< Nodes of the path that is currently being edited and which have not been selected and which will therefore be stationary. Only these nodes will be considered for snapping to. Of each unselected node both the position (Geom::Point) and the type (Inkscape::SnapTargetType) will be stored }; diff --git a/src/snapped-point.cpp b/src/snapped-point.cpp index ab545bd5f..f826211fa 100644 --- a/src/snapped-point.cpp +++ b/src/snapped-point.cpp @@ -29,7 +29,6 @@ Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const _second_distance (Geom::infinity()), _second_tolerance (1), _second_always_snap (false), - _transformation (Geom::Point(1,1)), _target_bbox(target_bbox), _pointer_distance (Geom::infinity()) { @@ -50,7 +49,6 @@ Inkscape::SnappedPoint::SnappedPoint(Inkscape::SnapCandidatePoint const &p, Snap _second_distance (Geom::infinity()), _second_tolerance (1), _second_always_snap (false), - _transformation (Geom::Point(1,1)), _target_bbox (p.getTargetBBox()), _pointer_distance (Geom::infinity()) { @@ -73,7 +71,6 @@ Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const _second_always_snap(a2), // tolerance should never be smaller than 1 px, as it is used for normalization in // isOtherSnapBetter. We don't want a division by zero. - _transformation (Geom::Point(1,1)), _target_bbox (Geom::OptRect()), _pointer_distance (Geom::infinity()) { @@ -94,7 +91,6 @@ Inkscape::SnappedPoint::SnappedPoint(): _second_distance (Geom::infinity()), _second_tolerance (1), _second_always_snap (false), - _transformation (Geom::Point(1,1)), _target_bbox (Geom::OptRect()), _pointer_distance (Geom::infinity()) { @@ -115,7 +111,6 @@ Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p): _second_distance (Geom::infinity()), _second_tolerance (1), _second_always_snap (false), - _transformation (Geom::Point(1,1)), _target_bbox (Geom::OptRect()), _pointer_distance (Geom::infinity()) { diff --git a/src/snapped-point.h b/src/snapped-point.h index 9d77ab162..cf3a15c3b 100644 --- a/src/snapped-point.h +++ b/src/snapped-point.h @@ -66,8 +66,6 @@ public: bool getFullyConstrained() const {return _fully_constrained;} bool getConstrainedSnap() const {return _constrained_snap;} bool getSnapped() const {return _distance < Geom::infinity();} - Geom::Point getTransformation() const {return _transformation;} - void setTransformation(Geom::Point const &t) {_transformation = t;} void setTarget(SnapTargetType const target) {_target = target;} SnapTargetType getTarget() const {return _target;} void setTargetBBox(Geom::OptRect const target) {_target_bbox = target;} @@ -122,8 +120,6 @@ protected: Geom::Coord _second_tolerance; /* If true then "Always snap" is on */ bool _second_always_snap; - /* The transformation (translation, scale, skew, or stretch) from the original point to the snapped point */ - Geom::Point _transformation; /* The bounding box we've snapped to (when applicable); will be used by the snapindicator */ Geom::OptRect _target_bbox; /* Distance from the un-transformed point to the mouse pointer, measured at the point in time when dragging started */ diff --git a/src/snapper.h b/src/snapper.h index 9616d0954..24f9b9442 100644 --- a/src/snapper.h +++ b/src/snapper.h @@ -76,6 +76,8 @@ public: SnapConstraint(Geom::Point const &d) : _point(), _direction(d), _radius(0), _type(DIRECTION) {} // Constructs a linear constraint SnapConstraint(Geom::Point const &p, Geom::Point const &d) : _point(p), _direction(d), _radius(0), _type(LINE) {} + // Orthogonal version + SnapConstraint(Geom::Point const &p, Geom::Dim2 const &d) : _point(p), _radius(0), _type(LINE) {_direction = Geom::Point(); _direction[d] = 1.;} SnapConstraint(Geom::Line const &l) : _point(l.origin()), _direction(l.versor()), _radius(0), _type(LINE) {} // Constructs a circular constraint SnapConstraint(Geom::Point const &p, Geom::Point const &d, Geom::Coord const &r) : _point(p), _direction(d), _radius(r), _type(CIRCLE) {} diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp index da2a54989..748b9d4cc 100644 --- a/src/ui/tool/transform-handle-set.cpp +++ b/src/ui/tool/transform-handle-set.cpp @@ -15,9 +15,11 @@ #include #include <2geom/transforms.h> #include "desktop.h" +#include "sp-namedview.h" #include "display/sodipodi-ctrlrect.h" #include "preferences.h" +#include "pure-transform.h" #include "snap.h" #include "snap-candidate.h" #include "sp-namedview.h" @@ -93,6 +95,7 @@ TransformHandle::TransformHandle(TransformHandleSet &th, SPAnchorType anchor, Gl setVisible(false); } +// TODO: This code is duplicated in seltrans.cpp; fix this! void TransformHandle::getNextClosestPoint(bool reverse) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -113,6 +116,11 @@ void TransformHandle::getNextClosestPoint(bool reverse) _snap_points.clear(); _snap_points.push_back(*_all_snap_sources_iter); + // Show the updated snap source now; otherwise it won't be shown until the selection is being moved again + SnapManager &m = _desktop->namedview->snap_manager; + m.setup(_desktop); + m.displaySnapsource(*_all_snap_sources_iter); + m.unSetup(); } } } @@ -247,7 +255,7 @@ protected: if (Geom::are_near(vold[Geom::X], 0) || Geom::are_near(vold[Geom::Y], 0)) return Geom::identity(); - double scale[2] = { vnew[Geom::X] / vold[Geom::X], vnew[Geom::Y] / vold[Geom::Y] }; + Geom::Scale scale = Geom::Scale(vnew[Geom::X] / vold[Geom::X], vnew[Geom::Y] / vold[Geom::Y]); if (held_alt(*event)) { for (unsigned i = 0; i < 2; ++i) { @@ -261,20 +269,21 @@ protected: SnapManager &m = _th._desktop->namedview->snap_manager; m.setupIgnoreSelection(_th._desktop, true, &_unselected_points); - Inkscape::SnappedPoint sp; + Inkscape::PureScale *ptr; if (held_control(*event)) { scale[0] = scale[1] = std::min(scale[0], scale[1]); - sp = m.constrainedSnapScale(_snap_points, _origin, Geom::Scale(scale[0], scale[1]), scc); + ptr = new Inkscape::PureScaleConstrained(Geom::Scale(scale[0], scale[1]), scc); } else { - sp = m.freeSnapScale(_snap_points, _origin, Geom::Scale(scale[0], scale[1]), scc); + ptr = new Inkscape::PureScale(Geom::Scale(scale[0], scale[1]), scc, false); } + m.snapTransformed(_snap_points, _origin, (*ptr)); m.unSetup(); - if (sp.getSnapped()) { - Geom::Point result = sp.getTransformation(); - scale[0] = result[0]; - scale[1] = result[1]; + if (ptr->best_snapped_point.getSnapped()) { + scale = ptr->getScaleSnapped(); } + + delete ptr; } _last_scale_x = scale[0]; @@ -349,11 +358,12 @@ protected: m.setupIgnoreSelection(_th._desktop, true, &_unselected_points); bool uniform = held_control(*event); - Inkscape::SnappedPoint sp = m.constrainedSnapStretch(_snap_points, _origin, vs[d1], scc, d1, uniform); + Inkscape::PureStretchConstrained psc = Inkscape::PureStretchConstrained(vs[d1], scc, d1, uniform); + m.snapTransformed(_snap_points, _origin, psc); m.unSetup(); - if (sp.getSnapped()) { - Geom::Point result = sp.getTransformation(); + if (psc.best_snapped_point.getSnapped()) { + Geom::Point result = psc.getStretchSnapped().vector(); //best_snapped_point.getTransformation(); vs[d1] = result[d1]; vs[d2] = result[d2]; } else { @@ -414,11 +424,12 @@ protected: } else { SnapManager &m = _th._desktop->namedview->snap_manager; m.setupIgnoreSelection(_th._desktop, true, &_unselected_points); - Inkscape::SnappedPoint sp = m.constrainedSnapRotate(_snap_points, _origin, angle, rotc); + Inkscape::PureRotateConstrained prc = Inkscape::PureRotateConstrained(angle, rotc); + m.snapTransformed(_snap_points, _origin, prc); m.unSetup(); - if (sp.getSnapped()) { - angle = sp.getTransformation()[0]; + if (prc.best_snapped_point.getSnapped()) { + angle = prc.getAngleSnapped(); //best_snapped_point.getTransformation()[0]; } } @@ -528,13 +539,12 @@ protected: SnapManager &m = _th._desktop->namedview->snap_manager; m.setupIgnoreSelection(_th._desktop, true, &_unselected_points); - Geom::Point cvec; cvec[d2] = 1.0; - Inkscape::Snapper::SnapConstraint const constraint(cvec); - Inkscape::SnappedPoint sp = m.constrainedSnapSkew(_snap_points, _origin, constraint, Geom::Point(skew[d1], scale[d1]), scc, d2); + Inkscape::PureSkewConstrained psc = Inkscape::PureSkewConstrained(skew[d1], scale[d1], scc, d2); + m.snapTransformed(_snap_points, _origin, psc); m.unSetup(); - if (sp.getSnapped()) { - skew[d1] = sp.getTransformation()[0]; + if (psc.best_snapped_point.getSnapped()) { + skew[d1] = psc.getSkewSnapped(); //best_snapped_point.getTransformation()[0]; } } -- cgit v1.2.3 From 82ca9953c316a91967aae392583310a4f6dec45d Mon Sep 17 00:00:00 2001 From: Mattia Rizzolo Date: Mon, 14 Sep 2015 17:08:31 +0000 Subject: Fix typo s/seperator/separator/ (bzr r14364.1.1) --- src/ui/interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index a129d4b92..d8dbd9452 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -872,7 +872,7 @@ static void sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, I // This was spelt wrong in the original version // and so this is for backward compatibility. It can // probably be dropped after the 0.44 release. - || !strcmp(menu_pntr->name(), "seperator")) { + || !strcmp(menu_pntr->name(), "separator")) { GtkWidget *item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); -- cgit v1.2.3 From edda99ec9d0d611a18631f6341c4c2e17b05d81b Mon Sep 17 00:00:00 2001 From: Mattia Rizzolo Date: Mon, 14 Sep 2015 17:11:44 +0000 Subject: Fix typo in a comment s/seperator/separator/ (bzr r14364.1.2) --- src/widgets/paint-selector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index 846ded511..d8d314834 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -972,7 +972,7 @@ ink_pattern_menu(GtkWidget *combo) } - // Select the first item that is not a seperator + // Select the first item that is not a separator if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL(store), &iter)) { gboolean sep = false; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, COMBO_COL_SEP, &sep, -1); -- cgit v1.2.3 From ce0673e204454338fd2850d9c97ff8d113da1ef7 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Tue, 15 Sep 2015 01:49:19 +0200 Subject: Fix for 1495106 (Add a check for id before sending a modified signal) Fixed bugs: - https://launchpad.net/bugs/1495106 (bzr r14367) --- src/document.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index d6a2e1b98..54e98b3e6 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1514,7 +1514,15 @@ bool SPDocument::addResource(gchar const *key, SPObject *object) g_hash_table_insert(priv->resources, (gpointer) key, rlist); GQuark q = g_quark_from_string(key); - priv->resources_changed_signals[q].emit(); + + /*do not send signal if the object has no id (yet), + it means the object is not completely built. + (happens when pasting swatches across documents, cf bug 1495106) + [this check should be more generally presend on emit() calls since + the backtrace is unusable with crashed from this cause] + */ + if(object->getId()) + priv->resources_changed_signals[q].emit(); result = true; } -- cgit v1.2.3 From 3005a32786badbc125628fd30f03ccdc32bb03d4 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 15 Sep 2015 12:13:14 +0200 Subject: Don't need bounding box if 'primitiveUnits' not 'objectBoundingBox'. (bzr r14368) --- src/display/nr-filter-primitive.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/display/nr-filter-primitive.cpp b/src/display/nr-filter-primitive.cpp index c8b569036..ea72efff0 100644 --- a/src/display/nr-filter-primitive.cpp +++ b/src/display/nr-filter-primitive.cpp @@ -110,17 +110,12 @@ void FilterPrimitive::set_subregion(SVGLength const &x, SVGLength const &y, Geom::Rect FilterPrimitive::filter_primitive_area(FilterUnits const &units) { - Geom::OptRect const bb_opt = units.get_item_bbox(); Geom::OptRect const fa_opt = units.get_filter_area(); - Geom::Rect bb; - Geom::Rect fa; - if (!bb_opt || !fa_opt) { + if (!fa_opt) { + std::cerr << "FilterPrimitive::filter_primitive_area: filter area undefined." << std::endl; return Geom::Rect (Geom::Point(0.,0.), Geom::Point(0.,0.)); - } else { - bb = *bb_opt; - fa = *fa_opt; } - + Geom::Rect fa = *fa_opt; // x, y, width, and height are independently defined (i.e. one can be defined, by default, to // the filter area (via default value ) while another is defined relative to the bounding @@ -138,6 +133,14 @@ Geom::Rect FilterPrimitive::filter_primitive_area(FilterUnits const &units) if( units.get_primitive_units() == SP_FILTER_UNITS_OBJECTBOUNDINGBOX ) { + Geom::OptRect const bb_opt = units.get_item_bbox(); + if (!bb_opt) { + std::cerr << "FilterPrimitive::filter_primitive_area: bounding box undefined and 'primitiveUnits' is 'objectBoundingBox'." << std::endl; + return Geom::Rect (Geom::Point(0.,0.), Geom::Point(0.,0.)); + } + Geom::Rect bb = *bb_opt; + + // Update computed values for ex, em, %. // For %, assumes primitive unit is objectBoundingBox. // TODO: fetch somehow the object ex and em lengths; 12, 6 are just dummy values. -- cgit v1.2.3 From cde4201fc0a5eed704bf7374300132e5ab9a0476 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Wed, 16 Sep 2015 20:22:07 +0200 Subject: fix for recent merge of ~mapreri/inkscape/typo (cf discussion at https://code.launchpad.net/~mapreri/inkscape/typo/+merge/270993 ) (bzr r14370) --- src/ui/interface.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index d8dbd9452..9a4e1d773 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -868,11 +868,7 @@ static void sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, I } continue; } - if (!strcmp(menu_pntr->name(), "separator") - // This was spelt wrong in the original version - // and so this is for backward compatibility. It can - // probably be dropped after the 0.44 release. - || !strcmp(menu_pntr->name(), "separator")) { + if (!strcmp(menu_pntr->name(), "separator")) { GtkWidget *item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); -- cgit v1.2.3 From ab9ef493fa3a752c5e16da7f3e187b4c00031442 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Thu, 17 Sep 2015 02:24:19 +0200 Subject: Added a pref option to disable "spacebar panning". (default:enabled) Fixed bugs: - https://launchpad.net/bugs/1401593 (bzr r14372) --- src/preferences-skeleton.h | 2 +- src/ui/dialog/inkscape-preferences.cpp | 8 +++----- src/ui/tools/tool-base.cpp | 9 ++++----- 3 files changed, 8 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index f4a08b928..b428cbe7a 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -269,7 +269,7 @@ static char const preferences_skeleton[] = " \n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 49864ccbb..14eaa65aa 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1250,11 +1250,9 @@ void InkscapePreferences::initPageBehavior() _scroll_auto_thres.init ( "/options/autoscrolldistance/value", -600.0, 600.0, 1.0, 1.0, -10.0, true, false); _page_scrolling.add_line( true, _("_Threshold:"), _scroll_auto_thres, _("pixels"), _("How far (in screen pixels) you need to be from the canvas edge to trigger autoscroll; positive is outside the canvas, negative is within the canvas"), false); -/* - _scroll_space.init ( _("Left mouse button pans when Space is pressed"), "/options/spacepans/value", false); - _page_scrolling.add_line( false, "", _scroll_space, "", - _("When on, pressing and holding Space and dragging with left mouse button pans canvas (as in Adobe Illustrator); when off, Space temporarily switches to Selector tool (default)")); -*/ + _scroll_space.init ( _("Mouse move pans when Space is pressed"), "/options/spacebarpans/value", true); + _page_scrolling.add_line( true, "", _scroll_space, "", + _("When on, pressing and holding Space and dragging pans canvas")); _wheel_zoom.init ( _("Mouse wheel zooms by default"), "/options/wheelzooms/value", false); _page_scrolling.add_line( false, "", _wheel_zoom, "", _("When on, mouse wheel zooms without Ctrl and scrolls canvas with Ctrl; when off, it zooms with Ctrl and scrolls without Ctrl")); diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 0f9b3ee7a..b5ffb9e7a 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -358,7 +358,7 @@ bool ToolBase::root_handler(GdkEvent* event) { /// @todo REmove redundant /value in preference keys tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); - + bool allow_panning = prefs->getBool("/options/spacebarpans/value"); gint ret = FALSE; switch (event->type) { @@ -582,7 +582,6 @@ bool ToolBase::root_handler(GdkEvent* event) { case GDK_KEY_PRESS: { double const acceleration = prefs->getDoubleLimited( "/options/scrollingacceleration/value", 0, 0, 6); - int const key_scroll = prefs->getIntLimited("/options/keyscroll/value", 10, 0, 1000); @@ -692,10 +691,10 @@ bool ToolBase::root_handler(GdkEvent* event) { break; case GDK_KEY_space: - xp = yp = 0; within_tolerance = true; + xp = yp = 0; + if (!allow_panning) break; panning = 4; - this->space_panning = true; this->message_context->set(Inkscape::INFORMATION_MESSAGE, _("Space+mouse move to pan canvas")); @@ -742,7 +741,7 @@ bool ToolBase::root_handler(GdkEvent* event) { switch (get_group0_keyval(&event->key)) { case GDK_KEY_space: - if (within_tolerance == true) { + if (within_tolerance || !allow_panning) { // Space was pressed, but not panned sp_toggle_selector(desktop); -- cgit v1.2.3 From 288eceeafde73ce1ad21a9f8c38d13072cb805be Mon Sep 17 00:00:00 2001 From: jtx Date: Thu, 17 Sep 2015 16:15:55 +0200 Subject: Improvements to transform by two knots pointed by Ivan Louette (bzr r14375) --- src/live_effects/lpe-transform_2pts.cpp | 76 ++++++++++++++++++++++++++++----- src/live_effects/lpe-transform_2pts.h | 4 ++ 2 files changed, 70 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 79ffd74de..8326bd6f1 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -19,7 +19,8 @@ #include "sp-path.h" #include "ui/icon-names.h" #include "svg/svg.h" - +#include "verbs.h" +// TODO due to internal breakage in glibmm headers, this must be last: #include namespace Inkscape { @@ -31,8 +32,12 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : from_original_width(_("From original width"), _("From original width"), "from_original_width", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), lock_lenght(_("Lock lenght"), _("Lock lenght to current distance"), "lock_lenght", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), lock_angle(_("Lock angle"), _("Lock angle"), "lock_angle", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + flip_horizontal(_("Flip horizontal"), _("Flip horizontal"), "flip_horizontal", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + flip_vertical(_("Flip vertical"), _("Flip vertical"), "flip_vertical", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), start(_("Start"), _("Start point"), "start", &wr, this, "Start point"), end(_("End"), _("End point"), "end", &wr, this, "End point"), + strech(_("Strech"), _("Strech the result"), "strech", &wr, this, 1), + offset(_("Offset"), _("Offset from knots"), "offset", &wr, this, 0), first_knot(_("First Knot"), _("First Knot"), "first_knot", &wr, this, 1), last_knot(_("Last Knot"), _("Last Knot"), "last_knot", &wr, this, 1), helper_size(_("Helper size:"), _("Rotation helper size"), "helper_size", &wr, this, 3), @@ -45,21 +50,34 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : previous_start(Geom::Point()), previous_lenght(-1) { - registerParameter(&start); - registerParameter(&end); + registerParameter(&first_knot); registerParameter(&last_knot); registerParameter(&helper_size); + registerParameter(&strech); + registerParameter(&offset); + registerParameter(&start); + registerParameter(&end); registerParameter(&elastic); registerParameter(&from_original_width); + registerParameter(&flip_vertical); + registerParameter(&flip_horizontal); registerParameter(&lock_lenght); registerParameter(&lock_angle); first_knot.param_make_integer(true); + first_knot.param_overwrite_widget(true); last_knot.param_make_integer(true); + last_knot.param_overwrite_widget(true); helper_size.param_set_range(0, 999); helper_size.param_set_increments(1, 1); helper_size.param_set_digits(0); + offset.param_set_range(-999999.0, 999999.0); + offset.param_set_increments(1, 1); + offset.param_set_digits(2); + strech.param_set_range(0, 999.0); + strech.param_set_increments(0.01, 0.01); + strech.param_set_digits(4); } LPETransform2Pts::~LPETransform2Pts() @@ -176,6 +194,7 @@ LPETransform2Pts::updateIndex() start.param_set_default(); end.param_set_default(); } + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change index of knot")); } //todo migrate to PathVector class? size_t @@ -259,6 +278,7 @@ Gtk::Widget *LPETransform2Pts::newWidget() Gtk::HBox * button1 = Gtk::manage(new Gtk::HBox(true,0)); Gtk::HBox * button2 = Gtk::manage(new Gtk::HBox(true,0)); Gtk::HBox * button3 = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::HBox * button4 = Gtk::manage(new Gtk::HBox(true,0)); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { Parameter *param = *it; @@ -292,7 +312,7 @@ Gtk::Widget *LPETransform2Pts::newWidget() widg->set_has_tooltip(false); } } - } else if (param->param_key == "lock_angle" || param->param_key == "lock_lenght") { + } else if (param->param_key == "flip_horizontal" || param->param_key == "flip_vertical") { Glib::ustring * tip = param->param_getTooltip(); if (widg) { button2->pack_start(*widg, true, true, 2); @@ -303,6 +323,17 @@ Gtk::Widget *LPETransform2Pts::newWidget() widg->set_has_tooltip(false); } } + } else if (param->param_key == "lock_angle" || param->param_key == "lock_lenght") { + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + button3->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } } else if (widg) { vbox->pack_start(*widg, true, true, 2); if (tip) { @@ -318,10 +349,11 @@ Gtk::Widget *LPETransform2Pts::newWidget() } Gtk::Button *reset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset")))); reset->signal_clicked().connect(sigc::mem_fun(*this, &LPETransform2Pts::reset)); - button3->pack_start(*reset, true, true, 2); + button4->pack_start(*reset, true, true, 2); vbox->pack_start(*button1, true, true, 2); vbox->pack_start(*button2, true, true, 2); vbox->pack_start(*button3, true, true, 2); + vbox->pack_start(*button4, true, true, 2); return dynamic_cast(vbox); } @@ -337,8 +369,26 @@ LPETransform2Pts::doEffect_pwd2 (Geom::Piecewise > const helper.start(point_a); helper.appendNew(point_b); Geom::Affine m; + Geom::Angle original_angle = original.angle(); + if(flip_horizontal && flip_vertical){ + m *= Geom::Rotate(-original_angle); + m *= Geom::Scale(-1,-1); + m *= Geom::Rotate(original_angle); + } else if(flip_vertical){ + m *= Geom::Rotate(-original_angle); + m *= Geom::Scale(1,-1); + m *= Geom::Rotate(original_angle); + } else if(flip_horizontal){ + m *= Geom::Rotate(-original_angle); + m *= Geom::Scale(-1,1); + m *= Geom::Rotate(original_angle); + } + if(strech != 1){ + m *= Geom::Rotate(-original_angle); + m *= Geom::Scale(1,strech); + m *= Geom::Rotate(original_angle); + } if(elastic) { - Geom::Angle original_angle = original.angle(); m *= Geom::Rotate(-original_angle); if(sca > 1){ m *= Geom::Scale(sca, 1.0); @@ -346,14 +396,20 @@ LPETransform2Pts::doEffect_pwd2 (Geom::Piecewise > const m *= Geom::Scale(sca, 1.0-((1.0-sca)/2.0)); } m *= Geom::Rotate(transformed.angle()); - helper *= m; - m *= Geom::Translate((Geom::Point)start - helper.initialPoint()); } else { m *= Geom::Scale(sca); m *= Geom::Rotate(rot); - helper *= m; - m *= Geom::Translate((Geom::Point)start - helper.initialPoint()); } + helper *= m; + Geom::Point trans = (Geom::Point)start - helper.initialPoint(); + if(flip_horizontal){ + trans = (Geom::Point)end - helper.initialPoint(); + } + if(offset != 0){ + trans = Geom::Point::polar(transformed.angle() + Geom::deg_to_rad(-90),offset) + trans; + } + m *= Geom::Translate(trans); + output.concat(pwd2_in * m); return output; diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index 947243c82..c20d56206 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -53,8 +53,12 @@ private: ToggleButtonParam from_original_width; ToggleButtonParam lock_lenght; ToggleButtonParam lock_angle; + ToggleButtonParam flip_horizontal; + ToggleButtonParam flip_vertical; PointParam start; PointParam end; + ScalarParam strech; + ScalarParam offset; ScalarParam first_knot; ScalarParam last_knot; ScalarParam helper_size; -- cgit v1.2.3 From 27ca90885f3f4dde9886780ff0cc0f40a34f4e7e Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 20 Sep 2015 15:54:59 +0200 Subject: Crude partial implementation of feTile filter primitive. (bzr r14377) --- src/display/nr-filter-image.cpp | 2 + src/display/nr-filter-offset.cpp | 4 +- src/display/nr-filter-slot.cpp | 21 +++++++++ src/display/nr-filter-slot.h | 8 ++++ src/display/nr-filter-tile.cpp | 99 ++++++++++++++++++++++++++++++++++++++-- src/display/nr-filter-tile.h | 1 + 6 files changed, 130 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp index 179ba0e0a..af89d98e0 100644 --- a/src/display/nr-filter-image.cpp +++ b/src/display/nr-filter-image.cpp @@ -56,6 +56,8 @@ void FilterImage::render_cairo(FilterSlot &slot) // Note: viewport calculation in non-trivial. Do not rely // on get_matrix_primitiveunits2pb(). Geom::Rect vp = filter_primitive_area( slot.get_units() ); + slot.set_primitive_area(_output, vp); // Needed for tiling + double feImageX = vp.min()[Geom::X]; double feImageY = vp.min()[Geom::Y]; double feImageWidth = vp.width(); diff --git a/src/display/nr-filter-offset.cpp b/src/display/nr-filter-offset.cpp index af1081abe..93bab7d39 100644 --- a/src/display/nr-filter-offset.cpp +++ b/src/display/nr-filter-offset.cpp @@ -37,9 +37,11 @@ void FilterOffset::render_cairo(FilterSlot &slot) cairo_surface_t *out = ink_cairo_surface_create_identical(in); // color_interpolation_filters for out same as in. See spec (DisplacementMap). copy_cairo_surface_ci(in, out); - cairo_t *ct = cairo_create(out); + Geom::Rect vp = filter_primitive_area( slot.get_units() ); + slot.set_primitive_area(_output, vp); // Needed for tiling + // Handle bounding box case double x = dx; double y = dy; diff --git a/src/display/nr-filter-slot.cpp b/src/display/nr-filter-slot.cpp index e4c2f048e..a6e0c5c4e 100644 --- a/src/display/nr-filter-slot.cpp +++ b/src/display/nr-filter-slot.cpp @@ -232,6 +232,27 @@ void FilterSlot::set(int slot_nr, cairo_surface_t *surface) _last_out = slot_nr; } +void FilterSlot::set_primitive_area(int slot_nr, Geom::Rect &area) +{ + if (slot_nr == NR_FILTER_SLOT_NOT_SET) + slot_nr = NR_FILTER_UNNAMED_SLOT; + + _primitiveAreas[slot_nr] = area; +} + +Geom::Rect FilterSlot::get_primitive_area(int slot_nr) +{ + if (slot_nr == NR_FILTER_SLOT_NOT_SET) + slot_nr = _last_out; + + PrimitiveAreaMap::iterator s = _primitiveAreas.find(slot_nr); + + if (s == _primitiveAreas.end()) { + return *(_units.get_filter_area()); + } + return s->second; +} + int FilterSlot::get_slot_count() { return _slots.size(); diff --git a/src/display/nr-filter-slot.h b/src/display/nr-filter-slot.h index 987dedfd1..166b2e718 100644 --- a/src/display/nr-filter-slot.h +++ b/src/display/nr-filter-slot.h @@ -54,6 +54,9 @@ public: cairo_surface_t *get_result(int slot_nr); + void set_primitive_area(int slot, Geom::Rect &area); + Geom::Rect get_primitive_area(int slot); + /** Returns the number of slots in use. */ int get_slot_count(); @@ -75,6 +78,11 @@ public: private: typedef std::map SlotMap; SlotMap _slots; + + // We need to keep track of the primitive area as this is needed in feTile + typedef std::map PrimitiveAreaMap; + PrimitiveAreaMap _primitiveAreas; + DrawingItem *_item; //Geom::Rect _source_bbox; ///< bounding box of source graphic surface diff --git a/src/display/nr-filter-tile.cpp b/src/display/nr-filter-tile.cpp index 93ca50210..913812828 100644 --- a/src/display/nr-filter-tile.cpp +++ b/src/display/nr-filter-tile.cpp @@ -10,6 +10,8 @@ */ #include + +#include "display/cairo-utils.h" #include "display/nr-filter-tile.h" #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" @@ -30,16 +32,105 @@ FilterTile::~FilterTile() void FilterTile::render_cairo(FilterSlot &slot) { + // FIX ME! static bool tile_warning = false; - -//IMPLEMENT ME! if (!tile_warning) { - g_warning("Renderer for feTile is not implemented."); + g_warning("Renderer for feTile has non-optimal implementation, expect slowness and bugs."); tile_warning = true; } + // Fixing isn't so easy as the Inkscape renderer breaks the canvas into "rendering" tiles for + // faster rendering. (The "rendering" tiles are not the same as the tiles in this primitive.) + // Only if the the feTile tile source falls inside the current "rendering" tile will the tile + // image be available. + + // This input source contains only the "rendering" tile. cairo_surface_t *in = slot.getcairo(_input); - slot.set(_output, in); + + // For debugging + // static int i = 0; + // ++i; + // std::stringstream filename; + // filename << "dump." << i << ".png"; + // cairo_surface_write_to_png( in, filename.str().c_str() ); + + // This is the feTile source area as determined by the input primitive area (see SVG spec). + Geom::Rect tile_area = slot.get_primitive_area(_input); + + if( tile_area.width() == 0.0 || tile_area.height() == 0.0 ) { + + slot.set(_output, in); + std::cerr << "FileTile::render_cairo: tile has zero width or height" << std::endl; + + } else { + + cairo_surface_t *out = ink_cairo_surface_create_identical(in); + // color_interpolation_filters for out same as in. + copy_cairo_surface_ci(in, out); + cairo_t *ct = cairo_create(out); + + // The rectangle of the "rendering" tile. + Geom::Rect sa = slot.get_slot_area(); + + Geom::Affine trans = slot.get_units().get_matrix_user2pb(); + + // Create feTile tile ---------------- + + // Get tile area in pixbuf units (tile transformed). + Geom::Rect tt = tile_area * trans; + + // Shift between "rendering" tile and feTile tile + Geom::Point shift = sa.min() - tt.min(); + + // Create feTile tile surface + cairo_surface_t *tile = cairo_surface_create_similar(in, cairo_surface_get_content(in), + tt.width(), tt.height()); + cairo_t *ct_tile = cairo_create(tile); + cairo_set_source_surface(ct_tile, in, shift[Geom::X], shift[Geom::Y]); + cairo_paint(ct_tile); + + // Paint tiles ------------------ + + // For debugging + // std::stringstream filename; + // filename << "tile." << i << ".png"; + // cairo_surface_write_to_png( tile, filename.str().c_str() ); + + // Determine number of feTile rows and columns + Geom::Rect pr = filter_primitive_area( slot.get_units() ); + int tile_cols = ceil( pr.width() / tile_area.width() ); + int tile_rows = ceil( pr.height() / tile_area.height() ); + + // Do tiling (TO DO: restrict to slot area.) + for( int col=0; col < tile_cols; ++col ) { + for( int row=0; row < tile_rows; ++row ) { + + Geom::Point offset( col*tile_area.width(), row*tile_area.height() ); + offset *= trans; + offset[Geom::X] -= trans[4]; + offset[Geom::Y] -= trans[5]; + + cairo_set_source_surface(ct, tile, offset[Geom::X], offset[Geom::Y]); + cairo_paint(ct); + } + } + slot.set(_output, out); + + // Clean up + cairo_destroy(ct); + cairo_surface_destroy(out); + cairo_destroy(ct_tile); + cairo_surface_destroy(tile); + } +} + +void FilterTile::area_enlarge(Geom::IntRect &area, Geom::Affine const &trans) +{ + // We need to enlarge enough to get tile source... we don't the area of the source tile in this + // function so we guess. This is VERY inefficient. + Geom::Point enlarge(200, 200); + enlarge *= trans; + area.expandBy( enlarge[Geom::X] < 100 ? 100: enlarge[Geom::X] ); } double FilterTile::complexity(Geom::Affine const &) diff --git a/src/display/nr-filter-tile.h b/src/display/nr-filter-tile.h index 29087f2d6..239ecff4b 100644 --- a/src/display/nr-filter-tile.h +++ b/src/display/nr-filter-tile.h @@ -26,6 +26,7 @@ public: virtual ~FilterTile(); virtual void render_cairo(FilterSlot &slot); + virtual void area_enlarge(Geom::IntRect &area, Geom::Affine const &trans); virtual double complexity(Geom::Affine const &ctm); }; -- cgit v1.2.3 From 6acb877a000ae9feaa38316bd6f69730cef3822d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 20 Sep 2015 15:57:16 +0200 Subject: Enable "Tile" filter primitive in Filters dialog. (bzr r14378) --- src/ui/dialog/filter-effects-dialog.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 1ff9e4a1b..22c8c76f2 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -2756,8 +2756,6 @@ FilterEffectsDialog::FilterEffectsDialog() _sizegroup = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL); _sizegroup->set_ignore_hidden(); - _add_primitive_type.remove_row(NR_FILTER_TILE); - // Initialize widget hierarchy #if WITH_GTKMM_3_0 Gtk::Paned* hpaned = Gtk::manage(new Gtk::Paned); @@ -2925,7 +2923,7 @@ void FilterEffectsDialog::init_settings_widgets() _settings->add_lightsource(); _settings->type(NR_FILTER_TILE); - _settings->add_notimplemented(); + _settings->add_no_params(); _settings->type(NR_FILTER_TURBULENCE); // _settings->add_checkbutton(false, SP_ATTR_STITCHTILES, _("Stitch Tiles"), "stitch", "noStitch"); @@ -3017,7 +3015,7 @@ void FilterEffectsDialog::update_primitive_infobox() break; case(NR_FILTER_TILE): _infobox_icon.set_from_icon_name("feTile-icon", Gtk::ICON_SIZE_DIALOG); - _infobox_desc.set_markup(_("The feTile filter primitive tiles a region with its input graphic")); + _infobox_desc.set_markup(_("The feTile filter primitive tiles a region with an input graphic. The source tile is defined by the filter primitive subregion of the input.")); break; case(NR_FILTER_TURBULENCE): _infobox_icon.set_from_icon_name("feTurbulence-icon", Gtk::ICON_SIZE_DIALOG); -- cgit v1.2.3 From 6d6a3649cacefa158228d884058347677fc6f51f Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 20 Sep 2015 20:01:28 +0200 Subject: fix regression observed on layer dialog (bzr r14379) --- src/document.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 54e98b3e6..c64bf3ed5 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1515,13 +1515,13 @@ bool SPDocument::addResource(gchar const *key, SPObject *object) GQuark q = g_quark_from_string(key); - /*do not send signal if the object has no id (yet), + /*in general, do not send signal if the object has no id (yet), it means the object is not completely built. (happens when pasting swatches across documents, cf bug 1495106) [this check should be more generally presend on emit() calls since the backtrace is unusable with crashed from this cause] */ - if(object->getId()) + if(object->getId() || dynamic_cast(object) ) priv->resources_changed_signals[q].emit(); result = true; -- cgit v1.2.3 From a1a178ce0e1550a8dc92585b90f0f93dd498833e Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Fri, 25 Sep 2015 18:11:37 +0200 Subject: UI. Fix for bug #1365405 (Scaling-Tool edit field for height not acting proportional). Fixed bugs: - https://launchpad.net/bugs/1365405 (bzr r14386) --- src/ui/dialog/transformation.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index 498ad7822..6049368f5 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -1170,6 +1170,9 @@ void Transformation::onReplaceMatrixToggled() void Transformation::onScaleProportionalToggled() { onScaleXValueChanged(); + if (_scalar_scale_vertical.setProgrammatically) { + _scalar_scale_vertical.setProgrammatically = false; + } } -- cgit v1.2.3 From 30db4c1056a5bd715c5a738e36acc0f59edf4c95 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Wed, 30 Sep 2015 02:28:58 +0200 Subject: Change command line PostScript export level to 3 (bug #1432310) (bzr r14389) --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 26c25af02..5393ddc6f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -212,7 +212,7 @@ static gboolean sp_export_id_only = FALSE; static gchar *sp_export_svg = NULL; static gchar *sp_export_ps = NULL; static gchar *sp_export_eps = NULL; -static gint sp_export_ps_level = 2; +static gint sp_export_ps_level = 3; static gchar *sp_export_pdf = NULL; static gchar *sp_export_pdf_version = NULL; static gchar *sp_export_emf = NULL; @@ -260,7 +260,7 @@ static void resetCommandlineGlobals() { sp_export_svg = NULL; sp_export_ps = NULL; sp_export_eps = NULL; - sp_export_ps_level = 2; + sp_export_ps_level = 3; sp_export_pdf = NULL; sp_export_pdf_version = NULL; sp_export_emf = NULL; @@ -405,7 +405,7 @@ struct poptOption options[] = { {"export-ps-level", 0, POPT_ARG_INT, &sp_export_ps_level, SP_ARG_EXPORT_PS_LEVEL, N_("Choose the PostScript Level used to export. Possible choices are" - " 2 (the default) and 3"), + " 2 and 3 (the default)"), N_("PS Level")}, {"export-pdf", 'A', -- cgit v1.2.3 From 10a193ebe2e0343bafe71e4a78603335ff1a70fb Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 2 Oct 2015 10:59:31 +0200 Subject: Use different method to find text to save when converting text to path. (Also has advantage of preserving lines.) Fixed bugs: - https://launchpad.net/bugs/1502013 (bzr r14390) --- src/path-chemistry.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 7bd5b6298..c71465782 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -474,7 +474,13 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) // Special treatment for text: convert each glyph to separate path, then group the paths Inkscape::XML::Node *g_repr = xml_doc->createElement("svg:g"); - Glib::ustring original_text; // To save original text of accessibility. + // Save original text for accessibility. + Glib::ustring original_text = sp_te_get_string_multiline( item, + te_get_layout(item)->begin(), + te_get_layout(item)->end() ); + if( original_text.size() > 0 ) { + g_repr->setAttribute("aria-label", original_text.c_str() ); + } g_repr->setAttribute("transform", item->getRepr()->attribute("transform")); /* Mask */ @@ -494,10 +500,8 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) item->style->write( SP_STYLE_FLAG_IFDIFF, item->parent ? item->parent->style : NULL); // TODO investigate posibility g_repr->setAttribute("style", style_str.c_str()); - Inkscape::Text::Layout::iterator iter = te_get_layout(item)->begin(); + Inkscape::Text::Layout::iterator iter = te_get_layout(item)->begin(); do { - original_text += (gunichar)te_get_layout(item)->characterAt( iter ); - Inkscape::Text::Layout::iterator iter_next = iter; iter_next.nextGlyph(); // iter_next is one glyph ahead from iter if (iter == iter_next) @@ -538,10 +542,6 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) g_repr->appendChild(p_repr); - // For accessibility, store original string - if( original_text.size() > 0 ) { - g_repr->setAttribute("aria-label", original_text.c_str() ); - } Inkscape::GC::release(p_repr); if (iter == te_get_layout(item)->end()) -- cgit v1.2.3 From 7acea8118f730927d041f26aae4e98f964fdda4f Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sat, 3 Oct 2015 00:16:13 +0200 Subject: Fixes some non-antisymmetrical sort function Fixed bugs: - https://launchpad.net/bugs/1502267 (bzr r14392) --- src/ui/dialog/align-and-distribute.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 882427912..6a9c3db6b 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -535,7 +535,7 @@ private : if (length_a != length_b) return (length_a > length_b); } // Last criteria: Sort according to the z-coordinate - return (a->isSiblingOf(b)); + return sp_item_repr_compare_position(a,b)<0; } virtual void on_button_click() -- cgit v1.2.3 From 8f1829c10ba3de26fc6f21be4ca74203d74c871f Mon Sep 17 00:00:00 2001 From: Riccardo Bernardini <> Date: Sat, 3 Oct 2015 08:14:44 +0200 Subject: Crash. Fix for Bug #1404934 (Crash when opening files (Glib::ConvertError exception)). Fixed bugs: - https://launchpad.net/bugs/1404934 (bzr r14393) --- src/resource-manager.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/resource-manager.cpp b/src/resource-manager.cpp index fe53eca4f..dbff27827 100644 --- a/src/resource-manager.cpp +++ b/src/resource-manager.cpp @@ -222,11 +222,15 @@ std::map ResourceManagerImpl::locateLinks(Glib::us Glib::ustring uri = (*it)->get_uri(); std::string scheme = Glib::uri_parse_scheme(uri); if ( scheme == "file" ) { - std::string path = Glib::filename_from_uri(uri); - path = Glib::path_get_dirname(path); - if ( std::find(priorLocations.begin(), priorLocations.end(), path) == priorLocations.end() ) { - // TODO debug g_message(" ==>[%s]", path.c_str()); - priorLocations.push_back(path); + try { + std::string path = Glib::filename_from_uri(uri); + path = Glib::path_get_dirname(path); + if ( std::find(priorLocations.begin(), priorLocations.end(), path) == priorLocations.end() ) { + // TODO debug g_message(" ==>[%s]", path.c_str()); + priorLocations.push_back(path); + } + } catch (Glib::ConvertError e) { + g_warning("Bad URL ignored [%s]", uri.c_str()); } } } -- cgit v1.2.3 From 8a5fcb84747766ff098bbc21080a24a74bce2973 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sat, 3 Oct 2015 16:09:07 +0200 Subject: Fix for r14372 bug Fixed bugs: - https://launchpad.net/bugs/1401593 (bzr r14394) --- src/ui/tools/tool-base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index b5ffb9e7a..bf7b61b61 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -741,7 +741,7 @@ bool ToolBase::root_handler(GdkEvent* event) { switch (get_group0_keyval(&event->key)) { case GDK_KEY_space: - if (within_tolerance || !allow_panning) { + if (within_tolerance) { // Space was pressed, but not panned sp_toggle_selector(desktop); -- cgit v1.2.3 From 6b61296109001d15cd1e2a43c38385b5fdba81c7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 4 Oct 2015 03:31:27 +0200 Subject: Add improvements to measure tool: more responsive add option to handle only active layer or all add a option to hide/show first and last segment add a option to compute only one global sice (bzr r14393.1.1) --- src/document.cpp | 20 +- src/document.h | 2 +- src/ui/tools/measure-tool.cpp | 731 ++++++++++++++++++++-------------------- src/ui/tools/measure-tool.h | 4 +- src/widgets/measure-toolbar.cpp | 36 ++ src/widgets/toolbox.cpp | 3 + 6 files changed, 426 insertions(+), 370 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index c64bf3ed5..97113cb25 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1450,7 +1450,7 @@ std::vector SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom: return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps); } -std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vector points) const +std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vector points, bool all_layers, size_t limit) const { std::vector items; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -1464,11 +1464,25 @@ std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vecto // Cache a flattened SVG DOM to speed up selection. std::deque nodes; build_flat_item_list(&nodes, key, SP_GROUP(this->root), true, false, NULL); - + SPObject *current_layer = SP_ACTIVE_DESKTOP->currentLayer(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::LayerModel *layer_model = NULL; + if(desktop){ + layer_model = desktop->layers; + } + size_t h = 0; for(int i = points.size()-1;i>=0; i--) { SPItem *item = find_item_at_point(&nodes, key, points[i]); if (item && items.end()==find(items.begin(),items.end(), item)) - items.push_back(item); + if(all_layers || (layer_model && layer_model->layerForObject(item) == current_layer)){ + items.push_back(item); + h++; + //limit 0 = no limit + if(h == limit){ + prefs->setDouble("/options/cursortolerance/value", saved_delta); + return items; + } + } } // and now we restore it back diff --git a/src/document.h b/src/document.h index dd1e295a2..be3f106d8 100644 --- a/src/document.h +++ b/src/document.h @@ -262,7 +262,7 @@ public: std::vector getItemsInBox(unsigned int dkey, Geom::Rect const &box) const; std::vector getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box) const; SPItem *getItemAtPoint(unsigned int key, Geom::Point const &p, bool into_groups, SPItem *upto = NULL) const; - std::vector getItemsAtPoints(unsigned const key, std::vector points) const; + std::vector getItemsAtPoints(unsigned const key, std::vector points, bool all_layers = true, size_t limit = 0) const; SPItem *getGroupAtPoint(unsigned int key, Geom::Point const &p) const; void changeUriAndHrefs(char const *uri); diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 570f3e796..aadc8790a 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -15,6 +15,7 @@ #include #include "util/units.h" #include "macros.h" +#include "rubberband.h" #include "display/curve.h" #include "sp-shape.h" #include "sp-text.h" @@ -296,22 +297,18 @@ static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom: } bool MeasureTool::root_handler(GdkEvent* event) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); - 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; + last_end = boost::none; start_point = desktop->w2d(button_w); if (event->button.button == 1 && !this->space_panning) { // save drag origin - xp = static_cast(event->button.x); - yp = static_cast(event->button.y); + start_point = desktop->w2d(Geom::Point(event->button.x, event->button.y)); within_tolerance = true; ret = TRUE; @@ -330,417 +327,423 @@ bool MeasureTool::root_handler(GdkEvent* event) { } case GDK_KEY_PRESS: { if ((event->key.keyval == GDK_KEY_Shift_L) || (event->key.keyval == GDK_KEY_Shift_R)) { - if (lastEnd) { - explicitBase = lastEnd; + if (last_end) { + explicitBase = last_end; } } break; } 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)); + if (!(event->motion.state & GDK_BUTTON1_MASK) && !(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); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); - Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE); - scp.addOrigin(start_point); + Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE); + scp.addOrigin(start_point); - m.preSnap(scp); - m.unSetup(); - } + m.preSnap(scp); + m.unSetup(); } else { ret = TRUE; - - if ( within_tolerance - && ( abs( static_cast(event->motion.x) - xp ) < tolerance ) - && ( abs( static_cast(event->motion.y) - yp ) < tolerance ) ) { - break; // do not drag if we're within tolerance from origin + 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_point ) < tolerance) { + return false; // 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]); - } - - measure_tmp_items.clear(); - - 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; - - 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(); - } + if(event->motion.time == 0 || !last_end || Geom::LInfty( motion_w - *last_end ) > (tolerance/2)){ + showCanvasItems(event->motion); + last_end = motion_w ; } + gobble_motion_events(GDK_BUTTON1_MASK); + } + break; + } + case GDK_BUTTON_RELEASE: { + sp_event_context_discard_delayed_snap_event(this); + explicitBase = boost::none; + last_end = boost::none; - Geom::PathVector lineseg; - Geom::Path p; - p.start(desktop->dt2doc(start_point)); - p.appendNew(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; + //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 (explicitBase) { - double deltax2 = explicitBase.get()[Geom::X] - start_point[Geom::X]; - double deltay2 = explicitBase.get()[Geom::Y] - start_point[Geom::Y]; + measure_tmp_items.clear(); - baseAngle = atan2(deltay2, deltax2); - angle -= baseAngle; + if (this->grabbed) { + sp_canvas_item_ungrab(this->grabbed, event->button.time); + this->grabbed = NULL; + } - if (angle < -M_PI) { - angle += 2 * M_PI; - } else if (angle > M_PI) { - angle -= 2 * M_PI; - } - } + start_point = Geom::Point(); + break; + } + default: + break; + } + if (!ret) { + ret = ToolBase::root_handler(event); + } + + return ret; +} -//TODO: calculate NPOINTS -//800 seems to be a good value for 800x600 resolution -#define NPOINTS 800 +void MeasureTool::showCanvasItems(GdkEventMotion const &mevent){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Geom::Point const motion_w(mevent.x, mevent.y); + bool show_in_between = prefs->getBool("/tools/measure/show_in_between"); + bool all_layers = prefs->getBool("/tools/measure/all_layers"); + //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]); + } - std::vector points; + measure_tmp_items.clear(); + Geom::Point const motion_dt(desktop->w2d(motion_w)); + Geom::Point end_point = motion_dt; - for (double i = 0; i < NPOINTS; i++) { - points.push_back(desktop->d2w(start_point + (i / NPOINTS) * (end_point - start_point))); - } + if (mevent.state & GDK_CONTROL_MASK) { + spdc_endpoint_snap_rotation(this, end_point, start_point, mevent.state); + } else { + if (!(mevent.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(); + } + } - // 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 items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, points); - std::vector intersection_times; - for (std::vector::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); - } - } - } + Geom::PathVector lineseg; + Geom::Path p; + p.start(desktop->dt2doc(start_point)); + p.appendNew(desktop->dt2doc(end_point)); + lineseg.push_back(p); - 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); - } + 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; - Glib::ustring unit_name = prefs->getString("/tools/measure/unit"); - if (!unit_name.compare("")) { - unit_name = "px"; - } + if (explicitBase) { + double deltax2 = explicitBase.get()[Geom::X] - start_point[Geom::X]; + double deltay2 = explicitBase.get()[Geom::Y] - start_point[Geom::Y]; - double fontsize = prefs->getInt("/tools/measure/fontsize"); + baseAngle = atan2(deltay2, deltax2); + angle -= baseAngle; - // 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); + if (angle < -M_PI) { + angle += 2 * M_PI; + } else if (angle > M_PI) { + angle -= 2 * M_PI; + } + } + std::vector items; + Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop); + r->setMode(RUBBERBAND_MODE_TOUCHPATH); + if(!show_in_between){ + r->start(desktop,start_point); + r->move(end_point); + items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints(), all_layers, 2); + r->stop(); + r->setMode(RUBBERBAND_MODE_TOUCHPATH); + r->start(desktop,end_point); + r->move(start_point); + std::vector items_reverse = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints(), all_layers, 2); + r->stop(); + if(items_reverse.size() == 2){ + items.push_back(items_reverse[1]); + } + if(items_reverse.size() >= 1){ + items.push_back(items_reverse[0]); + } + } else { + r->start(desktop,start_point); + r->move(end_point); + items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints(), all_layers); + r->stop(); + } + std::vector intersection_times; + for (std::vector::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; + } - std::vector intersections; - std::sort(intersection_times.begin(), intersection_times.end()); - for (std::vector::iterator iter_t = intersection_times.begin(); iter_t != intersection_times.end(); iter_t++) { - intersections.push_back(lineseg[0].pointAt(*iter_t)); - } + // 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; + } - std::vector 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); + curve->transform(item->i2doc_affine()); - placements.push_back(placement); - } + 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"; + } - // Adjust positions - repositionOverlappingLabels(placements, desktop, windowNormal, fontsize); - - for (std::vector::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); - } + double fontsize = prefs->getInt("/tools/measure/fontsize"); - 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); - } + // 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); - { - 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); - } + std::vector intersections; + std::sort(intersection_times.begin(), intersection_times.end()); + for (std::vector::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 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); + + placements.push_back(placement); + } - 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); - } + // Adjust positions + repositionOverlappingLabels(placements, desktop, windowNormal, fontsize); + for (std::vector::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); + } - // 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)); - } + Geom::Point angleDisplayPt = calcAngleDisplayAnchor(desktop, angle, baseAngle, + start_point, end_point, + fontsize); - // 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); - } - } + { + // 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); + } - 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)); - } + { + 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); + } - // call-out lines - for (std::vector::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)); - } + 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); + } - { - for (size_t idx = 1; idx < intersections.size(); ++idx) { - Geom::Point measure_text_pos = (intersections[idx - 1] + intersections[idx]) / 2; + // 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)); + } - 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)); - } - } + // Since adding goes to the bottom, do all lines last. - // 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)); - } + // 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))); + } - lastEnd = end_point; // track in case we get a anchoring key-press later + 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)); - gobble_motion_events(GDK_BUTTON1_MASK); - } - break; + createAngleDisplayCurve(desktop, start_point, end_point, angleDisplayPt, angle); } - 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]); - } + } - measure_tmp_items.clear(); + 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)); + } - if (this->grabbed) { - sp_canvas_item_ungrab(this->grabbed, event->button.time); - this->grabbed = NULL; - } + // call-out lines + for (std::vector::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)); + } - xp = 0; - yp = 0; - break; + { + for (size_t idx = 1; idx < intersections.size(); ++idx) { + Geom::Point measure_text_pos = (intersections[idx - 1] + intersections[idx]) / 2; + + 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)); } - default: - break; } - if (!ret) { - ret = ToolBase::root_handler(event); + // 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)); } - - return ret; } - } } } diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index 9701ba6ea..4673e0f0a 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -32,15 +32,15 @@ public: virtual void finish(); virtual bool root_handler(GdkEvent* event); + virtual void showCanvasItems(GdkEventMotion const &event); virtual const std::string& getPrefsPath(); private: SPCanvasItem* grabbed; - Geom::Point start_point; boost::optional explicitBase; - boost::optional lastEnd; + boost::optional last_end; }; } diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 5a4785b1f..ca79b5792 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -38,6 +38,8 @@ #include "widgets/ege-output-action.h" #include "preferences.h" #include "toolbox.h" +#include "widgets/ink-action.h" +#include "ui/icon-names.h" #include "ui/widget/unit-tracker.h" using Inkscape::UI::Widget::UnitTracker; @@ -79,6 +81,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_object_set_data( holder, "tracker", tracker ); EgeAdjustmentAction *eact = 0; + Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); /* Font Size */ { @@ -108,6 +111,39 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(measure_unit_changed), holder ); gtk_action_group_add_action( mainActions, act ); } + // ignore_1st_and_last + { + InkToggleAction* act = ink_toggle_action_new( "MeasureIgnore1stAndLast", + _("Ignore first and last"), + _("Ignore first and last"), + INKSCAPE_ICON("draw-geometry-line-segment"), + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/measure/ignore_1st_and_last"); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + } + // measure imbetweens + { + InkToggleAction* act = ink_toggle_action_new( "MeasureInBettween", + _("Show meassures between items"), + _("Show meassures between items"), + INKSCAPE_ICON("distribute-randomize"), + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/measure/show_in_between"); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + } + // measure only current layer + { + InkToggleAction* act = ink_toggle_action_new( "MeasureAllLayers", + _("Measure all layers"), + _("Measure all layers"), + INKSCAPE_ICON("dialog-layers"), + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/measure/all_layers"); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + } } // end of sp_measure_toolbox_prep() diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index cdf39e9ef..ba02adb92 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -341,6 +341,9 @@ static gchar const * ui_descr = " " " " " " + " " + " " + " " " " " " -- cgit v1.2.3 From 478e6969f70a62349396fa4e57e3c63b5811c165 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 4 Oct 2015 10:16:46 +0200 Subject: Protect against a NULL value for 'font-feature-settings'. "Fixes" #1502432. Fixed bugs: - https://launchpad.net/bugs/1502432 (bzr r14395) --- src/style.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/style.cpp b/src/style.cpp index d8402e08a..0cb5db0a7 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -1258,7 +1258,7 @@ SPStyle::getFontFeatureString() { if( font_variant_east_asian.value & SP_CSS_FONT_VARIANT_EAST_ASIAN_RUBY ) feature_string += "ruby, "; - if ( strcmp( font_feature_settings.value, "normal") ) { + if ( font_feature_settings.value && strcmp( font_feature_settings.value, "normal") ) { // We do no sanity checking... feature_string += font_feature_settings.value; feature_string += ", "; -- cgit v1.2.3 From 4ebb09cb87a2f082f505e774f33c1f6d24fdf26d Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 4 Oct 2015 17:42:12 +0200 Subject: Fixes clonetiler trace mode on non-px documents Fixed bugs: - https://launchpad.net/bugs/1502521 (bzr r14396) --- src/ui/dialog/clonetiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index f84a2ffd6..da1c6d9fb 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -2479,7 +2479,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) // Trace tab if (dotrace) { - Geom::Rect bbox_t = transform_rect (bbox_original, t); + Geom::Rect bbox_t = transform_rect (bbox_original, t*Geom::Scale(1.0/scale_units)); guint32 rgba = clonetiler_trace_pick (bbox_t); float r = SP_RGBA32_R_F(rgba); -- cgit v1.2.3 From bd4a5a52a3aae4a9c871a9ea766ab490a5e25d84 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 4 Oct 2015 20:15:20 +0200 Subject: Added knots to post editing the measure and make it persistant throught tools (bzr r14393.1.3) --- src/ui/tools/measure-tool.cpp | 139 ++++++++++++++++++++++++++++-------------- src/ui/tools/measure-tool.h | 30 ++++++--- 2 files changed, 114 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index aadc8790a..142c04fc3 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -30,7 +30,7 @@ #include "pixmaps/cursor-measure.xpm" #include "preferences.h" #include "inkscape.h" - +#include "knot.h" #include "ui/tools/measure-tool.h" #include "ui/tools/freehand-base.h" #include "display/canvas-text.h" @@ -45,11 +45,15 @@ #include "enums.h" #include "ui/control-manager.h" #include "knot-enums.h" +#include using Inkscape::ControlManager; using Inkscape::CTLINE_SECONDARY; using Inkscape::Util::unit_table; +#define MT_KNOT_COLOR_NORMAL 0xffffff00 +#define MT_KNOT_COLOR_MOUSEOVER 0xff000000 + namespace Inkscape { namespace UI { namespace Tools { @@ -57,7 +61,7 @@ namespace Tools { std::vector measure_tmp_items; const std::string& MeasureTool::getPrefsPath() { - return MeasureTool::prefsPath; + return MeasureTool::prefsPath; } const std::string MeasureTool::prefsPath = "/tools/measure"; @@ -227,14 +231,61 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom } // namespace - +static Geom::Point start_p = Geom::Point(); +static Geom::Point end_p = Geom::Point(); MeasureTool::MeasureTool() : ToolBase(cursor_measure_xpm, 4, 4) , grabbed(NULL) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + // create the knot + 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(); + if(end_p != Geom::Point()){ + this->knot_start->setPosition(start_p, SP_KNOT_STATE_NORMAL); + this->knot_start->show(); + this->knot_end->setPosition(end_p, SP_KNOT_STATE_NORMAL); + this->knot_end->show(); + this->showCanvasItems(this->knot_start->position(), this->knot_end->position()); + } + this->_knot_start_moved_connection = this->knot_start->moved_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotMovedHandler)); + 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::knotMovedHandler)); + this->_knot_end_ungrabbed_connection = this->knot_end->ungrabbed_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotUngrabbedHandler)); + } 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::knotMovedHandler(SPKnot */*knot*/, Geom::Point const /*&ppointer*/, guint /*state*/){ + showCanvasItems(this->knot_start->position(), this->knot_end->position()); +} + +void MeasureTool::knotUngrabbedHandler(SPKnot */*knot*/, unsigned int /*state*/){ + showCanvasItems(this->knot_start->position(), this->knot_end->position()); } void MeasureTool::finish() { @@ -249,12 +300,12 @@ void MeasureTool::finish() { } //void MeasureTool::setup() { -// ToolBase* ec = this; +// 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(); +// ToolBase::setup(); //} //gint MeasureTool::item_handler(SPItem* item, GdkEvent* event) { @@ -301,6 +352,8 @@ bool MeasureTool::root_handler(GdkEvent* event) { switch (event->type) { 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; @@ -353,7 +406,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { Geom::Point const motion_w(event->motion.x, event->motion.y); if ( within_tolerance){ if ( Geom::LInfty( motion_w - start_point ) < tolerance) { - return false; // Do not drag if we're within tolerance from origin. + return FALSE; // Do not drag if we're within tolerance from origin. } } // Once the user has moved farther than tolerance from the original location @@ -361,7 +414,24 @@ bool MeasureTool::root_handler(GdkEvent* event) { // 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/2)){ - showCanvasItems(event->motion); + 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; + + 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(); + } + } + showCanvasItems(start_point, end_point); last_end = motion_w ; } gobble_motion_events(GDK_BUTTON1_MASK); @@ -369,63 +439,42 @@ bool MeasureTool::root_handler(GdkEvent* event) { break; } case GDK_BUTTON_RELEASE: { - sp_event_context_discard_delayed_snap_event(this); - explicitBase = boost::none; - last_end = 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]); + this->knot_start->setPosition(start_point, SP_KNOT_STATE_NORMAL); + this->knot_start->show(); + if(last_end){ + Geom::Point end_point = desktop->w2d(*last_end); + this->knot_end->setPosition(end_point, SP_KNOT_STATE_NORMAL); + this->knot_end->show(); } - - measure_tmp_items.clear(); - if (this->grabbed) { sp_canvas_item_ungrab(this->grabbed, event->button.time); this->grabbed = NULL; } - - start_point = Geom::Point(); + sp_event_context_discard_delayed_snap_event(this); break; } default: break; } if (!ret) { - ret = ToolBase::root_handler(event); + ret = ToolBase::root_handler(event); } return ret; } -void MeasureTool::showCanvasItems(GdkEventMotion const &mevent){ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Geom::Point const motion_w(mevent.x, mevent.y); - bool show_in_between = prefs->getBool("/tools/measure/show_in_between"); - bool all_layers = prefs->getBool("/tools/measure/all_layers"); +void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point){ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + start_p = start_point; + end_p = end_point; //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(); - Geom::Point const motion_dt(desktop->w2d(motion_w)); - Geom::Point end_point = motion_dt; - - if (mevent.state & GDK_CONTROL_MASK) { - spdc_endpoint_snap_rotation(this, end_point, start_point, mevent.state); - } else { - if (!(mevent.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(); - } - } - + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool show_in_between = prefs->getBool("/tools/measure/show_in_between"); + bool all_layers = prefs->getBool("/tools/measure/all_layers"); Geom::PathVector lineseg; Geom::Path p; p.start(desktop->dt2doc(start_point)); @@ -463,10 +512,10 @@ void MeasureTool::showCanvasItems(GdkEventMotion const &mevent){ r->move(start_point); std::vector items_reverse = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints(), all_layers, 2); r->stop(); - if(items_reverse.size() == 2){ + 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){ + if(items_reverse.size() >= 1 && items_reverse[0] != items[1]){ items.push_back(items_reverse[0]); } } else { diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index 4673e0f0a..8a1eb2203 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -11,7 +11,8 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - +#include +#include #include "ui/tools/tool-base.h" #include <2geom/point.h> #include @@ -19,28 +20,37 @@ #define SP_MEASURE_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) #define SP_IS_MEASURE_CONTEXT(obj) (dynamic_cast((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); - virtual void showCanvasItems(GdkEventMotion const &event); + static const std::string prefsPath; - virtual const std::string& getPrefsPath(); + virtual void finish(); + virtual bool root_handler(GdkEvent* event); + virtual void showCanvasItems(Geom::Point start_point, Geom::Point end_point); + virtual const std::string& getPrefsPath(); + void knotMovedHandler(SPKnot */*knot*/, Geom::Point const /*&ppointer*/, guint /*state*/); + void knotUngrabbedHandler(SPKnot */*knot*/, unsigned int /*state*/); private: - SPCanvasItem* grabbed; + SPCanvasItem* grabbed; Geom::Point start_point; boost::optional explicitBase; boost::optional last_end; + SPKnot *knot_start; + SPKnot *knot_end; + sigc::connection _knot_start_moved_connection; + sigc::connection _knot_start_ungrabbed_connection; + sigc::connection _knot_end_moved_connection; + sigc::connection _knot_end_ungrabbed_connection; }; } -- cgit v1.2.3 From ef0299883a7bc9402c96856eeebba118ef7f49c8 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 4 Oct 2015 20:33:00 +0200 Subject: Add snap and CTRL constrain (bzr r14393.1.5) --- src/ui/tools/measure-tool.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 142c04fc3..5521dd6e8 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -420,16 +420,14 @@ bool MeasureTool::root_handler(GdkEvent* event) { 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(); - } + } 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(); } showCanvasItems(start_point, end_point); last_end = motion_w ; @@ -443,6 +441,17 @@ bool MeasureTool::root_handler(GdkEvent* event) { this->knot_start->show(); if(last_end){ Geom::Point end_point = desktop->w2d(*last_end); + if (event->button.state & GDK_CONTROL_MASK) { + spdc_endpoint_snap_rotation(this, end_point, start_point, event->motion.state); + } else if (!(event->button.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(); + } this->knot_end->setPosition(end_point, SP_KNOT_STATE_NORMAL); this->knot_end->show(); } -- cgit v1.2.3 From 88f15a973fc593be36a423864526c7e064bf3dd3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 5 Oct 2015 19:30:47 +0200 Subject: Add redraw to meassure when use toolbar (bzr r14393.1.6) --- src/ui/tools/measure-tool.cpp | 6 ++- src/ui/tools/measure-tool.h | 1 + src/widgets/measure-toolbar.cpp | 99 ++++++++++++++++++++++++++++++++++++----- 3 files changed, 94 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 5521dd6e8..c275a6d79 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -256,7 +256,7 @@ MeasureTool::MeasureTool() this->knot_start->show(); this->knot_end->setPosition(end_p, SP_KNOT_STATE_NORMAL); this->knot_end->show(); - this->showCanvasItems(this->knot_start->position(), this->knot_end->position()); + this->showCanvasItems(); } this->_knot_start_moved_connection = this->knot_start->moved_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotMovedHandler)); this->_knot_start_ungrabbed_connection = this->knot_start->ungrabbed_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotUngrabbedHandler)); @@ -472,6 +472,10 @@ bool MeasureTool::root_handler(GdkEvent* event) { return ret; } +void MeasureTool::showCanvasItems(){ + showCanvasItems(start_p, end_p); +} + void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point){ SPDesktop *desktop = SP_ACTIVE_DESKTOP; start_p = start_point; diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index 8a1eb2203..412de8b72 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -35,6 +35,7 @@ public: virtual void finish(); virtual bool root_handler(GdkEvent* event); + virtual void showCanvasItems(); virtual void showCanvasItems(Geom::Point start_point, Geom::Point end_point); virtual const std::string& getPrefsPath(); void knotMovedHandler(SPKnot */*knot*/, Geom::Point const /*&ppointer*/, guint /*state*/); diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index ca79b5792..e3536b6a7 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -33,6 +33,8 @@ #include "measure-toolbar.h" #include "desktop.h" +#include "inkscape.h" +#include "message-stack.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" #include "widgets/ege-output-action.h" @@ -40,6 +42,7 @@ #include "toolbox.h" #include "widgets/ink-action.h" #include "ui/icon-names.h" +#include "ui/tools/measure-tool.h" #include "ui/widget/unit-tracker.h" using Inkscape::UI::Widget::UnitTracker; @@ -47,11 +50,26 @@ using Inkscape::Util::Unit; using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; using Inkscape::UI::PrefPusher; +using Inkscape::UI::Tools::MeasureTool; //######################## //## Measure Toolbox ## //######################## +/** Temporary hack: Returns the node tool in the active desktop. + * Will go away during tool refactoring. */ +static MeasureTool *get_measure_tool() +{ + MeasureTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (SP_IS_MEASURE_CONTEXT(ec)) { + tool = static_cast(ec); + } + } + return tool; +} + static void sp_measure_fontsize_value_changed(GtkAdjustment *adj, GObject *tbl) { @@ -61,6 +79,10 @@ sp_measure_fontsize_value_changed(GtkAdjustment *adj, GObject *tbl) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setInt(Glib::ustring("/tools/measure/fontsize"), gtk_adjustment_get_value(adj)); + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } } } @@ -70,6 +92,61 @@ static void measure_unit_changed(GtkAction* /*act*/, GObject* tbl) Glib::ustring const unit = tracker->getActiveUnit()->abbr; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setString("/tools/measure/unit", unit); + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } +} + +static void toggle_ignore_1st_and_last( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setInt("/tools/measure/ignore_1st_and_last", active); + SPDesktop *desktop = static_cast(data); + if ( active ) { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Start and end measures inactive.")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Start and end measures active.")); + } + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } +} + +static void toggle_all_layers( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setInt("/tools/measure/all_layers", active); + SPDesktop *desktop = static_cast(data); + if ( active ) { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Use all layers in the measure.")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Use current layer in the measure.")); + } + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } +} + +static void toggle_show_in_between( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setInt("/tools/measure/show_in_between", active); + SPDesktop *desktop = static_cast(data); + if ( active ) { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Compute all elements.")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Compute max lenght.")); + } + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } } void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* holder) @@ -118,20 +195,20 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G _("Ignore first and last"), INKSCAPE_ICON("draw-geometry-line-segment"), secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/measure/ignore_1st_and_last"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/ignore_1st_and_last", true) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_ignore_1st_and_last), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } // measure imbetweens { InkToggleAction* act = ink_toggle_action_new( "MeasureInBettween", - _("Show meassures between items"), - _("Show meassures between items"), + _("Show measures between items"), + _("Show measures between items"), INKSCAPE_ICON("distribute-randomize"), secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/measure/show_in_between"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/show_in_between", true) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_show_in_between), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } // measure only current layer { @@ -140,9 +217,9 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G _("Measure all layers"), INKSCAPE_ICON("dialog-layers"), secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/measure/all_layers"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/all_layers", true) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_all_layers), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } } // end of sp_measure_toolbox_prep() -- cgit v1.2.3 From ae0a08f8986529a81c7bd239c7cde548c8bdacc3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 5 Oct 2015 20:13:58 +0200 Subject: add reverse to meassure output (bzr r14393.1.8) --- src/ui/tools/measure-tool.cpp | 10 ++++++++++ src/ui/tools/measure-tool.h | 1 + src/widgets/measure-toolbar.cpp | 17 ++++++++++++++++- src/widgets/toolbox.cpp | 1 + 4 files changed, 28 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index c275a6d79..8d838fc06 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -280,6 +280,16 @@ MeasureTool::~MeasureTool() { measure_tmp_items.clear(); } +void MeasureTool::reverseKnots(){ + Geom::Point start = start_p; + Geom::Point end = end_p; + this->knot_start->setPosition(end, SP_KNOT_STATE_NORMAL); + this->knot_start->show(); + this->knot_end->setPosition(start, SP_KNOT_STATE_NORMAL); + this->knot_end->show(); + this->showCanvasItems(end, start); +} + void MeasureTool::knotMovedHandler(SPKnot */*knot*/, Geom::Point const /*&ppointer*/, guint /*state*/){ showCanvasItems(this->knot_start->position(), this->knot_end->position()); } diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index 412de8b72..944b14ed8 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -37,6 +37,7 @@ public: virtual bool root_handler(GdkEvent* event); virtual void showCanvasItems(); virtual void showCanvasItems(Geom::Point start_point, Geom::Point end_point); + virtual void reverseKnots(); virtual const std::string& getPrefsPath(); void knotMovedHandler(SPKnot */*knot*/, Geom::Point const /*&ppointer*/, guint /*state*/); void knotUngrabbedHandler(SPKnot */*knot*/, unsigned int /*state*/); diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index e3536b6a7..5abd099d6 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -148,7 +148,12 @@ static void toggle_show_in_between( GtkToggleAction* act, gpointer data ) mt->showCanvasItems(); } } - +static void sp_reverse_knots(void){ + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->reverseKnots(); + } +} void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* holder) { UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); @@ -221,6 +226,16 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_all_layers), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } + //toogle start end + { + InkAction* act = ink_action_new( "MeasureReverse", + _("Reverse measure"), + _("Reverse measure"), + INKSCAPE_ICON("draw-geometry-mirror"), + secondarySize ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_reverse_knots), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } } // end of sp_measure_toolbox_prep() diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index ba02adb92..769829313 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -344,6 +344,7 @@ static gchar const * ui_descr = " " " " " " + " " " " " " -- cgit v1.2.3 From 8db12376ba038c323068c14955fac45f00fcb0e6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 6 Oct 2015 18:34:19 +0200 Subject: add snaping to knots and stating convert measure to items (bzr r14393.1.9) --- src/ui/tools/measure-tool.cpp | 148 +++++++++++++++++++++++++++++++++++++--- src/ui/tools/measure-tool.h | 7 +- src/widgets/measure-toolbar.cpp | 18 +++++ src/widgets/toolbox.cpp | 1 + 4 files changed, 162 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 8d838fc06..2a89189dd 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -17,15 +17,13 @@ #include "macros.h" #include "rubberband.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-canvas-item.h" #include "display/sp-canvas-util.h" #include "desktop.h" +#include "svg/svg.h" #include "document.h" #include "pixmaps/cursor-measure.xpm" #include "preferences.h" @@ -42,6 +40,10 @@ #include <2geom/angle.h> #include "snap.h" #include "sp-namedview.h" +#include "sp-shape.h" +#include "sp-text.h" +#include "sp-flowtext.h" +#include "sp-defs.h" #include "enums.h" #include "ui/control-manager.h" #include "knot-enums.h" @@ -258,9 +260,9 @@ MeasureTool::MeasureTool() this->knot_end->show(); this->showCanvasItems(); } - this->_knot_start_moved_connection = this->knot_start->moved_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotMovedHandler)); + 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::knotMovedHandler)); + 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)); } @@ -290,14 +292,44 @@ void MeasureTool::reverseKnots(){ this->showCanvasItems(end, start); } -void MeasureTool::knotMovedHandler(SPKnot */*knot*/, Geom::Point const /*&ppointer*/, guint /*state*/){ - showCanvasItems(this->knot_start->position(), this->knot_end->position()); +void MeasureTool::knotStartMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state){ + if (!(state & GDK_SHIFT_MASK)) { + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); + Inkscape::SnapCandidatePoint scp(ppointer, Inkscape::SNAPSOURCE_OTHER_HANDLE); + scp.addOrigin(end_p); + Inkscape::SnappedPoint sp = m.freeSnap(scp); + if(start_p != sp.getPoint()){ + start_p = sp.getPoint(); + this->knot_end->setPosition(start_p, SP_KNOT_STATE_MOUSEOVER); + } + m.unSetup(); + } + showCanvasItems(start_point, this->knot_end->position()); +} + +void MeasureTool::knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state){ + if (!(state & GDK_SHIFT_MASK)) { + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); + Inkscape::SnapCandidatePoint scp(ppointer, Inkscape::SNAPSOURCE_OTHER_HANDLE); + scp.addOrigin(start_p); + Inkscape::SnappedPoint sp = m.freeSnap(scp); + if(end_p != sp.getPoint()){ + end_p = sp.getPoint(); + this->knot_end->setPosition(end_p, SP_KNOT_STATE_MOUSEOVER); + } + m.unSetup(); + } + showCanvasItems(this->knot_start->position(), end_p); } -void MeasureTool::knotUngrabbedHandler(SPKnot */*knot*/, unsigned int /*state*/){ - showCanvasItems(this->knot_start->position(), this->knot_end->position()); +void MeasureTool::knotUngrabbedHandler(SPKnot */*knot*/, unsigned int state){ + showCanvasItems(this->knot_start->position(), end_p); } + + void MeasureTool::finish() { this->enableGrDrag(false); @@ -482,6 +514,100 @@ bool MeasureTool::root_handler(GdkEvent* event) { return ret; } +void MeasureTool::setMarkers(){ + SPDesktop *desktop = this->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 = this->desktop; + SPDocument *doc = desktop->getDocument(); + SPDefs *defs = doc->getDefs(); + Inkscape::XML::Node *repr; + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + repr = xml_doc->createElement("svg:marker"); + if(isStart){ + repr->setAttribute("id", "Arrow2Sstart"); + } else { + repr->setAttribute("id", "Arrow2Send"); + } + repr->setAttribute("inkscape:isstock", "true"); + if(isStart){ + repr->setAttribute("inkscape:stockid", "Arrow2Sstart"); + } else { + repr->setAttribute("inkscape:stockid", "Arrow2Send"); + } + repr->setAttribute("orient", "auto"); + repr->setAttribute("refX", "0.0"); + repr->setAttribute("refY", "0.0"); + repr->setAttribute("style", "overflow:visible;"); + SPItem *item = SP_ITEM(defs->appendChildRepr(repr)); + Inkscape::GC::release(repr); + item->updateRepr(); + Inkscape::XML::Node *repr2; + repr2 = xml_doc->createElement("svg:path"); + repr2->setAttribute("d", "M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z"); + if(isStart){ + repr2->setAttribute("id", "Arrow2SstartPath"); + } else { + repr2->setAttribute("id", "Arrow2SendPath"); + } + repr2->setAttribute("style", "fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"); + if(isStart){ + repr2->setAttribute("transform", "scale(0.3) translate(-2.3,0)"); + } else { + repr2->setAttribute("transform", "scale(0.3) rotate(180) translate(-2.3,0)"); + } + SPItem *item2 = SP_ITEM(item->appendChildRepr(repr2)); + Inkscape::GC::release(repr2); + item2->updateRepr(); +} + +void MeasureTool::toMarkDimension(){ + setMarkers(); + Geom::PathVector c; + Geom::Path p; + p.start(start_p); + p.appendNew(end_p); + c.push_back(p); + SPDesktop *desktop = this->desktop; + SPDocument *doc = desktop->getDocument(); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + if (c.size() == 1) { + Inkscape::XML::Node *repr; + repr = xml_doc->createElement("svg:path"); + gchar const *str = sp_svg_write_path(c); + gchar const *style_str = "fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow2Sstart);marker-end:url(#Arrow2Send)"; + g_assert( str != NULL ); + repr->setAttribute("d", str); + repr->setAttribute("style", style_str); + // Attach repr + SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr)); + Inkscape::GC::release(repr); + item->updateRepr(); + } + + // Flush pending updates + doc->ensureUpToDate(); + reset(); +} + +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(); +} + void MeasureTool::showCanvasItems(){ showCanvasItems(start_p, end_p); } @@ -765,12 +891,12 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(intersections[0]), - desktop->doc2dt(intersections[0]) + normal * 65); + desktop->doc2dt(intersections[0]) + normal * 60); 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); + desktop->doc2dt(intersections[intersections.size() - 1]) + normal * 60); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); } diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index 944b14ed8..44153a144 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -38,8 +38,13 @@ public: virtual void showCanvasItems(); virtual void showCanvasItems(Geom::Point start_point, Geom::Point end_point); virtual void reverseKnots(); + virtual void toMarkDimension(); + virtual void reset(); + virtual void setMarkers(); + virtual void setMarker(bool isStart); virtual const std::string& getPrefsPath(); - void knotMovedHandler(SPKnot */*knot*/, Geom::Point const /*&ppointer*/, guint /*state*/); + 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: diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 5abd099d6..a619418db 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -154,6 +154,14 @@ static void sp_reverse_knots(void){ mt->reverseKnots(); } } + +static void sp_to_mark_dimension(void){ + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->toMarkDimension(); + } +} + void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* holder) { UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); @@ -236,6 +244,16 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_reverse_knots), 0 ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } + //to mark dimensions + { + InkAction* act = ink_action_new( "MeasureMarkDimension", + _("Mark Dimension"), + _("Mark Dimension"), + INKSCAPE_ICON("draw-geometry-mirror"), + secondarySize ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_mark_dimension), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } } // end of sp_measure_toolbox_prep() diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 769829313..765e91629 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -345,6 +345,7 @@ static gchar const * ui_descr = " " " " " " + " " " " " " -- cgit v1.2.3 From bfe639d1e476a1144cecae26d5959569aae79dcd Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 6 Oct 2015 18:57:43 +0200 Subject: fix a bug on snapping with start knot (bzr r14393.1.10) --- src/ui/tools/measure-tool.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 2a89189dd..894687919 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -296,24 +296,24 @@ void MeasureTool::knotStartMovedHandler(SPKnot */*knot*/, Geom::Point const &ppo if (!(state & GDK_SHIFT_MASK)) { SnapManager &m = desktop->namedview->snap_manager; m.setup(desktop); - Inkscape::SnapCandidatePoint scp(ppointer, Inkscape::SNAPSOURCE_OTHER_HANDLE); - scp.addOrigin(end_p); + Inkscape::SnapCandidatePoint scp(this->knot_start->position(), Inkscape::SNAPSOURCE_OTHER_HANDLE); + scp.addOrigin(this->knot_end->position()); Inkscape::SnappedPoint sp = m.freeSnap(scp); if(start_p != sp.getPoint()){ start_p = sp.getPoint(); - this->knot_end->setPosition(start_p, SP_KNOT_STATE_MOUSEOVER); + this->knot_start->setPosition(start_p, SP_KNOT_STATE_MOUSEOVER); } m.unSetup(); } - showCanvasItems(start_point, this->knot_end->position()); + showCanvasItems(start_p, this->knot_end->position()); } void MeasureTool::knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state){ if (!(state & GDK_SHIFT_MASK)) { SnapManager &m = desktop->namedview->snap_manager; m.setup(desktop); - Inkscape::SnapCandidatePoint scp(ppointer, Inkscape::SNAPSOURCE_OTHER_HANDLE); - scp.addOrigin(start_p); + Inkscape::SnapCandidatePoint scp(this->knot_end->position(), Inkscape::SNAPSOURCE_OTHER_HANDLE); + scp.addOrigin(this->knot_start->position()); Inkscape::SnappedPoint sp = m.freeSnap(scp); if(end_p != sp.getPoint()){ end_p = sp.getPoint(); -- cgit v1.2.3 From 98b86a476c3b26d341a4c175d90bc5611b0899cf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 6 Oct 2015 19:14:44 +0200 Subject: fix a bug rendering the angle line in diferent units than pixels (bzr r14393.1.11) --- src/ui/tools/measure-tool.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 894687919..8a9340b07 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -190,12 +190,14 @@ Geom::Point calcAngleDisplayAnchor(SPDesktop *desktop, double angle, double base * @param anchor the anchor point for displaying the text label. * @param angle the angle of the arc segment to draw. */ -void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom::Point const &end, Geom::Point const &anchor, double angle) +void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom::Point const &end, Geom::Point const &anchor, double angle, Glib::ustring unit_name) { // Given that we have a point on the arc's edge and the angle of the arc, we need to get the two endpoints. double textLen = std::abs((anchor - center).length()); + textLen = Inkscape::Util::Quantity::convert(textLen, "px", unit_name); double sideLen = std::abs((end - center).length()); + sideLen = Inkscape::Util::Quantity::convert(sideLen, "px", unit_name); if (sideLen > 0.0) { double factor = std::min(1.0, textLen / sideLen); @@ -877,7 +879,7 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point CTLINE_SECONDARY); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); - createAngleDisplayCurve(desktop, start_point, end_point, angleDisplayPt, angle); + createAngleDisplayCurve(desktop, start_point, end_point, angleDisplayPt, angle, unit_name); } } -- cgit v1.2.3 From 8ffe79882b3a4e746088d75b76b51251c87aa4a9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 6 Oct 2015 19:33:01 +0200 Subject: Remove wrong code for angle helper path (bzr r14393.1.12) --- src/ui/tools/measure-tool.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 8a9340b07..894687919 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -190,14 +190,12 @@ Geom::Point calcAngleDisplayAnchor(SPDesktop *desktop, double angle, double base * @param anchor the anchor point for displaying the text label. * @param angle the angle of the arc segment to draw. */ -void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom::Point const &end, Geom::Point const &anchor, double angle, Glib::ustring unit_name) +void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom::Point const &end, Geom::Point const &anchor, double angle) { // Given that we have a point on the arc's edge and the angle of the arc, we need to get the two endpoints. double textLen = std::abs((anchor - center).length()); - textLen = Inkscape::Util::Quantity::convert(textLen, "px", unit_name); double sideLen = std::abs((end - center).length()); - sideLen = Inkscape::Util::Quantity::convert(sideLen, "px", unit_name); if (sideLen > 0.0) { double factor = std::min(1.0, textLen / sideLen); @@ -879,7 +877,7 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point CTLINE_SECONDARY); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); - createAngleDisplayCurve(desktop, start_point, end_point, angleDisplayPt, angle, unit_name); + createAngleDisplayCurve(desktop, start_point, end_point, angleDisplayPt, angle); } } -- cgit v1.2.3 From 4f5e6cf51b5fdd584d57fa225d3cdba407f01561 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 7 Oct 2015 18:13:48 +0200 Subject: working in dimension to item (bzr r14393.1.13) --- src/ui/tools/measure-tool.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 894687919..32f164a96 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -25,6 +25,7 @@ #include "desktop.h" #include "svg/svg.h" #include "document.h" +#include #include "pixmaps/cursor-measure.xpm" #include "preferences.h" #include "inkscape.h" @@ -38,12 +39,14 @@ #include <2geom/pathvector.h> #include <2geom/crossing.h> #include <2geom/angle.h> +#include <2geom/transforms.h> #include "snap.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 "enums.h" #include "ui/control-manager.h" #include "knot-enums.h" @@ -571,12 +574,17 @@ void MeasureTool::setMarker(bool isStart){ } void MeasureTool::toMarkDimension(){ + Geom::Point windowNormal = Geom::unit_vector(Geom::rot90(desktop->d2w(end_p - start_p))); + Geom::Point normal = desktop->w2d(windowNormal); setMarkers(); Geom::PathVector c; Geom::Path p; - p.start(start_p); - p.appendNew(end_p); + p.start(desktop->doc2dt(start_p) + normal * 60); + p.appendNew(desktop->doc2dt(end_p) + normal * 60); c.push_back(p); + c *= desktop->doc2dt(); + c *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + c *= Geom::Scale(95.0); SPDesktop *desktop = this->desktop; SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); @@ -596,7 +604,7 @@ void MeasureTool::toMarkDimension(){ // Flush pending updates doc->ensureUpToDate(); - reset(); + //reset(); } void MeasureTool::reset(){ -- cgit v1.2.3 From 6ec542b8becf1a402c3109f44d2b028a8c87a26c Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 8 Oct 2015 12:15:34 +0200 Subject: Correct transform when picking colors under mesh. (bzr r14401) --- src/sp-mesh-array.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 445c9a8f6..d76b884ae 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -313,7 +313,7 @@ bool SPMeshPatchI::tensorIsSet( unsigned int i ) { /** Return tensor control point for "corner" i. - If not sest, returns calculated (Coons) point. + If not set, returns calculated (Coons) point. */ Geom::Point SPMeshPatchI::getTensorPoint( guint k ) { @@ -1058,11 +1058,11 @@ void SPMeshNodeArray::create( SPMesh *mg, SPItem *item, Geom::OptRect bbox ) { Geom::Point center = bbox->midpoint(); // Must keep repr and array in sync. We have two choices: - // Build the repr first and the "read" it. - // Construct the array and the "write" it. + // Build the repr first and then "read" it. + // Construct the array and then "write" it. // We'll do the second. - // Remove any existing mesh. We could chose to simply scale an existing mesh... + // Remove any existing mesh. We could choose to simply scale an existing mesh... //clear(); // We get called twice when a new mesh is created...WHY? @@ -2265,10 +2265,12 @@ guint SPMeshNodeArray::color_pick( std::vector icorners, SPItem* item ) { // Region to average over Geom::Point p = n->p; - // std::cout << " p: " << p << std::endl; + // std::cout << " before transform: p: " << p << std::endl; p *= gr->gradientTransform; - // std::cout << " p: " << p << std::endl; - + // std::cout << " after transform: p: " << p << std::endl; + p *= item->i2doc_affine(); + // std::cout << " after transform: p: " << p << std::endl; + // If on edge, move inward guint cols = patch_columns()+1; guint rows = patch_rows()+1; @@ -2277,7 +2279,7 @@ guint SPMeshNodeArray::color_pick( std::vector icorners, SPItem* item ) { guint ncol = col * 3; guint nrow = row * 3; - double size = 3.0; + const double size = 3.0; // Top edge if( row == 0 ) { -- cgit v1.2.3 From 92d48dff17928ec1f964e5671383a9ebb32f3a6b Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 8 Oct 2015 12:25:06 +0200 Subject: Add buttons for some side/corner mesh opeartions. (bzr r14402) --- src/ui/tools/mesh-tool.cpp | 2 +- src/ui/tools/mesh-tool.h | 2 ++ src/widgets/mesh-toolbar.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++- src/widgets/toolbox.cpp | 5 ++- 4 files changed, 84 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index 813d6ae5b..303757493 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -316,7 +316,7 @@ static void sp_mesh_context_split_near_point(MeshTool *rc, SPItem *item, Geom:: /** Wrapper for various mesh operations that require a list of selected corner nodes. */ -static void +void sp_mesh_context_corner_operation (MeshTool *rc, MeshCornerOperation operation ) { diff --git a/src/ui/tools/mesh-tool.h b/src/ui/tools/mesh-tool.h index d952c9010..91b35b3af 100644 --- a/src/ui/tools/mesh-tool.h +++ b/src/ui/tools/mesh-tool.h @@ -20,6 +20,7 @@ #include #include #include "ui/tools/tool-base.h" +#include "sp-mesh-array.h" #define SP_MESH_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) #define SP_IS_MESH_CONTEXT(obj) (dynamic_cast((const Inkscape::UI::Tools::ToolBase*)obj) != NULL) @@ -57,6 +58,7 @@ private: void sp_mesh_context_select_next(ToolBase *event_context); void sp_mesh_context_select_prev(ToolBase *event_context); +void sp_mesh_context_corner_operation(MeshTool *event_context, MeshCornerOperation operation ); } } diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp index 1af55d9cd..bef9129b9 100644 --- a/src/widgets/mesh-toolbar.cpp +++ b/src/widgets/mesh-toolbar.cpp @@ -34,6 +34,7 @@ #include "widgets/gradient-image.h" #include "style.h" +#include "inkscape.h" #include "preferences.h" #include "document-private.h" #include "document-undo.h" @@ -66,6 +67,7 @@ using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; using Inkscape::UI::PrefPusher; +using Inkscape::UI::Tools::MeshTool; static bool blocked = false; @@ -314,10 +316,49 @@ static void ms_type_changed(EgeSelectOneAction *act, GtkWidget *widget) } } +/** Temporary hack: Returns the mesh tool in the active desktop. + * Will go away during tool refactoring. */ +static MeshTool *get_mesh_tool() +{ + MeshTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (SP_IS_MESH_CONTEXT(ec)) { + tool = static_cast(ec); + } + } + return tool; +} + +static void ms_toggle_sides(void) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + sp_mesh_context_corner_operation( mt, MG_CORNER_SIDE_TOGGLE ); + } +} + +static void ms_make_elliptical(void) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + sp_mesh_context_corner_operation( mt, MG_CORNER_SIDE_ARC ); + } +} + +static void ms_pick_colors(void) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + sp_mesh_context_corner_operation( mt, MG_CORNER_COLOR_PICK ); + } +} + static void mesh_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); /** * Mesh auxiliary toolbar construction and setup. + * Don't forget to add to XML in widgets/toolbox.cpp! * */ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* holder) @@ -466,7 +507,7 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } - /* Typeing method */ + /* Type */ { GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT ); @@ -487,6 +528,41 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); g_object_set_data( holder, "mesh_select_type_action", act ); } + + { + InkAction* act = ink_action_new( "MeshToggleSidesAction", + _("Toggle Sides"), + _("Toggle selected sides between Beziers and lines."), + INKSCAPE_ICON("node-segment-line"), + secondarySize ); + g_object_set( act, "short_label", _("Toggle side:"), NULL ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_sides), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + { + InkAction* act = ink_action_new( "MeshMakeEllipticalAction", + _("Make elliptical"), + _("Make selected sides elliptical by changing length of handles. Works best if handles already approximate ellipse."), + INKSCAPE_ICON("node-segment-curve"), + secondarySize ); + g_object_set( act, "short_label", _("Make elliptical:"), NULL ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_make_elliptical), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + { + InkAction* act = ink_action_new( "MeshPickColorsAction", + _("Pick colors:"), + _("Pick colors for selected corner nodes from underneath mesh."), + INKSCAPE_ICON("color-picker"), + secondarySize ); + g_object_set( act, "short_label", _("Pick Color"), NULL ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_pick_colors), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + } static void mesh_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index cdf39e9ef..a1c32352c 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -519,9 +519,12 @@ static gchar const * ui_descr = // " " // " " // " " + " " + " " + " " + " " " " " " - " " " " " " -- cgit v1.2.3 From 17f2a27dfcfbf68d218193a830faa9580ce8a363 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 10 Oct 2015 21:17:34 +0200 Subject: Added new button to get global measure as a dimension (bzr r14393.1.15) --- src/ui/tools/measure-tool.cpp | 169 ++++++++++++++++++++++++++++------------ src/ui/tools/measure-tool.h | 1 + src/widgets/measure-toolbar.cpp | 35 ++++++++- src/widgets/toolbox.cpp | 2 + 4 files changed, 155 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 32f164a96..585128135 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -25,6 +25,7 @@ #include "desktop.h" #include "svg/svg.h" #include "document.h" +#include "document-undo.h" #include #include "pixmaps/cursor-measure.xpm" #include "preferences.h" @@ -50,11 +51,14 @@ #include "enums.h" #include "ui/control-manager.h" #include "knot-enums.h" +#include "desktop-style.h" +#include "verbs.h" #include 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 @@ -74,7 +78,7 @@ const std::string MeasureTool::prefsPath = "/tools/measure"; namespace { -gint const DIMENSION_OFFSET = 35; +gint dimension_offset = 35; /** * Simple class to use for removing label overlap. @@ -236,8 +240,10 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom } // namespace -static Geom::Point start_p = Geom::Point(); -static Geom::Point end_p = Geom::Point(); +Geom::Point const MAGIC_POINT = Geom::Point(-0.0003432532004303,-0.006745034004304); +static Geom::Point start_p = MAGIC_POINT; +static Geom::Point end_p = MAGIC_POINT; + MeasureTool::MeasureTool() : ToolBase(cursor_measure_xpm, 4, 4) , grabbed(NULL) @@ -256,10 +262,10 @@ MeasureTool::MeasureTool() this->knot_end->setStroke(0x0000007f, 0x0000007f, 0x0000007f); this->knot_end->setShape(SP_KNOT_SHAPE_CIRCLE); this->knot_end->updateCtrl(); - if(end_p != Geom::Point()){ - this->knot_start->setPosition(start_p, SP_KNOT_STATE_NORMAL); + if(end_p != MAGIC_POINT){ + this->knot_start->moveto(start_p); this->knot_start->show(); - this->knot_end->setPosition(end_p, SP_KNOT_STATE_NORMAL); + this->knot_end->moveto(end_p); this->knot_end->show(); this->showCanvasItems(); } @@ -288,9 +294,9 @@ MeasureTool::~MeasureTool() { void MeasureTool::reverseKnots(){ Geom::Point start = start_p; Geom::Point end = end_p; - this->knot_start->setPosition(end, SP_KNOT_STATE_NORMAL); + this->knot_start->moveto(end); this->knot_start->show(); - this->knot_end->setPosition(start, SP_KNOT_STATE_NORMAL); + this->knot_end->moveto(start); this->knot_end->show(); this->showCanvasItems(end, start); } @@ -304,7 +310,7 @@ void MeasureTool::knotStartMovedHandler(SPKnot */*knot*/, Geom::Point const &ppo Inkscape::SnappedPoint sp = m.freeSnap(scp); if(start_p != sp.getPoint()){ start_p = sp.getPoint(); - this->knot_start->setPosition(start_p, SP_KNOT_STATE_MOUSEOVER); + this->knot_start->moveto(start_p); } m.unSetup(); } @@ -320,7 +326,7 @@ void MeasureTool::knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppoin Inkscape::SnappedPoint sp = m.freeSnap(scp); if(end_p != sp.getPoint()){ end_p = sp.getPoint(); - this->knot_end->setPosition(end_p, SP_KNOT_STATE_MOUSEOVER); + this->knot_end->moveto(end_p); } m.unSetup(); } @@ -328,7 +334,7 @@ void MeasureTool::knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppoin } void MeasureTool::knotUngrabbedHandler(SPKnot */*knot*/, unsigned int state){ - showCanvasItems(this->knot_start->position(), end_p); + showCanvasItems(this->knot_start->position(), this->knot_end->position()); } @@ -432,18 +438,20 @@ bool MeasureTool::root_handler(GdkEvent* event) { break; } case GDK_MOTION_NOTIFY: { - if (!(event->motion.state & GDK_BUTTON1_MASK) && !(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)); + 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)); - SnapManager &m = desktop->namedview->snap_manager; - m.setup(desktop); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); - Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE); - scp.addOrigin(start_point); + Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE); + scp.addOrigin(start_point); - m.preSnap(scp); - m.unSetup(); + m.preSnap(scp); + m.unSetup(); + } } else { ret = TRUE; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -482,12 +490,13 @@ bool MeasureTool::root_handler(GdkEvent* event) { break; } case GDK_BUTTON_RELEASE: { - this->knot_start->setPosition(start_point, SP_KNOT_STATE_NORMAL); + this->knot_start->moveto(start_point); this->knot_start->show(); + Geom::Point end_point = end_p; if(last_end){ - Geom::Point end_point = desktop->w2d(*last_end); + end_point = desktop->w2d(*last_end); if (event->button.state & GDK_CONTROL_MASK) { - spdc_endpoint_snap_rotation(this, end_point, start_point, event->motion.state); + spdc_endpoint_snap_rotation(this, end_point, start_point, event->motion.state); } else if (!(event->button.state & GDK_SHIFT_MASK)) { SnapManager &m = desktop->namedview->snap_manager; m.setup(desktop); @@ -497,14 +506,14 @@ bool MeasureTool::root_handler(GdkEvent* event) { end_point = sp.getPoint(); m.unSetup(); } - this->knot_end->setPosition(end_point, SP_KNOT_STATE_NORMAL); - this->knot_end->show(); } + this->knot_end->moveto(end_point); + this->knot_end->show(); + showCanvasItems(start_point, end_point); if (this->grabbed) { sp_canvas_item_ungrab(this->grabbed, event->button.time); this->grabbed = NULL; } - sp_event_context_discard_delayed_snap_event(this); break; } default: @@ -562,7 +571,7 @@ void MeasureTool::setMarker(bool isStart){ } else { repr2->setAttribute("id", "Arrow2SendPath"); } - repr2->setAttribute("style", "fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"); + repr2->setAttribute("style", "stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"); if(isStart){ repr2->setAttribute("transform", "scale(0.3) translate(-2.3,0)"); } else { @@ -574,17 +583,18 @@ void MeasureTool::setMarker(bool isStart){ } void MeasureTool::toMarkDimension(){ - Geom::Point windowNormal = Geom::unit_vector(Geom::rot90(desktop->d2w(end_p - start_p))); - Geom::Point normal = desktop->w2d(windowNormal); setMarkers(); Geom::PathVector c; Geom::Path p; - p.start(desktop->doc2dt(start_p) + normal * 60); - p.appendNew(desktop->doc2dt(end_p) + normal * 60); + Geom::Ray ray(start_p,end_p); + Geom::Point start = start_p + Geom::Point::polar(ray.angle(), 5); + start = desktop->doc2dt(start + Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -(dimension_offset / 4.0))); + Geom::Point end = end_p + Geom::Point::polar(ray.angle(), -5); + end = desktop->doc2dt(end+ Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -(dimension_offset / 4.0))); + p.start(start); + p.appendNew(end); c.push_back(p); - c *= desktop->doc2dt(); c *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - c *= Geom::Scale(95.0); SPDesktop *desktop = this->desktop; SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); @@ -592,21 +602,79 @@ void MeasureTool::toMarkDimension(){ Inkscape::XML::Node *repr; repr = xml_doc->createElement("svg:path"); gchar const *str = sp_svg_write_path(c); - gchar const *style_str = "fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow2Sstart);marker-end:url(#Arrow2Send)"; + Geom::Point stroke_width = Geom::Point(1,1) * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + std::stringstream style_str; + style_str.imbue(std::locale::classic()); + style_str << "fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:" << stroke_width[Geom::X] << ";stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow2Sstart);marker-end:url(#Arrow2Send)"; g_assert( str != NULL ); repr->setAttribute("d", str); - repr->setAttribute("style", style_str); - // Attach repr + repr->setAttribute("style", style_str.str().c_str()); SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr)); Inkscape::GC::release(repr); item->updateRepr(); } + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring unit_name = prefs->getString("/tools/measure/unit"); + if (!unit_name.compare("")) { + unit_name = "px"; + } + double fontsize = prefs->getInt("/tools/measure/fontsize") * (96/72); + Geom::Point middle = Geom::middle_point(start, end); + double totallengthval = (end_p - start_p).length(); + totallengthval = Inkscape::Util::Quantity::convert(totallengthval, "px", unit_name); + gchar *totallength_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str()); + setLabelText(totallength_str, middle, fontsize, Geom::deg_to_rad(180) - ray.angle()); // Flush pending updates doc->ensureUpToDate(); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE, + _("Add global meassure line")); //reset(); } +void MeasureTool::setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle) +{ + /* Create */ + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + 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); + + sp_repr_set_svg_double(rtext, "x", 0); + sp_repr_set_svg_double(rtext, "y", 0); + + /* Create */ + Inkscape::XML::Node *rtspan = xml_doc->createElement("svg:tspan"); + rtspan->setAttribute("sodipodi:role", "line"); // otherwise, why bother creating the tspan? + std::stringstream text_style; + text_style.imbue(std::locale::classic()); + text_style << "font-style:normal;font-weight:normal;font-size:" << fontsize << "px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"; + rtspan->setAttribute("style", text_style.str().c_str()); + 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 (bbox) { + Geom::Coord posX = Geom::middle_point(Geom::Point(bbox->left(), bbox->top()), Geom::Point(bbox->right(), bbox->top()))[Geom::X]; + Geom::Coord posY = Geom::middle_point(Geom::Point(bbox->left(), bbox->top()), Geom::Point(bbox->left(), bbox->bottom()))[Geom::Y]; + text_item->transform *= Geom::Translate(Geom::Point(posX, posY)).inverse(); + pos = pos + Geom::Point::polar(angle + Geom::deg_to_rad(90), -Geom::distance(Geom::Point(bbox->left(), bbox->top()), Geom::Point(bbox->left(), bbox->bottom()))); + } + 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); +} + void MeasureTool::reset(){ this->knot_start->hide(); this->knot_end->hide(); @@ -622,6 +690,9 @@ void MeasureTool::showCanvasItems(){ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point){ SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if(!desktop || !start_point.isFinite() || !end_point.isFinite() || end_point == MAGIC_POINT){ + return; + } start_p = start_point; end_p = end_point; //clear previous temporary canvas items, we'll draw new ones @@ -632,6 +703,7 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool show_in_between = prefs->getBool("/tools/measure/show_in_between"); bool all_layers = prefs->getBool("/tools/measure/all_layers"); + dimension_offset = prefs->getDouble("/tools/measure/offset"); Geom::PathVector lineseg; Geom::Path p; p.start(desktop->dt2doc(start_point)); @@ -660,13 +732,13 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop); r->setMode(RUBBERBAND_MODE_TOUCHPATH); if(!show_in_between){ - r->start(desktop,start_point); - r->move(end_point); + 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_point); - r->move(start_point); + r->start(desktop,end_p); + r->move(start_p); std::vector 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]){ @@ -722,8 +794,7 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point unit_name = "px"; } - double fontsize = prefs->getInt("/tools/measure/fontsize"); - + double fontsize = prefs->getInt("/tools/measure/fontsize") * (96/72); // 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); @@ -748,7 +819,7 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point 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.offset = dimension_offset; placement.start = desktop->doc2dt( (intersections[idx - 1] + intersections[idx]) / 2 ); placement.end = placement.start - (normal * placement.offset); @@ -830,7 +901,7 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point 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, + desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * (dimension_offset * 2), total_str); sp_canvastext_set_fontsize(canvas_tooltip, fontsize); canvas_tooltip->rgba = 0xffffffff; @@ -893,18 +964,18 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point 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); + desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2), + desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2)); 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 * 60); + desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2)); 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 * 60); + desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2)); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); } @@ -928,7 +999,7 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point ControlManager &mgr = ControlManager::getManager(); SPCtrlLine *control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(measure_text_pos), - desktop->doc2dt(measure_text_pos) - (normal * DIMENSION_OFFSET), + desktop->doc2dt(measure_text_pos) - (normal * dimension_offset), CTLINE_SECONDARY); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); } diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index 44153a144..0670fb9f7 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -43,6 +43,7 @@ public: virtual void setMarkers(); virtual void setMarker(bool isStart); virtual const std::string& getPrefsPath(); + void setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle); 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*/); diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index a619418db..9c782b4b6 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -86,6 +86,22 @@ sp_measure_fontsize_value_changed(GtkAdjustment *adj, GObject *tbl) } } +static void +sp_measure_offset_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt(Glib::ustring("/tools/measure/offset"), + gtk_adjustment_get_value(adj)); + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } + } +} + static void measure_unit_changed(GtkAction* /*act*/, GObject* tbl) { UnitTracker* tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); @@ -180,13 +196,12 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G _("The font size to be used in the measurement labels"), "/tools/measure/fontsize", 0.0, GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 10, 36, 1.0, 4.0, + 1, 36, 1.0, 4.0, 0, 0, 0, sp_measure_fontsize_value_changed); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); } - // units label { EgeOutputAction* act = ege_output_action_new( "measure_units_label", _("Units:"), _("The units to be used for the measurements"), 0 ); @@ -201,6 +216,20 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(measure_unit_changed), holder ); gtk_action_group_add_action( mainActions, act ); } + + /* Offset */ + { + eact = create_adjustment_action( "MeasureOffsetAction", + _("Offset"), _("Offset:"), + _("The offset size"), + "/tools/measure/offset", 30.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 90000.0, 1.0, 4.0, + 0, 0, 0, + sp_measure_offset_value_changed); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + // ignore_1st_and_last { InkToggleAction* act = ink_toggle_action_new( "MeasureIgnore1stAndLast", @@ -249,7 +278,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G InkAction* act = ink_action_new( "MeasureMarkDimension", _("Mark Dimension"), _("Mark Dimension"), - INKSCAPE_ICON("draw-geometry-mirror"), + INKSCAPE_ICON("tool-pointer"), secondarySize ); g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_mark_dimension), 0 ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 765e91629..65a0cd9cb 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -339,6 +339,8 @@ static gchar const * ui_descr = " " " " " " + " " + " " " " " " " " -- cgit v1.2.3 From b76d7592902d9e27cb442e203ebffed4a915b8e6 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 12 Oct 2015 12:05:07 +0200 Subject: Fix from Johan to prevent referencing null C++ pointer. Found via Clang scan build. (bzr r14404) --- src/ui/clipboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 816daf2e5..0792fb9c5 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -565,7 +565,7 @@ bool ClipboardManagerImpl::pastePathEffect(SPDesktop *desktop) } Inkscape::Selection *selection = desktop->getSelection(); - if (selection && selection->isEmpty()) { + if (!selection || selection->isEmpty()) { _userWarn(desktop, _("Select object(s) to paste live path effect to.")); return false; } -- cgit v1.2.3 From 2653fd7c3a138f91181f7bb64e1fd342c943ee7b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 12 Oct 2015 12:37:15 +0200 Subject: Convert Measure to Item done (bzr r14393.1.17) --- src/ui/tools/measure-tool.cpp | 905 ++++++++++++++++++++++++++-------------- src/ui/tools/measure-tool.h | 21 +- src/widgets/measure-toolbar.cpp | 17 + src/widgets/toolbox.cpp | 1 + 4 files changed, 638 insertions(+), 306 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 585128135..76b8e931e 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 * Jon A. Cruz + * Jabiertxo Arraiza * * Copyright (C) 2011 Authors * @@ -14,42 +15,44 @@ #include #include #include "util/units.h" -#include "macros.h" -#include "rubberband.h" +#include "display/canvas-text.h" #include "display/curve.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 "svg/svg.h" -#include "document.h" -#include "document-undo.h" -#include -#include "pixmaps/cursor-measure.xpm" -#include "preferences.h" -#include "inkscape.h" -#include "knot.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 "ui/control-manager.h" +#include <2geom/line.h> #include <2geom/path-intersection.h> #include <2geom/pathvector.h> #include <2geom/crossing.h> #include <2geom/angle.h> #include <2geom/transforms.h> -#include "snap.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 "macros.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" @@ -63,20 +66,21 @@ using Inkscape::DocumentUndo; #define MT_KNOT_COLOR_NORMAL 0xffffff00 #define MT_KNOT_COLOR_MOUSEOVER 0xff000000 + namespace Inkscape { namespace UI { namespace Tools { std::vector measure_tmp_items; -const std::string& MeasureTool::getPrefsPath() { +const std::string& MeasureTool::getPrefsPath() +{ return MeasureTool::prefsPath; } const std::string MeasureTool::prefsPath = "/tools/measure"; -namespace -{ +namespace { gint dimension_offset = 35; @@ -196,8 +200,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 ¢er, Geom::Point const &end, Geom::Point const &anchor, double angle) +void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, 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. @@ -205,7 +210,7 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, 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)) @@ -235,9 +240,47 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, 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 c; + Geom::Path p; + p.start(desktop->doc2dt(p1)); + p.appendNew(desktop->doc2dt(p2),desktop->doc2dt(p3),desktop->doc2dt(p4)); + c.push_back(p); + c *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + SPDocument *doc = desktop->getDocument(); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + if (c.size() == 1) { + Inkscape::XML::Node *repr; + repr = xml_doc->createElement("svg:path"); + gchar const *str = sp_svg_write_path(c); + Geom::Point strokewidth = Geom::Point(1,1) * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + SPCSSAttr *css = sp_repr_css_attr_new(); + std::stringstream stroke_width; + stroke_width.imbue(std::locale::classic()); + stroke_width << strokewidth[Geom::X] / desktop->current_zoom(); + sp_repr_css_set_property (css, "stroke-width", stroke_width.str().c_str()); + sp_repr_css_set_property (css, "fill", "none"); + guint32 line_color_secondary = 0xff00007f; + gchar c[64]; + sp_svg_write_color (c, sizeof(c), line_color_secondary); + sp_repr_css_set_property (css, "stroke", c); + sp_repr_css_set_property (css, "stroke-linecap", "butt"); + 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"); + sp_repr_css_set_property (css, "stroke-opacity", "0.5"); + 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); + measure_repr->addChild(repr, NULL); + Inkscape::GC::release(repr); + } + } } } - } // namespace Geom::Point const MAGIC_POINT = Geom::Point(-0.0003432532004303,-0.006745034004304); @@ -249,7 +292,7 @@ MeasureTool::MeasureTool() , grabbed(NULL) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - // create the knot + // 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); @@ -262,12 +305,13 @@ MeasureTool::MeasureTool() this->knot_end->setStroke(0x0000007f, 0x0000007f, 0x0000007f); this->knot_end->setShape(SP_KNOT_SHAPE_CIRCLE); this->knot_end->updateCtrl(); - if(end_p != MAGIC_POINT){ + Geom::Rect display_area = desktop->get_display_area () ; + if(display_area.interiorContains(start_p) && display_area.interiorContains(end_p) && end_p != MAGIC_POINT) { this->knot_start->moveto(start_p); this->knot_start->show(); this->knot_end->moveto(end_p); this->knot_end->show(); - this->showCanvasItems(); + showCanvasItems(); } 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)); @@ -276,7 +320,8 @@ MeasureTool::MeasureTool() } -MeasureTool::~MeasureTool() { +MeasureTool::~MeasureTool() +{ this->_knot_start_moved_connection.disconnect(); this->_knot_start_ungrabbed_connection.disconnect(); this->_knot_end_moved_connection.disconnect(); @@ -291,7 +336,8 @@ MeasureTool::~MeasureTool() { measure_tmp_items.clear(); } -void MeasureTool::reverseKnots(){ +void MeasureTool::reverseKnots() +{ Geom::Point start = start_p; Geom::Point end = end_p; this->knot_start->moveto(end); @@ -301,45 +347,59 @@ void MeasureTool::reverseKnots(){ this->showCanvasItems(end, start); } -void MeasureTool::knotStartMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state){ - if (!(state & GDK_SHIFT_MASK)) { +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 &m = desktop->namedview->snap_manager; m.setup(desktop); - Inkscape::SnapCandidatePoint scp(this->knot_start->position(), Inkscape::SNAPSOURCE_OTHER_HANDLE); + Inkscape::SnapCandidatePoint scp(point, Inkscape::SNAPSOURCE_OTHER_HANDLE); scp.addOrigin(this->knot_end->position()); Inkscape::SnappedPoint sp = m.freeSnap(scp); - if(start_p != sp.getPoint()){ - start_p = sp.getPoint(); - this->knot_start->moveto(start_p); - } + point = sp.getPoint(); m.unSetup(); } - showCanvasItems(start_p, this->knot_end->position()); + if(start_p != point) { + start_p = point; + this->knot_start->moveto(start_p); + } + showCanvasItems(start_p, end_p); } -void MeasureTool::knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state){ - if (!(state & GDK_SHIFT_MASK)) { +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 &m = desktop->namedview->snap_manager; m.setup(desktop); - Inkscape::SnapCandidatePoint scp(this->knot_end->position(), Inkscape::SNAPSOURCE_OTHER_HANDLE); + Inkscape::SnapCandidatePoint scp(point, Inkscape::SNAPSOURCE_OTHER_HANDLE); scp.addOrigin(this->knot_start->position()); Inkscape::SnappedPoint sp = m.freeSnap(scp); - if(end_p != sp.getPoint()){ - end_p = sp.getPoint(); - this->knot_end->moveto(end_p); - } + point = sp.getPoint(); m.unSetup(); } - showCanvasItems(this->knot_start->position(), end_p); + if(end_p != point) { + end_p = point; + this->knot_end->moveto(end_p); + } + showCanvasItems(start_p, end_p); } -void MeasureTool::knotUngrabbedHandler(SPKnot */*knot*/, unsigned int state){ - showCanvasItems(this->knot_start->position(), this->knot_end->position()); +void MeasureTool::knotUngrabbedHandler(SPKnot */*knot*/, unsigned int state) +{ + this->knot_start->moveto(start_p); + this->knot_end->moveto(end_p); + showCanvasItems(start_p, end_p); } -void MeasureTool::finish() { +void MeasureTool::finish() +{ this->enableGrDrag(false); if (this->grabbed) { @@ -386,9 +446,9 @@ static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom: 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)) || - ((*m).ta + eps < 1 && - item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta + eps), false, NULL)) ) { + item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta - eps), false, NULL)) || + ((*m).ta + eps < 1 && + item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta + eps), false, NULL)) ) { intersections.push_back((*m).ta); } #else @@ -398,106 +458,83 @@ static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom: } } -bool MeasureTool::root_handler(GdkEvent* event) { +bool MeasureTool::root_handler(GdkEvent* event) +{ gint ret = FALSE; switch (event->type) { - 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_point = desktop->w2d(button_w); - - if (event->button.button == 1 && !this->space_panning) { - // save drag origin - start_point = desktop->w2d(Geom::Point(event->button.x, 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_point = desktop->w2d(button_w); + + if (event->button.button == 1 && !this->space_panning) { + // save drag origin + start_point = 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 &m = desktop->namedview->snap_manager; + m.setup(desktop); + m.freeSnapReturnByRef(start_point, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.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 (last_end) { - explicitBase = last_end; - } + 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 (last_end) { + explicitBase = last_end; } - 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)); + 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)); - SnapManager &m = desktop->namedview->snap_manager; - m.setup(desktop); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); - Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE); - scp.addOrigin(start_point); + Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE); + scp.addOrigin(start_point); - m.preSnap(scp); - m.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_point ) < tolerance) { - return FALSE; // 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; - if(event->motion.time == 0 || !last_end || Geom::LInfty( motion_w - *last_end ) > (tolerance/2)){ - 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; - - 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(); - } - showCanvasItems(start_point, end_point); - last_end = motion_w ; + m.preSnap(scp); + m.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_point ) < tolerance) { + return FALSE; // Do not drag if we're within tolerance from origin. } - gobble_motion_events(GDK_BUTTON1_MASK); } - break; - } - case GDK_BUTTON_RELEASE: { - this->knot_start->moveto(start_point); - this->knot_start->show(); - Geom::Point end_point = end_p; - if(last_end){ - end_point = desktop->w2d(*last_end); - if (event->button.state & GDK_CONTROL_MASK) { + // 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; + + if (event->motion.state & GDK_CONTROL_MASK) { spdc_endpoint_snap_rotation(this, end_point, start_point, event->motion.state); - } else if (!(event->button.state & GDK_SHIFT_MASK)) { + } 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); @@ -506,153 +543,317 @@ bool MeasureTool::root_handler(GdkEvent* event) { end_point = sp.getPoint(); m.unSetup(); } + showCanvasItems(start_point, end_point); + last_end = motion_w ; } - this->knot_end->moveto(end_point); - this->knot_end->show(); - showCanvasItems(start_point, end_point); - if (this->grabbed) { - sp_canvas_item_ungrab(this->grabbed, event->button.time); - this->grabbed = NULL; + gobble_motion_events(GDK_BUTTON1_MASK); + } + break; + } + case GDK_BUTTON_RELEASE: { + this->knot_start->moveto(start_point); + this->knot_start->show(); + Geom::Point end_point = end_p; + if(last_end) { + end_point = desktop->w2d(*last_end); + if (event->button.state & GDK_CONTROL_MASK) { + spdc_endpoint_snap_rotation(this, end_point, start_point, event->motion.state); + } else if (!(event->button.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(); } - break; } - default: - break; + this->knot_end->moveto(end_point); + this->knot_end->show(); + showCanvasItems(start_point, end_point); + 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); } - + return ret; } -void MeasureTool::setMarkers(){ - SPDesktop *desktop = this->desktop; +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){ + if(!arrowEnd) { setMarker(false); } } -void MeasureTool::setMarker(bool isStart){ - SPDesktop *desktop = this->desktop; +void MeasureTool::setMarker(bool isStart) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; SPDocument *doc = desktop->getDocument(); SPDefs *defs = doc->getDefs(); - Inkscape::XML::Node *repr; + Inkscape::XML::Node *rmarker; Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - repr = xml_doc->createElement("svg:marker"); - if(isStart){ - repr->setAttribute("id", "Arrow2Sstart"); + rmarker = xml_doc->createElement("svg:marker"); + if(isStart) { + rmarker->setAttribute("id", "Arrow2Sstart"); } else { - repr->setAttribute("id", "Arrow2Send"); + rmarker->setAttribute("id", "Arrow2Send"); } - repr->setAttribute("inkscape:isstock", "true"); - if(isStart){ - repr->setAttribute("inkscape:stockid", "Arrow2Sstart"); + rmarker->setAttribute("inkscape:isstock", "true"); + if(isStart) { + rmarker->setAttribute("inkscape:stockid", "Arrow2Sstart"); } else { - repr->setAttribute("inkscape:stockid", "Arrow2Send"); + rmarker->setAttribute("inkscape:stockid", "Arrow2Send"); } - repr->setAttribute("orient", "auto"); - repr->setAttribute("refX", "0.0"); - repr->setAttribute("refY", "0.0"); - repr->setAttribute("style", "overflow:visible;"); - SPItem *item = SP_ITEM(defs->appendChildRepr(repr)); - Inkscape::GC::release(repr); - item->updateRepr(); - Inkscape::XML::Node *repr2; - repr2 = xml_doc->createElement("svg:path"); - repr2->setAttribute("d", "M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z"); - if(isStart){ - repr2->setAttribute("id", "Arrow2SstartPath"); + 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"); + if(isStart) { + rpath->setAttribute("id", "Arrow2SstartPath"); } else { - repr2->setAttribute("id", "Arrow2SendPath"); + rpath->setAttribute("id", "Arrow2SendPath"); } - repr2->setAttribute("style", "stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"); - if(isStart){ - repr2->setAttribute("transform", "scale(0.3) translate(-2.3,0)"); + 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); + if(isStart) { + rpath->setAttribute("transform", "scale(0.3) translate(-2.3,0)"); } else { - repr2->setAttribute("transform", "scale(0.3) rotate(180) translate(-2.3,0)"); + rpath->setAttribute("transform", "scale(0.3) rotate(180) translate(-2.3,0)"); } - SPItem *item2 = SP_ITEM(item->appendChildRepr(repr2)); - Inkscape::GC::release(repr2); - item2->updateRepr(); + SPItem *path = SP_ITEM(marker->appendChildRepr(rpath)); + Inkscape::GC::release(rpath); + path->updateRepr(); +} + +void MeasureTool::toItem() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + 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(start_p, end_p, 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(); } -void MeasureTool::toMarkDimension(){ +void MeasureTool::toMarkDimension() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *doc = desktop->getDocument(); setMarkers(); - Geom::PathVector c; - Geom::Path p; Geom::Ray ray(start_p,end_p); Geom::Point start = start_p + Geom::Point::polar(ray.angle(), 5); - start = desktop->doc2dt(start + Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -(dimension_offset / 4.0))); + start = start + Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -(dimension_offset / 4.0)); Geom::Point end = end_p + Geom::Point::polar(ray.angle(), -5); - end = desktop->doc2dt(end+ Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -(dimension_offset / 4.0))); - p.start(start); - p.appendNew(end); + end = end+ Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -(dimension_offset / 4.0)); + guint32 color = 0x000000ff; + setLine(start, end, true, &color); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring unit_name = prefs->getString("/tools/measure/unit"); + if (!unit_name.compare("")) { + unit_name = "px"; + } + double fontsize = prefs->getInt("/tools/measure/fontsize") * (96/72); + Geom::Point middle = Geom::middle_point(start, end); + double totallengthval = (end_p - start_p).length(); + totallengthval = Inkscape::Util::Quantity::convert(totallengthval, "px", unit_name); + gchar *totallength_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str()); + setLabelText(totallength_str, middle, fontsize, Geom::deg_to_rad(180) - ray.angle()); + doc->ensureUpToDate(); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add global meassure line")); +} + +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_point.isFinite() || !end_point.isFinite()) { + return; + } + Geom::PathVector c; + Geom::Path p; + p.start(desktop->doc2dt(start_point)); + p.appendNew(desktop->doc2dt(end_point)); c.push_back(p); c *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - SPDesktop *desktop = this->desktop; SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); if (c.size() == 1) { Inkscape::XML::Node *repr; repr = xml_doc->createElement("svg:path"); gchar const *str = sp_svg_write_path(c); - Geom::Point stroke_width = Geom::Point(1,1) * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - std::stringstream style_str; - style_str.imbue(std::locale::classic()); - style_str << "fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:" << stroke_width[Geom::X] << ";stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow2Sstart);marker-end:url(#Arrow2Send)"; + Geom::Point strokewidth = Geom::Point(1,1) * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + SPCSSAttr *css = sp_repr_css_attr_new(); + std::stringstream stroke_width; + stroke_width.imbue(std::locale::classic()); + if(measure_repr) { + stroke_width << strokewidth[Geom::X] / desktop->current_zoom(); + } else { + stroke_width << strokewidth[Geom::X]; + } + sp_repr_css_set_property (css, "stroke-width", stroke_width.str().c_str()); + sp_repr_css_set_property (css, "fill", "none"); + if(color) { + gchar c[64]; + sp_svg_write_color (c, sizeof(c), *color); + sp_repr_css_set_property (css, "stroke", c); + } else { + sp_repr_css_set_property (css, "stroke", "#000000"); + } + sp_repr_css_set_property (css, "stroke-linecap", "butt"); + 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); - repr->setAttribute("style", style_str.str().c_str()); - SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr)); - Inkscape::GC::release(repr); - item->updateRepr(); + 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(); + } } +} - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring unit_name = prefs->getString("/tools/measure/unit"); - if (!unit_name.compare("")) { - unit_name = "px"; +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 -3.55,-3.55 7.11,7.11 m 0,-7.11 -7.11,7.11"; + Geom::PathVector c = sp_svg_read_pathv(svgd); + Geom::Scale scale = Geom::Scale(desktop->current_zoom()).inverse(); + c *= scale; + Geom::Point strokewidth = (Geom::Point(1,1) * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse())/ desktop->current_zoom(); + c *= Geom::Translate(Geom::Point(strokewidth/2.0) - (scale.vector() * 0.5)); + c *= Geom::Translate(desktop->doc2dt(origin)); + c *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + SPDocument *doc = desktop->getDocument(); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + if (c.size() == 2) { + Inkscape::XML::Node *repr; + repr = xml_doc->createElement("svg:path"); + gchar const *str = sp_svg_write_path(c); + SPCSSAttr *css = sp_repr_css_attr_new(); + std::stringstream stroke_width; + stroke_width.imbue(std::locale::classic()); + stroke_width << strokewidth[Geom::X]; + sp_repr_css_set_property (css, "stroke-width", stroke_width.str().c_str()); + sp_repr_css_set_property (css, "fill", "none"); + guint32 line_color_secondary = 0xff0000ff; + gchar c[64]; + sp_svg_write_color (c, sizeof(c), line_color_secondary); + sp_repr_css_set_property (css, "stroke", c); + sp_repr_css_set_property (css, "stroke-linecap", "butt"); + 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"); + sp_repr_css_set_property (css, "stroke-opacity", "0.5"); + 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); + measure_repr->addChild(repr, NULL); + Inkscape::GC::release(repr); } - double fontsize = prefs->getInt("/tools/measure/fontsize") * (96/72); - Geom::Point middle = Geom::middle_point(start, end); - double totallengthval = (end_p - start_p).length(); - totallengthval = Inkscape::Util::Quantity::convert(totallengthval, "px", unit_name); - gchar *totallength_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str()); - setLabelText(totallength_str, middle, fontsize, Geom::deg_to_rad(180) - ray.angle()); - // Flush pending updates - doc->ensureUpToDate(); - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE, - _("Add global meassure line")); - //reset(); } -void MeasureTool::setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle) +void MeasureTool::setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle, guint32 *background, Inkscape::XML::Node *measure_repr, CanvasTextAnchorPositionEnum text_anchor) { - /* Create */ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + /* Create */ + 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); - - sp_repr_set_svg_double(rtext, "x", 0); - sp_repr_set_svg_double(rtext, "y", 0); + 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); + } /* Create */ Inkscape::XML::Node *rtspan = xml_doc->createElement("svg:tspan"); rtspan->setAttribute("sodipodi:role", "line"); // otherwise, why bother creating the tspan? - std::stringstream text_style; - text_style.imbue(std::locale::classic()); - text_style << "font-style:normal;font-weight:normal;font-size:" << fontsize << "px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"; - rtspan->setAttribute("style", text_style.str().c_str()); + SPCSSAttr *css = sp_repr_css_attr_new(); + std::stringstream font_size; + font_size.imbue(std::locale::classic()); + font_size << fontsize ; + 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", "0px"); + sp_repr_css_set_property (css, "word-spacing", "0px"); + 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 */ @@ -663,19 +864,63 @@ void MeasureTool::setLabelText(const char *value, Geom::Point pos, double fontsi Inkscape::GC::release(rtext); text_item->updateRepr(); Geom::OptRect bbox = text_item->geometricBounds(); - if (bbox) { - Geom::Coord posX = Geom::middle_point(Geom::Point(bbox->left(), bbox->top()), Geom::Point(bbox->right(), bbox->top()))[Geom::X]; - Geom::Coord posY = Geom::middle_point(Geom::Point(bbox->left(), bbox->top()), Geom::Point(bbox->left(), bbox->bottom()))[Geom::Y]; - text_item->transform *= Geom::Translate(Geom::Point(posX, posY)).inverse(); - pos = pos + Geom::Point::polar(angle + Geom::deg_to_rad(90), -Geom::distance(Geom::Point(bbox->left(), bbox->top()), Geom::Point(bbox->left(), bbox->bottom()))); + if (!measure_repr && bbox) { + Geom::Point center = bbox->midpoint(); + text_item->transform *= Geom::Translate(center).inverse(); + pos = pos + Geom::Point::polar(angle+ Geom::deg_to_rad(90), -bbox->height()); + } + if(measure_repr) { + /* Create */ + Inkscape::XML::Node *rgroup = xml_doc->createElement("svg:g"); + /* Create */ + Inkscape::XML::Node *rrect = xml_doc->createElement("svg:rect"); + SPCSSAttr *css = sp_repr_css_attr_new (); + gchar c[64]; + sp_svg_write_color (c, sizeof(c), *background); + sp_repr_css_set_property (css, "fill", c); + 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", 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); } - 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); } -void MeasureTool::reset(){ +void MeasureTool::reset() +{ this->knot_start->hide(); this->knot_end->hide(); for (size_t idx = 0; idx < measure_tmp_items.size(); ++idx) { @@ -684,15 +929,19 @@ void MeasureTool::reset(){ measure_tmp_items.clear(); } -void MeasureTool::showCanvasItems(){ +void MeasureTool::showCanvasItems() +{ showCanvasItems(start_p, end_p); } -void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point){ +void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point, bool to_item, Inkscape::XML::Node *measure_repr) +{ SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if(!desktop || !start_point.isFinite() || !end_point.isFinite() || end_point == MAGIC_POINT){ + if(!desktop || !start_point.isFinite() || !end_point.isFinite() || end_point == MAGIC_POINT) { return; } + guint32 line_color_primary = 0x0000ff7f; + guint32 line_color_secondary = 0xff00007f; start_p = start_point; end_p = end_point; //clear previous temporary canvas items, we'll draw new ones @@ -731,7 +980,7 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point std::vector items; Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop); r->setMode(RUBBERBAND_MODE_TOUCHPATH); - if(!show_in_between){ + if(!show_in_between) { r->start(desktop,start_p); r->move(end_p); items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints(), all_layers, 2); @@ -741,10 +990,10 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point r->move(start_p); std::vector 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]){ + 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]){ + if(items_reverse.size() >= 1 && items_reverse[0] != items[1]) { items.push_back(items_reverse[0]); } } else { @@ -754,10 +1003,10 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point r->stop(); } std::vector intersection_times; - for (std::vector::const_iterator i=items.begin();i!=items.end();i++) { + for (std::vector::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); + 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(); @@ -802,11 +1051,11 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point std::vector intersections; std::sort(intersection_times.begin(), intersection_times.end()); for (std::vector::iterator iter_t = intersection_times.begin(); iter_t != intersection_times.end(); iter_t++) { - if(show_in_between){ + if(show_in_between) { intersections.push_back(lineseg[0].pointAt(*iter_t)); } } - if(!show_in_between && intersection_times.size() > 1){ + 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])); } @@ -828,47 +1077,52 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point // Adjust positions repositionOverlappingLabels(placements, desktop, windowNormal, fontsize); - for (std::vector::iterator it = placements.begin(); it != placements.end(); ++it) - { + for (std::vector::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); + 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)); + if(to_item) { + guint32 background = canvas_tooltip->rgba_background; + setLabelText(measure_str, place.end, fontsize, 0, &background, measure_repr); + } g_free(measure_str); } Geom::Point angleDisplayPt = calcAngleDisplayAnchor(desktop, angle, baseAngle, - start_point, end_point, - fontsize); + 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); + 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)); + if(to_item) { + guint32 background = canvas_tooltip->rgba_background; + setLabelText(angle_str, angleDisplayPt, fontsize, 0, &background, measure_repr); + } g_free(angle_str); } @@ -879,17 +1133,20 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point // 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); + 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)); + if(to_item) { + guint32 background = canvas_tooltip->rgba_background; + setLabelText(totallength_str, end_point + desktop->w2d(Geom::Point(3*fontsize, -fontsize)), fontsize, 0, &background, measure_repr, TEXT_ANCHOR_LEFT); + } g_free(totallength_str); } @@ -900,44 +1157,68 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point // 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 * (dimension_offset * 2), - total_str); + desktop, + desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * (dimension_offset * 2), + 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)); + if(to_item) { + guint32 background = canvas_tooltip->rgba_background; + setLabelText(total_str, desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * (dimension_offset * 2), fontsize, 0, &background, measure_repr); + } g_free(total_str); } + // 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)); + if(to_item) { + setPoint(start_point, 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_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)); + if(to_item) { + setPoint(desktop->doc2dt(intersections[idx]), measure_repr); + } } - // 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); + 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])) { @@ -951,12 +1232,18 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point } SPCtrlLine *control_line = ControlManager::getManager().createControlLine(desktop->getTempGroup(), - start_point, - anchorEnd, - CTLINE_SECONDARY); + 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); + if(to_item) { + setLine(start_point, + anchorEnd, + false, + &line_color_secondary, + measure_repr); + } + createAngleDisplayCurve(desktop, start_point, end_point, angleDisplayPt, angle, measure_repr); } } @@ -967,29 +1254,50 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2), desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2)); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); - + if(to_item) { + setLine(desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2), + desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2), + false, + &line_color_primary, + measure_repr); + } control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(intersections[0]), desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2)); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); - + if(to_item) { + setLine(desktop->doc2dt(intersections[0]), + desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2), + false, + &line_color_primary, + measure_repr); + } control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(intersections[intersections.size() - 1]), desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2)); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); + if(to_item) { + setLine(desktop->doc2dt(intersections[intersections.size() - 1]), + desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2), + false, + &line_color_primary, + measure_repr); + } } // call-out lines - for (std::vector::iterator it = placements.begin(); it != placements.end(); ++it) - { + for (std::vector::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); + place.start, + place.end, + CTLINE_SECONDARY); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); + if(to_item) { + setLine(place.start,place.end, false, &line_color_secondary, measure_repr); + } } { @@ -998,28 +1306,19 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point 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); + 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)); + if(to_item) { + setLine(desktop->doc2dt(measure_text_pos), + desktop->doc2dt(measure_text_pos) - (normal * dimension_offset), + false, + &line_color_secondary, + 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)); - } } } } diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index 0670fb9f7..ee45c18e5 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -6,7 +6,7 @@ * * Authors: * Felipe Correa da Silva Sanches - * + * Jabiertxo Arraiza * Copyright (C) 2011 Authors * * Released under GNU GPL, read the file 'COPYING' for more information @@ -15,6 +15,7 @@ #include #include "ui/tools/tool-base.h" #include <2geom/point.h> +#include "display/canvas-text.h" #include #define SP_MEASURE_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) @@ -36,14 +37,17 @@ public: virtual void finish(); virtual bool root_handler(GdkEvent* event); virtual void showCanvasItems(); - virtual void showCanvasItems(Geom::Point start_point, Geom::Point end_point); + virtual void showCanvasItems(Geom::Point start_point, Geom::Point end_point, bool to_item = false, Inkscape::XML::Node *measure_repr = NULL); virtual void reverseKnots(); virtual void toMarkDimension(); + virtual void toItem(); virtual void reset(); virtual void setMarkers(); virtual void setMarker(bool isStart); virtual const std::string& getPrefsPath(); - void setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle); + void setPoint(Geom::Point origin, Inkscape::XML::Node *measure_repr); + void setLine(Geom::Point start_point,Geom::Point end_point, bool markers = false, guint32 *color = NULL, Inkscape::XML::Node *measure_repr = NULL); + void setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle, guint32 *background = NULL, 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*/); @@ -66,3 +70,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/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 9c782b4b6..48c781fb3 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -178,6 +178,13 @@ static void sp_to_mark_dimension(void){ } } +static void sp_to_item(void){ + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->toItem(); + } +} + void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* holder) { UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); @@ -283,6 +290,16 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_mark_dimension), 0 ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } + //to item + { + InkAction* act = ink_action_new( "MeasureToItem", + _("Convert to item"), + _("Convert to item"), + INKSCAPE_ICON("path-reverse"), + secondarySize ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_item), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } } // end of sp_measure_toolbox_prep() diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 3daa3c467..665502745 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -348,6 +348,7 @@ static gchar const * ui_descr = " " " " " " + " " " " " " -- cgit v1.2.3 From f586b5aeb837df4cd4e3aac55c0e0fcba4ae54fa Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 12 Oct 2015 13:48:06 +0200 Subject: Fix position of text when 'direction' is 'rtl' (right-to-left). (bzr r14405) --- src/libnrtype/Layout-TNG-Compute.cpp | 28 ++++++++++++++++++++++------ src/libnrtype/Layout-TNG-Input.cpp | 6 +++--- 2 files changed, 25 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index d81e1b6b4..c4b0a5bee 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -24,15 +24,31 @@ namespace Text { #define TRACE(_args) IFTRACE(g_print _args) // ******* enum conversion tables + +// These enums are probably from the SVG 1.0 era where one could interpret 'writing-mode' as setting direction. +// SVG 1.1 makes it clear that 'direction' should be used. 'direction' has only two values 'ltr' and 'rtl'. +// The first two values for the 'writing-mode' enum just happen to match the first two value of 'direction' so the +// existing code worked when 'writing-mode' was changed to 'direction'. +// static Layout::EnumConversionItem const enum_convert_spstyle_direction_to_pango_direction[] = { +// {SP_CSS_WRITING_MODE_LR_TB, PANGO_DIRECTION_LTR}, +// {SP_CSS_WRITING_MODE_RL_TB, PANGO_DIRECTION_RTL}, +// {SP_CSS_WRITING_MODE_TB_LR, PANGO_DIRECTION_LTR}}; // this is correct + +// static Layout::EnumConversionItem const enum_convert_spstyle_direction_to_my_direction[] = { +// {SP_CSS_WRITING_MODE_LR_TB, Layout::LEFT_TO_RIGHT}, +// {SP_CSS_WRITING_MODE_RL_TB, Layout::RIGHT_TO_LEFT}, +// {SP_CSS_WRITING_MODE_TB_LR, Layout::LEFT_TO_RIGHT}}; // this is correct + +// Proper 'direction' enums static Layout::EnumConversionItem const enum_convert_spstyle_direction_to_pango_direction[] = { - {SP_CSS_WRITING_MODE_LR_TB, PANGO_DIRECTION_LTR}, - {SP_CSS_WRITING_MODE_RL_TB, PANGO_DIRECTION_RTL}, - {SP_CSS_WRITING_MODE_TB_LR, PANGO_DIRECTION_LTR}}; // this is correct + {SP_CSS_DIRECTION_LTR, PANGO_DIRECTION_LTR}, + {SP_CSS_DIRECTION_RTL, PANGO_DIRECTION_RTL}}; static Layout::EnumConversionItem const enum_convert_spstyle_direction_to_my_direction[] = { - {SP_CSS_WRITING_MODE_LR_TB, Layout::LEFT_TO_RIGHT}, - {SP_CSS_WRITING_MODE_RL_TB, Layout::RIGHT_TO_LEFT}, - {SP_CSS_WRITING_MODE_TB_LR, Layout::LEFT_TO_RIGHT}}; // this is correct + {SP_CSS_DIRECTION_LTR, Layout::LEFT_TO_RIGHT}, + {SP_CSS_DIRECTION_RTL, Layout::RIGHT_TO_LEFT}}; + + /** \brief private to Layout. Does the real work of text flowing. diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index 84f3f260e..c9cfe81cc 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -202,13 +202,13 @@ Layout::Direction Layout::InputStreamTextSource::styleGetBlockProgression() cons } -static Layout::Alignment text_anchor_to_alignment(unsigned anchor, Layout::Direction /*para_direction*/) +static Layout::Alignment text_anchor_to_alignment(unsigned anchor, Layout::Direction para_direction) { switch (anchor) { default: - case SP_CSS_TEXT_ANCHOR_START: return Layout::LEFT; + case SP_CSS_TEXT_ANCHOR_START: return para_direction == Layout::LEFT_TO_RIGHT ? Layout::LEFT : Layout::RIGHT; case SP_CSS_TEXT_ANCHOR_MIDDLE: return Layout::CENTER; - case SP_CSS_TEXT_ANCHOR_END: return Layout::RIGHT; + case SP_CSS_TEXT_ANCHOR_END: return para_direction == Layout::LEFT_TO_RIGHT ? Layout::RIGHT : Layout::LEFT; } } -- cgit v1.2.3 From 328132ad756f7b094341c52175d184449155fe0f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 12 Oct 2015 18:08:22 +0200 Subject: Fix positions of genetated intersection items (bzr r14393.1.19) --- src/ui/tools/measure-tool.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 76b8e931e..00d66b4c9 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -733,7 +733,7 @@ void MeasureTool::setLine(Geom::Point start_point,Geom::Point end_point, bool ma } else { sp_repr_css_set_property (css, "stroke", "#000000"); } - sp_repr_css_set_property (css, "stroke-linecap", "butt"); + sp_repr_css_set_property (css, "stroke-linecap", "square"); 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"); @@ -770,12 +770,12 @@ void MeasureTool::setPoint(Geom::Point origin, Inkscape::XML::Node *measure_repr return; } char const * svgd; - svgd = "m -3.55,-3.55 7.11,7.11 m 0,-7.11 -7.11,7.11"; + svgd = "m 0.707,0.707 6.586,6.586 m 0,-6.586 -6.586,6.586"; Geom::PathVector c = sp_svg_read_pathv(svgd); Geom::Scale scale = Geom::Scale(desktop->current_zoom()).inverse(); + c *= Geom::Translate(Geom::Point(-3.5,-3.5)); c *= scale; - Geom::Point strokewidth = (Geom::Point(1,1) * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse())/ desktop->current_zoom(); - c *= Geom::Translate(Geom::Point(strokewidth/2.0) - (scale.vector() * 0.5)); + c *= Geom::Translate(Geom::Point() - (scale.vector() * 0.5)); c *= Geom::Translate(desktop->doc2dt(origin)); c *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); SPDocument *doc = desktop->getDocument(); @@ -785,6 +785,7 @@ void MeasureTool::setPoint(Geom::Point origin, Inkscape::XML::Node *measure_repr repr = xml_doc->createElement("svg:path"); gchar const *str = sp_svg_write_path(c); SPCSSAttr *css = sp_repr_css_attr_new(); + Geom::Point strokewidth = (Geom::Point(1,1) * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse())/ desktop->current_zoom(); std::stringstream stroke_width; stroke_width.imbue(std::locale::classic()); stroke_width << strokewidth[Geom::X]; @@ -794,7 +795,7 @@ void MeasureTool::setPoint(Geom::Point origin, Inkscape::XML::Node *measure_repr gchar c[64]; sp_svg_write_color (c, sizeof(c), line_color_secondary); sp_repr_css_set_property (css, "stroke", c); - sp_repr_css_set_property (css, "stroke-linecap", "butt"); + sp_repr_css_set_property (css, "stroke-linecap", "square"); 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"); -- cgit v1.2.3 From af1bbe5ddd52aef9e74a778006b01b3a0e249e5d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 13 Oct 2015 12:11:48 +0200 Subject: Fix position node splited Added parameter to Symm move nodes, Todo:Get better english strings (bzr r14407) --- src/live_effects/lpe-roughen.cpp | 125 +++++++++++++++++++++++++++++++++------ src/live_effects/lpe-roughen.h | 7 ++- 2 files changed, 111 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 33ffd96d6..108b34a26 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -49,8 +49,10 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) "global_randomize", &wr, this, 1.), shift_nodes(_("Shift nodes"), _("Shift nodes"), "shift_nodes", &wr, this, true), - shift_node_handles(_("Shift node handles"), _("Shift node handles"), - "shift_node_handles", &wr, this, true) + shift_handles(_("Shift node handles"), _("Shift node handles"), + "shift_handles", &wr, this, true), + shift_handles_sym(_("Sym shift node handles"), _("Sym shift node handles"), + "shift_handles_sym", &wr, this, false) { registerParameter(&method); registerParameter(&max_segment_size); @@ -59,7 +61,8 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) registerParameter(&displace_y); registerParameter(&global_randomize); registerParameter(&shift_nodes); - registerParameter(&shift_node_handles); + registerParameter(&shift_handles); + registerParameter(&shift_handles_sym); displace_x.param_set_range(0., Geom::infinity()); displace_y.param_set_range(0., Geom::infinity()); global_randomize.param_set_range(0., Geom::infinity()); @@ -170,6 +173,7 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); Geom::Path::const_iterator curve_endit = path_it->end_default(); SPCurve *nCurve = new SPCurve(); + Geom::Point prev(0, 0); if (path_it->closed()) { const Geom::Curve &closingline = path_it->back_closed(); @@ -212,18 +216,26 @@ void LPERoughen::doEffect(SPCurve *curve) } else { splits = ceil(length / max_segment_size); } - for (unsigned int t = splits; t >= 1; t--) { - if (t == 1 && splits != 1) { + Geom::Curve const * original = nCurve->last_segment()->duplicate() ; + for (unsigned int t = 1; t <= splits; t++) { + if(t == splits && splits != 1){ continue; } - const SPCurve *tmp; + SPCurve const * tmp; if (splits == 1) { tmp = jitter(nCurve->last_segment()); } else { - tmp = addNodesAndJitter(nCurve->last_segment(), 1. / t); + bool last = false; + if(t == splits-1){ + last = true; + } + double time = Geom::nearest_time(original->pointAt((1. / (double)splits) * t), *nCurve->last_segment()); + tmp = addNodesAndJitter(nCurve->last_segment(), prev, time, last); } if (nCurve->get_segment_count() > 1) { - nCurve->backspace(); + if(t!= splits){ + nCurve->backspace(); + } nCurve->append_continuous(tmp, 0.001); } else { nCurve = tmp->copy(); @@ -237,6 +249,27 @@ void LPERoughen::doEffect(SPCurve *curve) first = false; } if (path_it->closed()) { + if(shift_handles_sym && curve_it2 == curve_endit){ + SPCurve *out = new SPCurve(); + nCurve = nCurve->create_reverse(); + Geom::CubicBezier const *cubic_start = dynamic_cast(nCurve->first_segment()); + Geom::CubicBezier const *cubic = dynamic_cast(nCurve->last_segment()); + Geom::Point oposite = nCurve->first_segment()->initialPoint(); + if(cubic_start){ + Geom::Ray ray((*cubic_start)[1], (*cubic_start)[0]); + double dist = Geom::distance((*cubic_start)[1], (*cubic_start)[0]); + oposite = Geom::Point::polar(ray.angle(),dist) + (*cubic_start)[0]; + } + if(cubic){ + out->moveto((*cubic)[0]); + out->curveto((*cubic)[1], oposite, (*cubic)[3]); + } else { + out->moveto(nCurve->last_segment()->initialPoint()); + out->curveto(nCurve->last_segment()->initialPoint(), oposite, nCurve->last_segment()->finalPoint()); + } + nCurve->backspace(); + nCurve->append_continuous(out, 0.001); + } nCurve->closepath_current(); } curve->append(nCurve, false); @@ -245,7 +278,7 @@ void LPERoughen::doEffect(SPCurve *curve) } } -SPCurve *LPERoughen::addNodesAndJitter(const Geom::Curve *A, double t) +SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last) { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast(&*A); @@ -259,38 +292,94 @@ SPCurve *LPERoughen::addNodesAndJitter(const Geom::Curve *A, double t) point3 = randomize(); point_b3 = randomize(); } - if (shift_node_handles) { + if (shift_handles && !shift_handles_sym) { point1 = randomize(); point2 = randomize(); point_b1 = randomize(); point_b2 = randomize(); - } else { + } else if(shift_handles_sym) { + Geom::Ray ray(prev,A->initialPoint()); + double dist = Geom::distance(prev, A->initialPoint()); + point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint(); + if(prev==Geom::Point(0,0)){ + point1 = A->pointAt(t / 3) + randomize(); + } + point2 = A->pointAt((t / 3) * 2) + randomize(); + Geom::Ray ray2(point2, point3); + double dist2 = Geom::distance(point2, point3); + point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3; + point1 = point1 - A->pointAt(t / 3); + point2 = point2 - A->pointAt((t / 3) * 2); + point_b1 = randomize(); + point_b2 = randomize(); + }else { point2 = point3; point_b1 = point3; point_b2 = point_b3; } - if (cubic) { + if(shift_handles_sym && cubic) { + std::pair div = cubic->subdivide(t); + std::vector seg1 = div.first.controlPoints(), + seg2 = div.second.controlPoints(); + out->moveto(seg1[0]); + Geom::Ray ray(prev,A->initialPoint()); + double dist = Geom::distance(seg1[1], A->initialPoint()); + point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint(); + point2 = seg1[2] + point2; + point3 = seg1[3] + point3; + if(prev==Geom::Point(0,0)){ + point1 = seg1[1] + randomize(); + } + out->curveto(point1, point2, point3); + + Geom::Ray ray2(point2, point3); + double dist2 = Geom::distance(seg2[1], point3); + point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3; + point_b2 = seg2[2]; + out->curveto(point_b1, point_b2, seg2[3]); + } else if(shift_handles_sym && !cubic) { + out->moveto(A->initialPoint()); + Geom::Ray ray(prev,A->initialPoint()); + double dist = Geom::distance(A->pointAt(t / 3) + randomize(), A->initialPoint()); + point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint(); + point2 = A->pointAt((t / 3) * 2) + point2; + point3 = A->pointAt(t) + point3; + if(prev==Geom::Point(0,0)){ + point1 = A->pointAt(t / 3) + randomize(); + } + out->curveto(point1, point2, point3); + Geom::Ray ray2(point2, point3); + double dist2 = Geom::distance(A->pointAt(t + ((t / 3) * 2)) + point_b2, point3); + point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3; + point_b2 = A->pointAt(t + ((t / 3) * 2)) + point_b2; + out->curveto(point_b1, point_b2, A->finalPoint()); + } else if (cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); out->moveto(seg1[0]); out->curveto(seg1[1] + point1, seg1[2] + point2, seg1[3] + point3); out->curveto(seg2[1] + point_b1, seg2[2], seg2[3]); - } else if (shift_node_handles) { + } else if (shift_handles) { out->moveto(A->initialPoint()); out->curveto(A->pointAt(t / 3) + point1, A->pointAt((t / 3) * 2) + point2, A->pointAt(t) + point3); - out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t + ((t / 3) * 2)), - A->finalPoint()); + out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t + ((t / 3) * 2)) + point_b2, + A->finalPoint()); } else { out->moveto(A->initialPoint()); out->lineto(A->pointAt(t) + point3); out->lineto(A->finalPoint()); } + if(last){ + prev = point_b2; + } else { + prev = point2; + } return out; } -SPCurve *LPERoughen::jitter(const Geom::Curve *A) +SPCurve *LPERoughen::jitter(Geom::Curve const * A) { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast(&*A); @@ -300,7 +389,7 @@ SPCurve *LPERoughen::jitter(const Geom::Curve *A) if (shift_nodes) { point3 = randomize(); } - if (shift_node_handles) { + if (shift_handles) { point1 = randomize(); point2 = randomize(); } else { @@ -309,7 +398,7 @@ SPCurve *LPERoughen::jitter(const Geom::Curve *A) if (cubic) { out->moveto((*cubic)[0]); out->curveto((*cubic)[1] + point1, (*cubic)[2] + point2, (*cubic)[3] + point3); - } else if (shift_node_handles) { + } else if (shift_handles) { out->moveto(A->initialPoint()); out->curveto(A->pointAt(0.3333) + point1, A->pointAt(0.6666) + point2, A->finalPoint() + point3); diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index 2b285cd40..8241cedca 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -38,8 +38,8 @@ public: virtual double sign(double randNumber); virtual Geom::Point randomize(); virtual void doBeforeEffect(SPLPEItem const * lpeitem); - virtual SPCurve *addNodesAndJitter(const Geom::Curve *A, double t); - virtual SPCurve *jitter(const Geom::Curve *A); + virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last); + virtual SPCurve *jitter(Geom::Curve const * A); virtual Geom::Point tPoint(Geom::Point A, Geom::Point B, double t = 0.5); virtual Gtk::Widget *newWidget(); @@ -51,7 +51,8 @@ private: RandomParam displace_y; RandomParam global_randomize; BoolParam shift_nodes; - BoolParam shift_node_handles; + BoolParam shift_handles; + BoolParam shift_handles_sym; LPERoughen(const LPERoughen &); LPERoughen &operator=(const LPERoughen &); -- cgit v1.2.3 From f886fd682e7e4ea2622fbb523dc3a14ba75569a3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 13 Oct 2015 22:09:54 +0200 Subject: Added a parameter to roughen LPE to allow fixed displacement of points (bzr r14408) --- src/live_effects/lpe-roughen.cpp | 235 +++++++++++++++++++++------------------ src/live_effects/lpe-roughen.h | 5 +- 2 files changed, 127 insertions(+), 113 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 108b34a26..6f24c288d 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -52,7 +52,9 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) shift_handles(_("Shift node handles"), _("Shift node handles"), "shift_handles", &wr, this, true), shift_handles_sym(_("Sym shift node handles"), _("Sym shift node handles"), - "shift_handles_sym", &wr, this, false) + "shift_handles_sym", &wr, this, false), + fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment lenght"), + "fixed_displacement", &wr, this, false) { registerParameter(&method); registerParameter(&max_segment_size); @@ -63,6 +65,7 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) registerParameter(&shift_nodes); registerParameter(&shift_handles); registerParameter(&shift_handles_sym); + registerParameter(&fixed_displacement); displace_x.param_set_range(0., Geom::infinity()); displace_y.param_set_range(0., Geom::infinity()); global_randomize.param_set_range(0., Geom::infinity()); @@ -150,12 +153,15 @@ double LPERoughen::sign(double random_number) return random_number; } -Geom::Point LPERoughen::randomize() +Geom::Point LPERoughen::randomize(double max_lenght) { double displace_x_parsed = displace_x * global_randomize; double displace_y_parsed = displace_y * global_randomize; - Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed)); + if( fixed_displacement ){ + Geom::Ray ray(Geom::Point(0,0),output); + output = Geom::Point::polar(ray.angle(), max_lenght); + } return output; } @@ -181,33 +187,24 @@ void LPERoughen::doEffect(SPCurve *curve) curve_endit = path_it->end_open(); } } - Geom::Point initialMove(0, 0); - if (shift_nodes) { - initialMove = randomize(); - } - Geom::Point initialPoint = curve_it1->initialPoint() + initialMove; - nCurve->moveto(initialPoint); + nCurve->moveto(curve_it1->initialPoint()); Geom::Point point0(0, 0); - Geom::Point point1(0, 0); - Geom::Point point2(0, 0); - Geom::Point point3(0, 0); - bool first = true; + Geom::Point point_a1(0, 0); + Geom::Point point_a2(0, 0); + Geom::Point point_a3(0, 0); while (curve_it1 != curve_endit) { Geom::CubicBezier const *cubic = NULL; point0 = curve_it1->initialPoint(); - point1 = curve_it1->initialPoint(); - point2 = curve_it1->finalPoint(); - point3 = curve_it1->finalPoint(); + point_a1 = curve_it1->initialPoint(); + point_a2 = curve_it1->finalPoint(); + point_a3 = curve_it1->finalPoint(); cubic = dynamic_cast(&*curve_it1); if (cubic) { - point1 = (*cubic)[1]; - if (shift_nodes && first) { - point1 = (*cubic)[1] + initialMove; - } - point2 = (*cubic)[2]; - nCurve->curveto(point1, point2, point3); + point_a1 = (*cubic)[1]; + point_a2 = (*cubic)[2]; + nCurve->curveto(point_a1, point_a2, point_a3); } else { - nCurve->lineto(point3); + nCurve->lineto(point_a3); } double length = curve_it1->length(0.001); std::size_t splits = 0; @@ -223,7 +220,7 @@ void LPERoughen::doEffect(SPCurve *curve) } SPCurve const * tmp; if (splits == 1) { - tmp = jitter(nCurve->last_segment()); + tmp = jitter(nCurve->last_segment(), prev); } else { bool last = false; if(t == splits-1){ @@ -233,9 +230,7 @@ void LPERoughen::doEffect(SPCurve *curve) tmp = addNodesAndJitter(nCurve->last_segment(), prev, time, last); } if (nCurve->get_segment_count() > 1) { - if(t!= splits){ - nCurve->backspace(); - } + nCurve->backspace(); nCurve->append_continuous(tmp, 0.001); } else { nCurve = tmp->copy(); @@ -246,7 +241,6 @@ void LPERoughen::doEffect(SPCurve *curve) if(curve_it2 != curve_endit) { ++curve_it2; } - first = false; } if (path_it->closed()) { if(shift_handles_sym && curve_it2 == curve_endit){ @@ -254,7 +248,7 @@ void LPERoughen::doEffect(SPCurve *curve) nCurve = nCurve->create_reverse(); Geom::CubicBezier const *cubic_start = dynamic_cast(nCurve->first_segment()); Geom::CubicBezier const *cubic = dynamic_cast(nCurve->last_segment()); - Geom::Point oposite = nCurve->first_segment()->initialPoint(); + Geom::Point oposite = nCurve->first_segment()->pointAt(1.0/3.0); if(cubic_start){ Geom::Ray ray((*cubic_start)[1], (*cubic_start)[0]); double dist = Geom::distance((*cubic_start)[1], (*cubic_start)[0]); @@ -269,7 +263,9 @@ void LPERoughen::doEffect(SPCurve *curve) } nCurve->backspace(); nCurve->append_continuous(out, 0.001); + nCurve = nCurve->create_reverse(); } + nCurve->move_endpoints(nCurve->last_segment()->finalPoint(), nCurve->last_segment()->finalPoint()); nCurve->closepath_current(); } curve->append(nCurve, false); @@ -282,129 +278,146 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast(&*A); - Geom::Point point1(0, 0); - Geom::Point point2(0, 0); - Geom::Point point3(0, 0); + double max_lenght = Geom::distance(A->initialPoint(),A->pointAt(t)) / 3.0; + Geom::Point point_a1(0, 0); + Geom::Point point_a2(0, 0); + Geom::Point point_a3(0, 0); Geom::Point point_b1(0, 0); Geom::Point point_b2(0, 0); Geom::Point point_b3(0, 0); if (shift_nodes) { - point3 = randomize(); - point_b3 = randomize(); + point_a3 = randomize(max_lenght); + if(last){ + point_b3 = randomize(max_lenght); + } } - if (shift_handles && !shift_handles_sym) { - point1 = randomize(); - point2 = randomize(); - point_b1 = randomize(); - point_b2 = randomize(); - } else if(shift_handles_sym) { - Geom::Ray ray(prev,A->initialPoint()); - double dist = Geom::distance(prev, A->initialPoint()); - point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint(); - if(prev==Geom::Point(0,0)){ - point1 = A->pointAt(t / 3) + randomize(); + if (shift_handles || shift_handles_sym) { + point_a1 = randomize(max_lenght); + point_a2 = randomize(max_lenght); + point_b1 = randomize(max_lenght); + if(last){ + point_b2 = randomize(max_lenght); + } + } else { + point_a2 = point_a3; + point_b1 = point_a3; + if(last){ + point_b2 = point_b3; } - point2 = A->pointAt((t / 3) * 2) + randomize(); - Geom::Ray ray2(point2, point3); - double dist2 = Geom::distance(point2, point3); - point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3; - point1 = point1 - A->pointAt(t / 3); - point2 = point2 - A->pointAt((t / 3) * 2); - point_b1 = randomize(); - point_b2 = randomize(); - }else { - point2 = point3; - point_b1 = point3; - point_b2 = point_b3; } if(shift_handles_sym && cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); - out->moveto(seg1[0]); Geom::Ray ray(prev,A->initialPoint()); - double dist = Geom::distance(seg1[1], A->initialPoint()); - point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint(); - point2 = seg1[2] + point2; - point3 = seg1[3] + point3; - if(prev==Geom::Point(0,0)){ - point1 = seg1[1] + randomize(); + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + if(prev == Geom::Point(0,0)){ + point_a1 = randomize(max_lenght); + } + if(last){ + prev = A->pointAt(1 - (t / 3)) + point_b2; + } else { + point_b3 = Geom::Point(0,0); + point_b2 = Geom::Point(0,0); + } + Geom::Ray ray2(seg2[1] + point_b1, seg1[3] + point_a3); + point_a2 = Geom::Point::polar(ray2.angle(), max_lenght); + if(!last){ + prev = seg1[3] + point_a3 + point_a2; + } + out->moveto(seg1[0]); + out->curveto(seg1[0] + point_a1, seg1[3] + point_a3 + point_a2, seg1[3] + point_a3); + if(last){ + out->curveto(seg2[1] + point_b1, A->pointAt(1 - (t / 3)) + point_b2, seg2[3] + point_b3); + } else { + out->curveto(seg2[1] + point_b1, seg2[2] + point_b2, seg2[3] + point_b3); } - out->curveto(point1, point2, point3); - - Geom::Ray ray2(point2, point3); - double dist2 = Geom::distance(seg2[1], point3); - point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3; - point_b2 = seg2[2]; - out->curveto(point_b1, point_b2, seg2[3]); } else if(shift_handles_sym && !cubic) { - out->moveto(A->initialPoint()); Geom::Ray ray(prev,A->initialPoint()); - double dist = Geom::distance(A->pointAt(t / 3) + randomize(), A->initialPoint()); - point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint(); - point2 = A->pointAt((t / 3) * 2) + point2; - point3 = A->pointAt(t) + point3; + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); if(prev==Geom::Point(0,0)){ - point1 = A->pointAt(t / 3) + randomize(); + point_a1 = randomize(max_lenght); + } + if(last){ + prev = A->pointAt(1 - (t / 3)) + point_b2; + } else { + point_b3 = Geom::Point(0,0); + point_b2 = Geom::Point(0,0); + } + Geom::Ray ray2(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t) + point_a3); + point_a2 = Geom::Point::polar(ray2.angle(), max_lenght); + if(!last){ + prev = A->pointAt((t / 3) * 2) + point_a2; + } + out->moveto(A->initialPoint()); + out->curveto(A->initialPoint() + point_a1, A->pointAt(t) + point_a3 + point_a2, A->pointAt(t) + point_a3); + if(last){ + out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(1 - (t / 3)) + point_b2, A->finalPoint() + point_b3); + } else { + out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2, A->finalPoint() + point_b3); } - out->curveto(point1, point2, point3); - Geom::Ray ray2(point2, point3); - double dist2 = Geom::distance(A->pointAt(t + ((t / 3) * 2)) + point_b2, point3); - point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3; - point_b2 = A->pointAt(t + ((t / 3) * 2)) + point_b2; - out->curveto(point_b1, point_b2, A->finalPoint()); } else if (cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); out->moveto(seg1[0]); - out->curveto(seg1[1] + point1, seg1[2] + point2, seg1[3] + point3); - out->curveto(seg2[1] + point_b1, seg2[2], seg2[3]); + out->curveto(seg1[1] + point_a1, seg1[2] + point_a2, seg1[3] + point_a3); + out->curveto(seg2[1] + point_b1, seg2[2] + point_b2, seg2[3] + point_b3); } else if (shift_handles) { out->moveto(A->initialPoint()); - out->curveto(A->pointAt(t / 3) + point1, A->pointAt((t / 3) * 2) + point2, - A->pointAt(t) + point3); - out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t + ((t / 3) * 2)) + point_b2, - A->finalPoint()); + out->curveto(A->pointAt(t / 3) + point_a1, A->pointAt((t / 3) * 2) + point_a2, A->pointAt(t) + point_a3); + out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2, A->finalPoint() + point_b3); } else { out->moveto(A->initialPoint()); - out->lineto(A->pointAt(t) + point3); - out->lineto(A->finalPoint()); - } - if(last){ - prev = point_b2; - } else { - prev = point2; + out->lineto(A->pointAt(t) + point_a3); + out->lineto(A->finalPoint() + point_b3); } return out; } -SPCurve *LPERoughen::jitter(Geom::Curve const * A) +SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev) { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast(&*A); - Geom::Point point1(0, 0); - Geom::Point point2(0, 0); - Geom::Point point3(0, 0); + double max_lenght = Geom::distance(A->initialPoint(),A->finalPoint()) / 3.0; + Geom::Point point_a1(0, 0); + Geom::Point point_a2(0, 0); + Geom::Point point_a3(0, 0); if (shift_nodes) { - point3 = randomize(); + point_a3 = randomize(max_lenght); } - if (shift_handles) { - point1 = randomize(); - point2 = randomize(); - } else { - point2 = point3; + if (shift_handles || shift_handles_sym) { + point_a1 = randomize(max_lenght); + point_a2 = randomize(max_lenght); } - if (cubic) { + if(shift_handles_sym && cubic) { + Geom::Ray ray(prev,A->initialPoint()); + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + if(prev == Geom::Point(0,0)){ + point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); + } + prev = (*cubic)[2] + point_a2; + out->moveto((*cubic)[0]); + out->curveto((*cubic)[0] + point_a1, (*cubic)[2] + point_a2, (*cubic)[3] + point_a3); + } else if(shift_handles_sym && !cubic) { + Geom::Ray ray(prev,A->initialPoint()); + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + if(prev==Geom::Point(0,0)){ + point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); + } + prev = A->pointAt((1.0/3.0) * 2) + point_a2; + out->moveto(A->initialPoint()); + out->curveto(A->initialPoint() + point_a1, A->pointAt((1.0/3.0) * 2) + point_a2, A->finalPoint() + point_a3); + } else if (cubic) { out->moveto((*cubic)[0]); - out->curveto((*cubic)[1] + point1, (*cubic)[2] + point2, (*cubic)[3] + point3); + out->curveto((*cubic)[1] + point_a1, (*cubic)[2] + point_a2, (*cubic)[3] + point_a3); } else if (shift_handles) { out->moveto(A->initialPoint()); - out->curveto(A->pointAt(0.3333) + point1, A->pointAt(0.6666) + point2, - A->finalPoint() + point3); + out->curveto(A->pointAt(0.3333) + point_a1, A->pointAt(0.6666) + point_a2, + A->finalPoint() + point_a3); } else { out->moveto(A->initialPoint()); - out->lineto(A->finalPoint() + point3); + out->lineto(A->finalPoint() + point_a3); } return out; } diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index 8241cedca..e221e95fb 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -36,10 +36,10 @@ public: virtual void doEffect(SPCurve *curve); virtual double sign(double randNumber); - virtual Geom::Point randomize(); + virtual Geom::Point randomize(double max_lenght); virtual void doBeforeEffect(SPLPEItem const * lpeitem); virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last); - virtual SPCurve *jitter(Geom::Curve const * A); + virtual SPCurve *jitter(Geom::Curve const * A, Geom::Point &prev); virtual Geom::Point tPoint(Geom::Point A, Geom::Point B, double t = 0.5); virtual Gtk::Widget *newWidget(); @@ -53,6 +53,7 @@ private: BoolParam shift_nodes; BoolParam shift_handles; BoolParam shift_handles_sym; + BoolParam fixed_displacement; LPERoughen(const LPERoughen &); LPERoughen &operator=(const LPERoughen &); -- cgit v1.2.3 From bdf7f8acb13e3c1920307674e3fea3cbca8ba12e Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 14 Oct 2015 13:20:09 +0200 Subject: Fix from Johan to prevent referencing null C++ pointer. Found via Clang scan build. (bzr r14409) --- src/widgets/gradient-vector.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index 259d4c9af..8e92f589a 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -842,7 +842,8 @@ static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *s GtkWidget *vb, *w, *f; - g_return_val_if_fail(!gradient || SP_IS_GRADIENT(gradient), NULL); + g_return_val_if_fail(gradient != NULL, NULL); + g_return_val_if_fail(SP_IS_GRADIENT(gradient), NULL); #if GTK_CHECK_VERSION(3,0,0) vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, PAD); -- cgit v1.2.3 From d6926d4ffcd9fdf0c1e69fb3bf9397eac0f54f81 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 14 Oct 2015 20:42:56 +0200 Subject: improved results of roughen LPE (bzr r14410) --- src/live_effects/lpe-roughen.cpp | 44 ++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 6f24c288d..dec3f955f 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -314,23 +314,19 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } - if(last){ - prev = A->pointAt(1 - (t / 3)) + point_b2; - } else { - point_b3 = Geom::Point(0,0); - point_b2 = Geom::Point(0,0); - } - Geom::Ray ray2(seg2[1] + point_b1, seg1[3] + point_a3); - point_a2 = Geom::Point::polar(ray2.angle(), max_lenght); + ray.setPoints(seg2[1] + point_a3 + point_b1, seg1[3] + point_a3); + point_a2 = Geom::Point::polar(ray.angle(), max_lenght); if(!last){ prev = seg1[3] + point_a3 + point_a2; + } else { + prev = A->pointAt(1 - (t / 3)) + point_b2 + point_b3; } out->moveto(seg1[0]); - out->curveto(seg1[0] + point_a1, seg1[3] + point_a3 + point_a2, seg1[3] + point_a3); + out->curveto(seg1[0] + point_a1, seg1[2] + point_a3 + point_a2, seg1[3] + point_a3); if(last){ - out->curveto(seg2[1] + point_b1, A->pointAt(1 - (t / 3)) + point_b2, seg2[3] + point_b3); + out->curveto(seg2[1] + point_a3 + point_b1, A->pointAt(1 - (t / 3)) + point_b2 + point_b3, seg2[3] + point_b3); } else { - out->curveto(seg2[1] + point_b1, seg2[2] + point_b2, seg2[3] + point_b3); + out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); } } else if(shift_handles_sym && !cubic) { Geom::Ray ray(prev,A->initialPoint()); @@ -338,35 +334,31 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point if(prev==Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } - if(last){ - prev = A->pointAt(1 - (t / 3)) + point_b2; - } else { - point_b3 = Geom::Point(0,0); - point_b2 = Geom::Point(0,0); - } - Geom::Ray ray2(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t) + point_a3); - point_a2 = Geom::Point::polar(ray2.angle(), max_lenght); + ray.setPoints(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t) + point_a3); + point_a2 = Geom::Point::polar(ray.angle(), max_lenght); if(!last){ prev = A->pointAt((t / 3) * 2) + point_a2; + } else { + prev = A->pointAt(1 - (t / 3)) + point_b2 + point_b3; } out->moveto(A->initialPoint()); - out->curveto(A->initialPoint() + point_a1, A->pointAt(t) + point_a3 + point_a2, A->pointAt(t) + point_a3); + out->curveto(A->initialPoint() + point_a1, A->pointAt((t / 3) * 2) + point_a3 + point_a2, A->pointAt(t) + point_a3); if(last){ - out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(1 - (t / 3)) + point_b2, A->finalPoint() + point_b3); + out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(1 - (t / 3)) + point_b2 + point_b3, A->finalPoint() + point_b3); } else { - out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2, A->finalPoint() + point_b3); + out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); } } else if (cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); out->moveto(seg1[0]); - out->curveto(seg1[1] + point_a1, seg1[2] + point_a2, seg1[3] + point_a3); - out->curveto(seg2[1] + point_b1, seg2[2] + point_b2, seg2[3] + point_b3); + out->curveto(seg1[1] + point_a1, seg1[2] + point_a2 + point_a3, seg1[3] + point_a3); + out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); } else if (shift_handles) { out->moveto(A->initialPoint()); - out->curveto(A->pointAt(t / 3) + point_a1, A->pointAt((t / 3) * 2) + point_a2, A->pointAt(t) + point_a3); - out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2, A->finalPoint() + point_b3); + out->curveto(A->pointAt(t / 3) + point_a1, A->pointAt((t / 3) * 2) + point_a2 + point_a3, A->pointAt(t) + point_a3); + out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); } else { out->moveto(A->initialPoint()); out->lineto(A->pointAt(t) + point_a3); -- cgit v1.2.3 From e49ce373b61fba07422c156090b0ee7553cde18f Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Wed, 14 Oct 2015 21:47:34 +0200 Subject: Fix snapping while rotating a selection Fixed bugs: - https://launchpad.net/bugs/1479167 (bzr r14411) --- src/2geom/path-sink.cpp | 4 ++-- src/object-snapper.cpp | 43 ++++++------------------------------------- src/pure-transform.cpp | 2 +- 3 files changed, 9 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/2geom/path-sink.cpp b/src/2geom/path-sink.cpp index 3b8d407f8..77301b716 100644 --- a/src/2geom/path-sink.cpp +++ b/src/2geom/path-sink.cpp @@ -73,8 +73,8 @@ void PathSink::feed(Rect const &r) { void PathSink::feed(Circle const &e) { Coord r = e.radius(); Point c = e.center(); - Point a = c + Point(0, c[Y] + r); - Point b = c + Point(0, c[Y] - r); + Point a = c + Point(0, +r); + Point b = c + Point(0, -r); moveTo(a); arcTo(r, r, 0, false, false, b); diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 634d56aa6..7302f9de6 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -637,7 +637,6 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(IntermSnapResults &isr, constraint_line.appendNew(p_max_on_cl); constraint_path.push_back(constraint_line); } - // Length of constraint_path will always be one bool strict_snapping = _snapmanager->snapprefs.getStrictSnapping(); @@ -646,45 +645,15 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(IntermSnapResults &isr, for (std::vector::const_iterator k = _paths_to_snap_to->begin(); k != _paths_to_snap_to->end(); ++k) { if (k->path_vector && _allowSourceToSnapToTarget(p.getSourceType(), (*k).target_type, strict_snapping)) { // Do the intersection math - Geom::CrossingSet cs = Geom::crossings(constraint_path, *(k->path_vector)); - // Store the results as intersection points - unsigned int index = 0; - for (Geom::CrossingSet::const_iterator i = cs.begin(); i != cs.end(); ++i) { - if (index >= constraint_path.size()) { - break; - } - // Reconstruct and store the points of intersection - for (Geom::Crossings::const_iterator m = (*i).begin(); m != (*i).end(); ++m) { - intersections.push_back(constraint_path[index].pointAt((*m).ta)); - } - index++; - } - - //Geom::crossings will not consider the closing segment apparently, so we'll handle that separately here - //TODO: This should have been fixed in rev. #9859, which makes this workaround obsolete - for(Geom::PathVector::iterator it_pv = k->path_vector->begin(); it_pv != k->path_vector->end(); ++it_pv) { - if (it_pv->closed()) { - // Get the closing linesegment and convert it to a path - Geom::Path cls; - cls.close(false); - cls.append(it_pv->back_closed()); - // Intersect that closing path with the constrained path - Geom::Crossings cs = Geom::crossings(constraint_path.front(), cls); - // Reconstruct and store the points of intersection - index = 0; // assuming the constraint path vector has only one path - for (Geom::Crossings::const_iterator m = cs.begin(); m != cs.end(); ++m) { - intersections.push_back(constraint_path[index].pointAt((*m).ta)); - } - } - } + std::vector inters = constraint_path.intersect(*(k->path_vector)); - // Convert the collected points of intersection to snapped points - for (std::vector::iterator p_inters = intersections.begin(); p_inters != intersections.end(); ++p_inters) { + // Convert the collected intersections to snapped points + for (std::vector::const_iterator i = inters.begin(); i != inters.end(); ++i) { // Convert to desktop coordinates - (*p_inters) = dt->doc2dt(*p_inters); + Geom::Point p_inters = dt->doc2dt(i->point()); // Construct a snapped point - Geom::Coord dist = Geom::L2(p.getPoint() - *p_inters); - SnappedPoint s = SnappedPoint(*p_inters, p.getSourceType(), p.getSourceNum(), k->target_type, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true, false, k->target_bbox); + Geom::Coord dist = Geom::L2(p.getPoint() - p_inters); + SnappedPoint s = SnappedPoint(p_inters, p.getSourceType(), p.getSourceNum(), k->target_type, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true, false, k->target_bbox); // Store the snapped point if (dist <= tolerance) { // If the intersection is within snapping range, then we might snap to it isr.points.push_back(s); diff --git a/src/pure-transform.cpp b/src/pure-transform.cpp index aa89c8a8e..9c7054b9f 100644 --- a/src/pure-transform.cpp +++ b/src/pure-transform.cpp @@ -63,7 +63,7 @@ void PureTransform::snap(::SnapManager *sm, std::vector todo(owner->hrefList); todo.push_front(owner->parent); while(!todo.empty()){ -- cgit v1.2.3 From b39fc82af6e1320d3c2b301a1639965b04f05fd9 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Thu, 15 Oct 2015 01:13:10 +0200 Subject: clang-format (bzr r14413) --- src/uri-references.cpp | 159 +++++++++++++++++++++++++++---------------------- 1 file changed, 87 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/uri-references.cpp b/src/uri-references.cpp index 0aae9b39d..b6ccdbf5f 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -26,74 +26,91 @@ namespace Inkscape { URIReference::URIReference(SPObject *owner) - : _owner(owner), _owner_document(NULL), _obj(NULL), _uri(NULL) + : _owner(owner) + , _owner_document(NULL) + , _obj(NULL) + , _uri(NULL) { g_assert(_owner != NULL); /* FIXME !!! attach to owner's destroy signal to clean up in case */ } URIReference::URIReference(SPDocument *owner_document) - : _owner(NULL), _owner_document(owner_document), _obj(NULL), _uri(NULL) + : _owner(NULL) + , _owner_document(owner_document) + , _obj(NULL) + , _uri(NULL) { g_assert(_owner_document != NULL); } -URIReference::~URIReference() -{ - detach(); -} +URIReference::~URIReference() { detach(); } /* * The main ideas here are: * (1) "If we are inside a clone, then we can accept if and only if our "original thing" can accept the reference" - * (this caused problems when there are clones because a change in ids triggers signals for the object hrefing this id, but also its cloned reprs - * (descendants of referencing an ancestor of the href'ing object)). The way it is done here is *atrocious*, but i could not find a better way. + * (this caused problems when there are clones because a change in ids triggers signals for the object hrefing this id, + *but also its cloned reprs + * (descendants of referencing an ancestor of the href'ing object)). The way it is done here is *atrocious*, but i + *could not find a better way. * FIXME: find a better and safer way to find the "original object" of anyone with the flag ->cloned * - * (2) Once we have an (potential owner) object, it can accept a href to obj, iff the graph of objects where directed edges are + * (2) Once we have an (potential owner) object, it can accept a href to obj, iff the graph of objects where directed + *edges are * either parent->child relations , *** or href'ing to href'ed *** relations, stays acyclic. - * We can go either from owner and up in the tree, or from obj and down, in either case this will be in the worst case linear in the number of objects. - * There are no easy objects allowing to do the second proposition, while "hrefList" is a "list of objects href'ing us", so we'll take this. + * We can go either from owner and up in the tree, or from obj and down, in either case this will be in the worst case + *linear in the number of objects. + * There are no easy objects allowing to do the second proposition, while "hrefList" is a "list of objects href'ing us", + *so we'll take this. * Then we keep a set of already visited elements, and do a DFS on this graph. if we find obj, then BOOM. */ -bool URIReference::_acceptObject(SPObject *obj) const { - //we go back following hrefList and parent to find if the object already references ourselves indirectly - std::set done; - SPObject * owner = getOwner(); - if(!owner)return true; - while(owner->cloned){ - std::vector positions; - while(owner->cloned){ - int position=0; - SPObject* c = owner->parent->firstChild(); - while(c != owner && dynamic_cast(c) ){position++;c=c->next;} - positions.push_back(position); - owner=owner->parent; - } - owner = ((SPUse*)owner)->get_original(); - for(int i=positions.size()-2;i>=0;i--)owner=owner->childList(false)[positions[i]]; - } - //once we have the "original" object (hopefully) we look at who is referencing it - if(obj == owner)return false; - std::list todo(owner->hrefList); - todo.push_front(owner->parent); - while(!todo.empty()){ - SPObject* e = todo.front(); - todo.pop_front(); - if(!dynamic_cast(e))continue; - if(done.insert(e).second){ - if(e==obj){return false;} - todo.push_front(e->parent); - todo.insert(todo.begin(),e->hrefList.begin(),e->hrefList.end()); - } - } +bool URIReference::_acceptObject(SPObject *obj) const +{ + // we go back following hrefList and parent to find if the object already references ourselves indirectly + std::set done; + SPObject *owner = getOwner(); + if (!owner) + return true; + while (owner->cloned) { + std::vector positions; + while (owner->cloned) { + int position = 0; + SPObject *c = owner->parent->firstChild(); + while (c != owner && dynamic_cast(c)) { + position++; + c = c->next; + } + positions.push_back(position); + owner = owner->parent; + } + owner = ((SPUse *)owner)->get_original(); + for (int i = positions.size() - 2; i >= 0; i--) + owner = owner->childList(false)[positions[i]]; + } + // once we have the "original" object (hopefully) we look at who is referencing it + if (obj == owner) + return false; + std::list todo(owner->hrefList); + todo.push_front(owner->parent); + while (!todo.empty()) { + SPObject *e = todo.front(); + todo.pop_front(); + if (!dynamic_cast(e)) + continue; + if (done.insert(e).second) { + if (e == obj) { + return false; + } + todo.push_front(e->parent); + todo.insert(todo.begin(), e->hrefList.begin(), e->hrefList.end()); + } + } return true; } - void URIReference::attach(const URI &uri) throw(BadURIException) { SPDocument *document = NULL; @@ -109,32 +126,30 @@ void URIReference::attach(const URI &uri) throw(BadURIException) // PNG and JPG files are allowed (in the case of feImage). gchar *filename = uri.toString(); bool skip = false; - if( g_str_has_suffix( filename, ".jpg" ) || - g_str_has_suffix( filename, ".JPG" ) || - g_str_has_suffix( filename, ".png" ) || - g_str_has_suffix( filename, ".PNG" ) ) { + if (g_str_has_suffix(filename, ".jpg") || g_str_has_suffix(filename, ".JPG") || + g_str_has_suffix(filename, ".png") || g_str_has_suffix(filename, ".PNG")) { skip = true; } - + // The path contains references to separate document files to load. - if(document && uri.getPath() && !skip ) { + if (document && uri.getPath() && !skip) { std::string base = document->getBase() ? document->getBase() : ""; std::string path = uri.getFullPath(base); - if(!path.empty()) { + if (!path.empty()) { document = document->createChildDoc(path); } else { document = NULL; } } - if(!document) { + if (!document) { g_warning("Can't get document for referenced URI: %s", filename); - g_free( filename ); + g_free(filename); return; } - g_free( filename ); + g_free(filename); gchar const *fragment = uri.getFragment(); - if ( !uri.isRelative() || uri.getQuery() || !fragment ) { + if (!uri.isRelative() || uri.getQuery() || !fragment) { throw UnsupportedURIException(); } @@ -149,9 +164,9 @@ void URIReference::attach(const URI &uri) throw(BadURIException) the strlen calculation and validity testing to before strdup, and copying just the id without the "))". -- pjrm */ if (!strncmp(fragment, "xpointer(id(", 12)) { - id = g_strdup(fragment+12); + id = g_strdup(fragment + 12); size_t const len = strlen(id); - if ( len < 3 || strcmp(id+len-2, "))") ) { + if (len < 3 || strcmp(id + len - 2, "))")) { g_free(id); throw MalformedURIException(); } @@ -184,13 +199,14 @@ void URIReference::detach() void URIReference::_setObject(SPObject *obj) { - if ( obj && !_acceptObject(obj) ) { + if (obj && !_acceptObject(obj)) { obj = NULL; } - if ( obj == _obj ) return; + if (obj == _obj) + return; - SPObject *old_obj=_obj; + SPObject *old_obj = _obj; _obj = obj; _release_connection.disconnect(); @@ -211,7 +227,7 @@ void URIReference::_setObject(SPObject *obj) */ void URIReference::_release(SPObject *obj) { - g_assert( _obj == obj ); + g_assert(_obj == obj); _setObject(NULL); } @@ -219,28 +235,27 @@ void URIReference::_release(SPObject *obj) -SPObject* sp_css_uri_reference_resolve( SPDocument *document, const gchar *uri ) +SPObject *sp_css_uri_reference_resolve(SPDocument *document, const gchar *uri) { - SPObject* ref = NULL; + SPObject *ref = NULL; - if ( document && uri && ( strncmp(uri, "url(", 4) == 0 ) ) { - gchar *trimmed = extract_uri( uri ); - if ( trimmed ) { - ref = sp_uri_reference_resolve( document, trimmed ); - g_free( trimmed ); + if (document && uri && (strncmp(uri, "url(", 4) == 0)) { + gchar *trimmed = extract_uri(uri); + if (trimmed) { + ref = sp_uri_reference_resolve(document, trimmed); + g_free(trimmed); } } return ref; } -SPObject * -sp_uri_reference_resolve (SPDocument *document, const gchar *uri) +SPObject *sp_uri_reference_resolve(SPDocument *document, const gchar *uri) { - SPObject* ref = NULL; + SPObject *ref = NULL; - if ( uri && (*uri == '#') ) { - ref = document->getObjectById( uri + 1 ); + if (uri && (*uri == '#')) { + ref = document->getObjectById(uri + 1); } return ref; -- cgit v1.2.3 From b80f68e9585593a78bad9ae34385cbebe780299a Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 Oct 2015 13:52:47 +0200 Subject: Add new 'writing-mode' values, remove 'block-progression', fix a few typos. (bzr r14416) --- src/attributes-test.h | 3 ++- src/attributes.cpp | 2 +- src/attributes.h | 2 +- src/libnrtype/Layout-TNG-Input.cpp | 7 ------- src/style-enums.h | 39 +++++++++++++++++++++++++------------- src/style.cpp | 27 ++++++++++++++------------ src/style.h | 8 ++++---- 7 files changed, 49 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/attributes-test.h b/src/attributes-test.h index 411304ec3..e197deedf 100644 --- a/src/attributes-test.h +++ b/src/attributes-test.h @@ -43,6 +43,7 @@ public: SVG 2: text-decoration-fill, text-decoration-stroke SVG 2: solid-color, solid-opacity SVG 2: Hatches and Meshes + CSS 3: text-orientation CSS 3: font-variant-xxx, font-feature-settings */ struct {char const *attr; bool supported;} const all_attrs[] = { @@ -69,7 +70,6 @@ struct {char const *attr; bool supported;} const all_attrs[] = { {"baseProfile", false}, {"bbox", true}, {"bias", true}, - {"block-progression", true}, {"by", true}, {"calcMode", true}, {"cap-height", true}, @@ -334,6 +334,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = { {"widths", true}, {"word-spacing", true}, {"writing-mode", true}, + {"text-orientation", true}, {"x", true}, {"x-height", true}, {"x1", true}, diff --git a/src/attributes.cpp b/src/attributes.cpp index 991834cb2..a237f8861 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -440,8 +440,8 @@ static SPStyleProp const props[] = { /* Text (css3) */ {SP_PROP_DIRECTION, "direction"}, - {SP_PROP_BLOCK_PROGRESSION, "block-progression"}, {SP_PROP_WRITING_MODE, "writing-mode"}, + {SP_PROP_TEXT_ORIENTATION, "text-orientation"}, {SP_PROP_UNICODE_BIDI, "unicode-bidi"}, {SP_PROP_ALIGNMENT_BASELINE, "alignment-baseline"}, {SP_PROP_BASELINE_SHIFT, "baseline-shift"}, diff --git a/src/attributes.h b/src/attributes.h index 47f1388b0..42ec99d8f 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -444,8 +444,8 @@ enum SPAttributeEnum { SP_PROP_TEXT_TRANSFORM, SP_PROP_DIRECTION, - SP_PROP_BLOCK_PROGRESSION, SP_PROP_WRITING_MODE, + SP_PROP_TEXT_ORIENTATION, SP_PROP_UNICODE_BIDI, SP_PROP_ALIGNMENT_BASELINE, SP_PROP_BASELINE_SHIFT, diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index c9cfe81cc..9c2fc5c11 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -172,11 +172,6 @@ float Layout::InputStreamTextSource::styleComputeFontSize() const return medium_font_size * inherit_multiplier; } -static const Layout::EnumConversionItem enum_convert_spstyle_block_progression_to_direction[] = { - {SP_CSS_BLOCK_PROGRESSION_TB, Layout::TOP_TO_BOTTOM}, - {SP_CSS_BLOCK_PROGRESSION_LR, Layout::LEFT_TO_RIGHT}, - {SP_CSS_BLOCK_PROGRESSION_RL, Layout::RIGHT_TO_LEFT}}; - static const Layout::EnumConversionItem enum_convert_spstyle_writing_mode_to_direction[] = { {SP_CSS_WRITING_MODE_LR_TB, Layout::TOP_TO_BOTTOM}, {SP_CSS_WRITING_MODE_RL_TB, Layout::TOP_TO_BOTTOM}, @@ -190,8 +185,6 @@ Layout::Direction Layout::InputStreamTextSource::styleGetBlockProgression() cons SPStyle const *this_style = style; for ( ; ; ) { - if (this_style->block_progression.set) - return (Layout::Direction)_enum_converter(this_style->block_progression.computed, enum_convert_spstyle_block_progression_to_direction, sizeof(enum_convert_spstyle_block_progression_to_direction)/sizeof(enum_convert_spstyle_block_progression_to_direction[0])); if (this_style->writing_mode.set) return (Layout::Direction)_enum_converter(this_style->writing_mode.computed, enum_convert_spstyle_writing_mode_to_direction, sizeof(enum_convert_spstyle_writing_mode_to_direction)/sizeof(enum_convert_spstyle_writing_mode_to_direction[0])); if (this_style->object == NULL || this_style->object->parent == NULL) break; diff --git a/src/style-enums.h b/src/style-enums.h index dfc99282c..03255b3b1 100644 --- a/src/style-enums.h +++ b/src/style-enums.h @@ -163,12 +163,6 @@ enum SPCSSDirection { SP_CSS_DIRECTION_RTL }; -enum SPCSSBlockProgression { - SP_CSS_BLOCK_PROGRESSION_TB, - SP_CSS_BLOCK_PROGRESSION_RL, - SP_CSS_BLOCK_PROGRESSION_LR -}; - enum SPCSSWritingMode { SP_CSS_WRITING_MODE_LR_TB, SP_CSS_WRITING_MODE_RL_TB, @@ -176,6 +170,16 @@ enum SPCSSWritingMode { SP_CSS_WRITING_MODE_TB_LR }; +// CSS WRITING MODES 3 +enum SPCSSTextOrientation { + SP_CSS_TEXT_ORIENTATION_MIXED, + SP_CSS_TEXT_ORIENTATION_UPRIGHT, + SP_CSS_TEXT_ORIENTATION_SIDEWAYS_RIGHT, + SP_CSS_TEXT_ORIENTATION_SIDEWAYS_LEFT, + SP_CSS_TEXT_ORIENTATION_SIDEWAYS, + SP_CSS_TEXT_ORIENTATION_USE_GLYPH_ORIENTATION +}; + enum SPTextAnchor { SP_CSS_TEXT_ANCHOR_START, SP_CSS_TEXT_ANCHOR_MIDDLE, @@ -489,13 +493,6 @@ static SPStyleEnum const enum_direction[] = { {NULL, -1} }; -static SPStyleEnum const enum_block_progression[] = { - {"tb", SP_CSS_BLOCK_PROGRESSION_TB}, - {"rl", SP_CSS_BLOCK_PROGRESSION_RL}, - {"lr", SP_CSS_BLOCK_PROGRESSION_LR}, - {NULL, -1} -}; - static SPStyleEnum const enum_writing_mode[] = { /* Note that using the same enumerator for lr as lr-tb means we write as lr-tb even if the * input file said lr. We prefer writing lr-tb on the grounds that the spec says the initial @@ -504,12 +501,28 @@ static SPStyleEnum const enum_writing_mode[] = { * ECMA scripts may be surprised to find tb-rl in DOM if they set the attribute to rl, so * sharing enumerators for different strings may be a bug (once we support ecma script). */ + // SVG 1.1 Deprecated but still must be supported in SVG 2. {"lr-tb", SP_CSS_WRITING_MODE_LR_TB}, {"rl-tb", SP_CSS_WRITING_MODE_RL_TB}, {"tb-rl", SP_CSS_WRITING_MODE_TB_RL}, {"lr", SP_CSS_WRITING_MODE_LR_TB}, {"rl", SP_CSS_WRITING_MODE_RL_TB}, {"tb", SP_CSS_WRITING_MODE_TB_RL}, + // SVG 2 & CSS 3 Writing Modes + {"horizontal-tb", SP_CSS_WRITING_MODE_LR_TB}, // This is correct, 'direction' distinguishes between 'lr' and 'rl'. + {"vertical-rl", SP_CSS_WRITING_MODE_TB_RL}, + {"vertical-lr", SP_CSS_WRITING_MODE_TB_LR}, + {NULL, -1} +}; + +// CSS WRITING MODES 3 +static SPStyleEnum const enum_text_orientation[] = { + {"mixed", SP_CSS_TEXT_ORIENTATION_MIXED}, // Default + {"upright", SP_CSS_TEXT_ORIENTATION_UPRIGHT}, + {"sideways-right", SP_CSS_TEXT_ORIENTATION_SIDEWAYS_RIGHT}, + {"sideways-left", SP_CSS_TEXT_ORIENTATION_SIDEWAYS_LEFT}, + {"sideways", SP_CSS_TEXT_ORIENTATION_SIDEWAYS}, + {"use-glyph-orientation", SP_CSS_TEXT_ORIENTATION_USE_GLYPH_ORIENTATION}, {NULL, -1} }; diff --git a/src/style.cpp b/src/style.cpp index 0cb5db0a7..369127792 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -136,8 +136,8 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : text_transform( "text-transform", enum_text_transform, SP_CSS_TEXT_TRANSFORM_NONE ), direction( "direction", enum_direction, SP_CSS_DIRECTION_LTR ), - block_progression("block-progression", enum_block_progression, SP_CSS_BLOCK_PROGRESSION_TB), writing_mode( "writing-mode", enum_writing_mode, SP_CSS_WRITING_MODE_LR_TB ), + text_orientation( "text-orientation",enum_text_orientation,SP_CSS_TEXT_ORIENTATION_MIXED ), baseline_shift(), text_anchor( "text-anchor", enum_text_anchor, SP_CSS_TEXT_ANCHOR_START ), white_space( "white-space", enum_white_space, SP_CSS_WHITE_SPACE_NORMAL ), @@ -318,9 +318,9 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &word_spacing ); _properties.push_back( &text_transform ); - _properties.push_back( &direction ); - _properties.push_back( &block_progression ); _properties.push_back( &writing_mode ); + _properties.push_back( &direction ); + _properties.push_back( &text_orientation ); _properties.push_back( &baseline_shift ); _properties.push_back( &text_anchor ); _properties.push_back( &white_space ); @@ -413,8 +413,8 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( text_transform.name, reinterpret_cast(&SPStyle::text_transform ) ) ); // _propmap.insert( std::make_pair( direction.name, reinterpret_cast(&SPStyle::direction ) ) ); - // _propmap.insert( std::make_pair( block_progression.name, reinterpret_cast(&SPStyle::block_progression ) ) ); // _propmap.insert( std::make_pair( writing_mode.name, reinterpret_cast(&SPStyle::writing_mode ) ) ); + // _propmap.insert( std::make_pair( text_orientation.name, reinterpret_cast(&SPStyle::text_orientation ) ) ); // _propmap.insert( std::make_pair( baseline_shift.name, reinterpret_cast(&SPStyle::baseline_shift ) ) ); // _propmap.insert( std::make_pair( text_anchor.name, reinterpret_cast(&SPStyle::text_anchor ) ) ); // _propmap.insert( std::make_pair( white_space.name, reinterpret_cast(&SPStyle::white_space ) ) ); @@ -778,12 +778,12 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { case SP_PROP_DIRECTION: direction.readIfUnset( val ); break; - case SP_PROP_BLOCK_PROGRESSION: - block_progression.readIfUnset( val ); - break; case SP_PROP_WRITING_MODE: writing_mode.readIfUnset( val ); break; + case SP_PROP_TEXT_ORIENTATION: + text_orientation.readIfUnset( val ); + break; case SP_PROP_TEXT_ANCHOR: text_anchor.readIfUnset( val ); break; @@ -1689,16 +1689,19 @@ sp_style_unset_property_attrs(SPObject *o) repr->setAttribute("text-anchor", NULL); } if (style->white_space.set) { - repr->setAttribute("white_space", NULL); + repr->setAttribute("white-space", NULL); } if (style->shape_inside.set) { - repr->setAttribute("shape_inside", NULL); + repr->setAttribute("shape-inside", NULL); } if (style->shape_padding.set) { - repr->setAttribute("shape_padding", NULL); + repr->setAttribute("shape-padding", NULL); } if (style->writing_mode.set) { - repr->setAttribute("writing_mode", NULL); + repr->setAttribute("writing-mode", NULL); + } + if (style->text_orientation.set) { + repr->setAttribute("text-orientation", NULL); } if (style->filter.set) { repr->setAttribute("filter", NULL); @@ -1781,8 +1784,8 @@ sp_css_attr_unset_text(SPCSSAttr *css) sp_repr_css_set_property(css, "word-spacing", NULL); sp_repr_css_set_property(css, "text-transform", NULL); sp_repr_css_set_property(css, "direction", NULL); - sp_repr_css_set_property(css, "block-progression", NULL); sp_repr_css_set_property(css, "writing-mode", NULL); + sp_repr_css_set_property(css, "text-orientation", NULL); sp_repr_css_set_property(css, "text-anchor", NULL); sp_repr_css_set_property(css, "white-space", NULL); sp_repr_css_set_property(css, "shape-inside", NULL); diff --git a/src/style.h b/src/style.h index 02432d3e7..3948b876c 100644 --- a/src/style.h +++ b/src/style.h @@ -142,12 +142,12 @@ public: SPIEnum text_transform; /* CSS3 Text */ - /** text direction (css3 text 3.2) */ + /** text direction (svg1.1) */ SPIEnum direction; - /** block progression (css3 text 3.2) */ - SPIEnum block_progression; - /** Writing mode (css3 text 3.2 and svg1.1 10.7.2) */ + /** Writing mode (svg1.1 10.7.2, CSS Writing Modes 3) */ SPIEnum writing_mode; + /** Text orientation (CSS Writing Modes 3) */ + SPIEnum text_orientation; /** Baseline shift (svg1.1 10.9.2) */ SPIBaselineShift baseline_shift; -- cgit v1.2.3 From d929999b79640a8b1425a999483d782883035d3b Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 Oct 2015 14:14:01 +0200 Subject: Simplify code after removal of 'block-progression'. (bzr r14417) --- src/libnrtype/Layout-TNG-Input.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index 9c2fc5c11..77480cebe 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -172,27 +172,24 @@ float Layout::InputStreamTextSource::styleComputeFontSize() const return medium_font_size * inherit_multiplier; } -static const Layout::EnumConversionItem enum_convert_spstyle_writing_mode_to_direction[] = { - {SP_CSS_WRITING_MODE_LR_TB, Layout::TOP_TO_BOTTOM}, - {SP_CSS_WRITING_MODE_RL_TB, Layout::TOP_TO_BOTTOM}, - {SP_CSS_WRITING_MODE_TB_RL, Layout::RIGHT_TO_LEFT}, - {SP_CSS_WRITING_MODE_TB_LR, Layout::LEFT_TO_RIGHT}}; - Layout::Direction Layout::InputStreamTextSource::styleGetBlockProgression() const { - // this function shouldn't be necessary, but since style.cpp doesn't support - // shorthand properties yet, it is. - SPStyle const *this_style = style; + switch( style->writing_mode.computed ) { - for ( ; ; ) { - if (this_style->writing_mode.set) - return (Layout::Direction)_enum_converter(this_style->writing_mode.computed, enum_convert_spstyle_writing_mode_to_direction, sizeof(enum_convert_spstyle_writing_mode_to_direction)/sizeof(enum_convert_spstyle_writing_mode_to_direction[0])); - if (this_style->object == NULL || this_style->object->parent == NULL) break; - this_style = this_style->object->parent->style; - if (this_style == NULL) break; - } + case SP_CSS_WRITING_MODE_LR_TB: + case SP_CSS_WRITING_MODE_RL_TB: return TOP_TO_BOTTOM; + + case SP_CSS_WRITING_MODE_TB_RL: + return RIGHT_TO_LEFT; + + case SP_CSS_WRITING_MODE_TB_LR: + return LEFT_TO_RIGHT; + default: + std::cerr << "Layout::InputTextStream::styleGetBlockProgression: invalid writing mode." << std::endl; + } + return TOP_TO_BOTTOM; } static Layout::Alignment text_anchor_to_alignment(unsigned anchor, Layout::Direction para_direction) -- cgit v1.2.3 From f8a67994cf1d608c6f14e7c41497b62f4a402392 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 15 Oct 2015 17:15:00 +0200 Subject: Bug fixes in roughen and added uption to retract handles (bzr r14418) --- src/live_effects/lpe-roughen.cpp | 82 ++++++++++++++++++---------------------- src/live_effects/lpe-roughen.h | 1 + 2 files changed, 38 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index dec3f955f..ed1ddcaf8 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -51,6 +51,8 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) true), shift_handles(_("Shift node handles"), _("Shift node handles"), "shift_handles", &wr, this, true), + retract_handles(_("Retract node handles"), _("Retract node handles"), + "retract_handles", &wr, this, false), shift_handles_sym(_("Sym shift node handles"), _("Sym shift node handles"), "shift_handles_sym", &wr, this, false), fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment lenght"), @@ -64,6 +66,7 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) registerParameter(&global_randomize); registerParameter(&shift_nodes); registerParameter(&shift_handles); + registerParameter(&retract_handles); registerParameter(&shift_handles_sym); registerParameter(&fixed_displacement); displace_x.param_set_range(0., Geom::infinity()); @@ -167,8 +170,7 @@ Geom::Point LPERoughen::randomize(double max_lenght) void LPERoughen::doEffect(SPCurve *curve) { - Geom::PathVector const original_pathv = - pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); + Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); curve->reset(); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { @@ -180,31 +182,14 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::Path::const_iterator curve_endit = path_it->end_default(); SPCurve *nCurve = new SPCurve(); Geom::Point prev(0, 0); - if (path_it->closed()) { - const Geom::Curve &closingline = - path_it->back_closed(); - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - curve_endit = path_it->end_open(); - } - } nCurve->moveto(curve_it1->initialPoint()); - Geom::Point point0(0, 0); - Geom::Point point_a1(0, 0); - Geom::Point point_a2(0, 0); - Geom::Point point_a3(0, 0); while (curve_it1 != curve_endit) { Geom::CubicBezier const *cubic = NULL; - point0 = curve_it1->initialPoint(); - point_a1 = curve_it1->initialPoint(); - point_a2 = curve_it1->finalPoint(); - point_a3 = curve_it1->finalPoint(); cubic = dynamic_cast(&*curve_it1); if (cubic) { - point_a1 = (*cubic)[1]; - point_a2 = (*cubic)[2]; - nCurve->curveto(point_a1, point_a2, point_a3); + nCurve->curveto((*cubic)[1], (*cubic)[2], curve_it1->finalPoint()); } else { - nCurve->lineto(point_a3); + nCurve->lineto(curve_it1->finalPoint()); } double length = curve_it1->length(0.001); std::size_t splits = 0; @@ -238,12 +223,10 @@ void LPERoughen::doEffect(SPCurve *curve) delete tmp; } ++curve_it1; - if(curve_it2 != curve_endit) { - ++curve_it2; - } + ++curve_it2; } if (path_it->closed()) { - if(shift_handles_sym && curve_it2 == curve_endit){ + if(shift_handles_sym && curve_it1 == curve_endit && !retract_handles){ SPCurve *out = new SPCurve(); nCurve = nCurve->create_reverse(); Geom::CubicBezier const *cubic_start = dynamic_cast(nCurve->first_segment()); @@ -305,7 +288,17 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point point_b2 = point_b3; } } - if(shift_handles_sym && cubic) { + if(retract_handles){ + out->moveto(A->initialPoint()); + out->lineto(A->pointAt(t) + point_a3); + if(cubic && !last){ + std::pair div = cubic->subdivide(t); + std::vector seg2 = div.second.controlPoints(); + out->curveto(seg2[1], seg2[2], seg2[3]); + } else { + out->lineto(A->finalPoint() + point_b3); + } + } else if(shift_handles_sym && cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); @@ -314,15 +307,15 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } - ray.setPoints(seg2[1] + point_a3 + point_b1, seg1[3] + point_a3); + ray.setPoints(seg2[1] + point_a3 + point_b1, seg2[0] + point_a3); point_a2 = Geom::Point::polar(ray.angle(), max_lenght); - if(!last){ - prev = seg1[3] + point_a3 + point_a2; - } else { + if(last){ prev = A->pointAt(1 - (t / 3)) + point_b2 + point_b3; + } else { + prev = seg1[3] + point_a2 + point_a3; } out->moveto(seg1[0]); - out->curveto(seg1[0] + point_a1, seg1[2] + point_a3 + point_a2, seg1[3] + point_a3); + out->curveto(seg1[0] + point_a1, seg1[3] + point_a2 + point_a3, seg1[3] + point_a3); if(last){ out->curveto(seg2[1] + point_a3 + point_b1, A->pointAt(1 - (t / 3)) + point_b2 + point_b3, seg2[3] + point_b3); } else { @@ -336,18 +329,14 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point } ray.setPoints(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t) + point_a3); point_a2 = Geom::Point::polar(ray.angle(), max_lenght); - if(!last){ - prev = A->pointAt((t / 3) * 2) + point_a2; - } else { - prev = A->pointAt(1 - (t / 3)) + point_b2 + point_b3; - } - out->moveto(A->initialPoint()); - out->curveto(A->initialPoint() + point_a1, A->pointAt((t / 3) * 2) + point_a3 + point_a2, A->pointAt(t) + point_a3); if(last){ - out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(1 - (t / 3)) + point_b2 + point_b3, A->finalPoint() + point_b3); + prev = A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3; } else { - out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); + prev = A->pointAt(t) + point_a3 + point_a2; } + out->moveto(A->initialPoint()); + out->curveto(A->initialPoint() + point_a1, A->pointAt(t) + point_a3 + point_a2, A->pointAt(t) + point_a3); + out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); } else if (cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), @@ -382,7 +371,10 @@ SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev) point_a1 = randomize(max_lenght); point_a2 = randomize(max_lenght); } - if(shift_handles_sym && cubic) { + if(retract_handles){ + out->moveto(A->initialPoint()); + out->lineto(A->finalPoint() + point_a3); + } else if(shift_handles_sym && cubic) { Geom::Ray ray(prev,A->initialPoint()); point_a1 = Geom::Point::polar(ray.angle(), max_lenght); if(prev == Geom::Point(0,0)){ @@ -390,7 +382,7 @@ SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev) } prev = (*cubic)[2] + point_a2; out->moveto((*cubic)[0]); - out->curveto((*cubic)[0] + point_a1, (*cubic)[2] + point_a2, (*cubic)[3] + point_a3); + out->curveto((*cubic)[0] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); } else if(shift_handles_sym && !cubic) { Geom::Ray ray(prev,A->initialPoint()); point_a1 = Geom::Point::polar(ray.angle(), max_lenght); @@ -399,13 +391,13 @@ SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev) } prev = A->pointAt((1.0/3.0) * 2) + point_a2; out->moveto(A->initialPoint()); - out->curveto(A->initialPoint() + point_a1, A->pointAt((1.0/3.0) * 2) + point_a2, A->finalPoint() + point_a3); + out->curveto(A->initialPoint() + point_a1, A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3, A->finalPoint() + point_a3); } else if (cubic) { out->moveto((*cubic)[0]); - out->curveto((*cubic)[1] + point_a1, (*cubic)[2] + point_a2, (*cubic)[3] + point_a3); + out->curveto((*cubic)[1] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); } else if (shift_handles) { out->moveto(A->initialPoint()); - out->curveto(A->pointAt(0.3333) + point_a1, A->pointAt(0.6666) + point_a2, + out->curveto(A->pointAt(0.3333) + point_a1, A->pointAt(0.6666) + point_a2 + point_a3, A->finalPoint() + point_a3); } else { out->moveto(A->initialPoint()); diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index e221e95fb..57a516310 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -52,6 +52,7 @@ private: RandomParam global_randomize; BoolParam shift_nodes; BoolParam shift_handles; + BoolParam retract_handles; BoolParam shift_handles_sym; BoolParam fixed_displacement; -- cgit v1.2.3 From c5b64a5ba1975d10f5e4a9ba41c41ad03a6321ee Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Thu, 15 Oct 2015 21:06:11 +0200 Subject: Make the handle of a dynamic offset snappable Fixed bugs: - https://launchpad.net/bugs/1174858 (bzr r14419) --- src/ui/object-edit.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/object-edit.cpp b/src/ui/object-edit.cpp index 0a6c792dc..459acf002 100644 --- a/src/ui/object-edit.cpp +++ b/src/ui/object-edit.cpp @@ -1364,13 +1364,15 @@ public: }; void -OffsetKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int /*state*/) +OffsetKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { SPOffset *offset = dynamic_cast(item); g_assert(offset != NULL); - offset->rad = sp_offset_distance_to_original(offset, p); - offset->knot = p; + Geom::Point const p_snapped = snap_knot_position(p, state); + + offset->rad = sp_offset_distance_to_original(offset, p_snapped); + offset->knot = p_snapped; offset->knotSet = true; offset->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -- cgit v1.2.3 From 074d5514042f280f94ea897269a4421ff50d8c30 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 16 Oct 2015 13:12:59 +0200 Subject: Fixed explicit base with SHIFT to allow calculate angles A bit refactor (bzr r14393.2.2) --- src/ui/tools/measure-tool.cpp | 118 ++++++++++++++++++++---------------------- src/ui/tools/measure-tool.h | 4 +- 2 files changed, 56 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 00d66b4c9..110b706fd 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -344,7 +344,7 @@ void MeasureTool::reverseKnots() this->knot_start->show(); this->knot_end->moveto(start); this->knot_end->show(); - this->showCanvasItems(end, start); + this->showCanvasItems(); } void MeasureTool::knotStartMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state) @@ -365,7 +365,7 @@ void MeasureTool::knotStartMovedHandler(SPKnot */*knot*/, Geom::Point const &ppo start_p = point; this->knot_start->moveto(start_p); } - showCanvasItems(start_p, end_p); + showCanvasItems(); } void MeasureTool::knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state) @@ -386,14 +386,15 @@ void MeasureTool::knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppoin end_p = point; this->knot_end->moveto(end_p); } - showCanvasItems(start_p, end_p); + last_end = desktop->d2w(end_p); + showCanvasItems(); } void MeasureTool::knotUngrabbedHandler(SPKnot */*knot*/, unsigned int state) { this->knot_start->moveto(start_p); this->knot_end->moveto(end_p); - showCanvasItems(start_p, end_p); + showCanvasItems(); } @@ -469,11 +470,11 @@ bool MeasureTool::root_handler(GdkEvent* event) Geom::Point const button_w(event->button.x, event->button.y); explicitBase = boost::none; last_end = boost::none; - start_point = desktop->w2d(button_w); + start_p = desktop->w2d(button_w); if (event->button.button == 1 && !this->space_panning) { // save drag origin - start_point = desktop->w2d(Geom::Point(event->button.x, event->button.y)); + start_p = desktop->w2d(Geom::Point(event->button.x, event->button.y)); within_tolerance = true; ret = TRUE; @@ -481,7 +482,7 @@ bool MeasureTool::root_handler(GdkEvent* event) SnapManager &m = desktop->namedview->snap_manager; m.setup(desktop); - m.freeSnapReturnByRef(start_point, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.freeSnapReturnByRef(start_p, Inkscape::SNAPSOURCE_OTHER_HANDLE); m.unSetup(); sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), @@ -492,9 +493,7 @@ bool MeasureTool::root_handler(GdkEvent* event) } case GDK_KEY_PRESS: { if ((event->key.keyval == GDK_KEY_Shift_L) || (event->key.keyval == GDK_KEY_Shift_R)) { - if (last_end) { - explicitBase = last_end; - } + explicitBase = end_p; } break; } @@ -508,7 +507,7 @@ bool MeasureTool::root_handler(GdkEvent* event) m.setup(desktop); Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE); - scp.addOrigin(start_point); + scp.addOrigin(start_p); m.preSnap(scp); m.unSetup(); @@ -519,7 +518,7 @@ bool MeasureTool::root_handler(GdkEvent* event) 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_point ) < tolerance) { + if ( Geom::LInfty( motion_w - start_p ) < tolerance) { return FALSE; // Do not drag if we're within tolerance from origin. } } @@ -530,20 +529,20 @@ bool MeasureTool::root_handler(GdkEvent* event) 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); + spdc_endpoint_snap_rotation(this, end_p, start_p, 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::SnapCandidatePoint scp(end_p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + scp.addOrigin(start_p); Inkscape::SnappedPoint sp = m.freeSnap(scp); - end_point = sp.getPoint(); + end_p = sp.getPoint(); m.unSetup(); } - showCanvasItems(start_point, end_point); + showCanvasItems(); last_end = motion_w ; } gobble_motion_events(GDK_BUTTON1_MASK); @@ -551,26 +550,26 @@ bool MeasureTool::root_handler(GdkEvent* event) break; } case GDK_BUTTON_RELEASE: { - this->knot_start->moveto(start_point); + this->knot_start->moveto(start_p); this->knot_start->show(); - Geom::Point end_point = end_p; + end_p = end_p; if(last_end) { - end_point = desktop->w2d(*last_end); + end_p = desktop->w2d(*last_end); if (event->button.state & GDK_CONTROL_MASK) { - spdc_endpoint_snap_rotation(this, end_point, start_point, event->motion.state); + spdc_endpoint_snap_rotation(this, end_p, start_p, event->motion.state); } else if (!(event->button.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::SnapCandidatePoint scp(end_p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + scp.addOrigin(start_p); Inkscape::SnappedPoint sp = m.freeSnap(scp); - end_point = sp.getPoint(); + end_p = sp.getPoint(); m.unSetup(); } } - this->knot_end->moveto(end_point); + this->knot_end->moveto(end_p); this->knot_end->show(); - showCanvasItems(start_point, end_point); + showCanvasItems(); if (this->grabbed) { sp_canvas_item_ungrab(this->grabbed, event->button.time); this->grabbed = NULL; @@ -660,7 +659,7 @@ void MeasureTool::toItem() guint32 line_color_primary = 0x0000ff7f; Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::XML::Node *rgroup = xml_doc->createElement("svg:g"); - showCanvasItems(start_p, end_p, true, rgroup); + showCanvasItems(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); @@ -700,7 +699,7 @@ void MeasureTool::toMarkDimension() 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_point.isFinite() || !end_point.isFinite()) { + if(!desktop || !start_p.isFinite() || !end_p.isFinite()) { return; } Geom::PathVector c; @@ -930,21 +929,14 @@ void MeasureTool::reset() measure_tmp_items.clear(); } -void MeasureTool::showCanvasItems() -{ - showCanvasItems(start_p, end_p); -} - -void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point, bool to_item, Inkscape::XML::Node *measure_repr) +void MeasureTool::showCanvasItems(bool to_item, Inkscape::XML::Node *measure_repr) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if(!desktop || !start_point.isFinite() || !end_point.isFinite() || end_point == MAGIC_POINT) { + if(!desktop || !start_p.isFinite() || !end_p.isFinite() || end_p == MAGIC_POINT) { return; } guint32 line_color_primary = 0x0000ff7f; guint32 line_color_secondary = 0xff00007f; - start_p = start_point; - end_p = end_point; //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]); @@ -956,18 +948,18 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point dimension_offset = prefs->getDouble("/tools/measure/offset"); Geom::PathVector lineseg; Geom::Path p; - p.start(desktop->dt2doc(start_point)); - p.appendNew(desktop->dt2doc(end_point)); + p.start(desktop->dt2doc(start_p)); + p.appendNew(desktop->dt2doc(end_p)); 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 deltax = end_p[Geom::X] - start_p[Geom::X]; + double deltay = end_p[Geom::Y] - start_p[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]; + double deltax2 = explicitBase.get()[Geom::X] - start_p[Geom::X]; + double deltay2 = explicitBase.get()[Geom::Y] - start_p[Geom::Y]; baseAngle = atan2(deltay2, deltax2); angle -= baseAngle; @@ -998,8 +990,8 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point items.push_back(items_reverse[0]); } } else { - r->start(desktop,start_point); - r->move(end_point); + r->start(desktop,start_p); + r->move(end_p); items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints(), all_layers); r->stop(); } @@ -1046,7 +1038,7 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point double fontsize = prefs->getInt("/tools/measure/fontsize") * (96/72); // Normal will be used for lines and text - Geom::Point windowNormal = Geom::unit_vector(Geom::rot90(desktop->d2w(end_point - start_point))); + Geom::Point windowNormal = Geom::unit_vector(Geom::rot90(desktop->d2w(end_p - start_p))); Geom::Point normal = desktop->w2d(windowNormal); std::vector intersections; @@ -1102,7 +1094,7 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point } Geom::Point angleDisplayPt = calcAngleDisplayAnchor(desktop, angle, baseAngle, - start_point, end_point, + start_p, end_p, fontsize); { @@ -1128,14 +1120,14 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point } { - double totallengthval = (end_point - start_point).length(); + double totallengthval = (end_p - start_p).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)), + end_p + desktop->w2d(Geom::Point(3*fontsize, -fontsize)), totallength_str); sp_canvastext_set_fontsize(canvas_tooltip, fontsize); canvas_tooltip->rgba = 0xffffffff; @@ -1146,7 +1138,7 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0)); if(to_item) { guint32 background = canvas_tooltip->rgba_background; - setLabelText(totallength_str, end_point + desktop->w2d(Geom::Point(3*fontsize, -fontsize)), fontsize, 0, &background, measure_repr, TEXT_ANCHOR_LEFT); + setLabelText(totallength_str, end_p + desktop->w2d(Geom::Point(3*fontsize, -fontsize)), fontsize, 0, &background, measure_repr, TEXT_ANCHOR_LEFT); } g_free(totallength_str); } @@ -1187,10 +1179,10 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point "shape", SP_KNOT_SHAPE_CROSS, NULL ); - SP_CTRL(canvasitem)->moveto(start_point); + SP_CTRL(canvasitem)->moveto(start_p); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvasitem, 0)); if(to_item) { - setPoint(start_point, measure_repr); + setPoint(start_p, measure_repr); } } @@ -1218,33 +1210,33 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point // draw main control line { SPCtrlLine *control_line = ControlManager::getManager().createControlLine(desktop->getTempGroup(), - start_point, - end_point); + start_p, + end_p); 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; + if ((end_p[Geom::X] != start_p[Geom::X]) && (end_p[Geom::Y] != start_p[Geom::Y])) { + 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_point)) + anchorEnd *= (Geom::Affine(Geom::Translate(-start_p)) * Geom::Affine(Geom::Rotate(baseAngle)) - * Geom::Affine(Geom::Translate(start_point))); + * Geom::Affine(Geom::Translate(start_p))); } SPCtrlLine *control_line = ControlManager::getManager().createControlLine(desktop->getTempGroup(), - start_point, + start_p, anchorEnd, CTLINE_SECONDARY); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); if(to_item) { - setLine(start_point, + setLine(start_p, anchorEnd, false, &line_color_secondary, measure_repr); } - createAngleDisplayCurve(desktop, start_point, end_point, angleDisplayPt, angle, measure_repr); + createAngleDisplayCurve(desktop, start_p, end_p, angleDisplayPt, angle, measure_repr); } } diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index ee45c18e5..919152aad 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -36,8 +36,7 @@ public: virtual void finish(); virtual bool root_handler(GdkEvent* event); - virtual void showCanvasItems(); - virtual void showCanvasItems(Geom::Point start_point, Geom::Point end_point, bool to_item = false, Inkscape::XML::Node *measure_repr = NULL); + virtual void showCanvasItems(bool to_item = false, Inkscape::XML::Node *measure_repr = NULL); virtual void reverseKnots(); virtual void toMarkDimension(); virtual void toItem(); @@ -54,7 +53,6 @@ public: private: SPCanvasItem* grabbed; - Geom::Point start_point; boost::optional explicitBase; boost::optional last_end; SPKnot *knot_start; -- cgit v1.2.3 From 7480acb475c646171babc133edcde56356867ede Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 16 Oct 2015 15:57:52 +0200 Subject: removed unnecesary line (bzr r14393.2.3) --- src/ui/tools/measure-tool.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 110b706fd..7fedf6631 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -386,7 +386,6 @@ void MeasureTool::knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppoin end_p = point; this->knot_end->moveto(end_p); } - last_end = desktop->d2w(end_p); showCanvasItems(); } -- cgit v1.2.3 From 69aa4c6436321b22525fb11c552ca7d60ac1b096 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 16 Oct 2015 19:17:47 +0200 Subject: Add convert to guides option (bzr r14393.2.4) --- src/ui/tools/measure-tool.cpp | 91 +++++++++++++++++++++++++++++++++++++++++ src/ui/tools/measure-tool.h | 1 + src/widgets/measure-toolbar.cpp | 17 ++++++++ src/widgets/toolbox.cpp | 1 + 4 files changed, 110 insertions(+) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 7fedf6631..bf82fb745 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -650,6 +650,97 @@ void MeasureTool::setMarker(bool isStart) path->updateRepr(); } +void MeasureTool::toGuides() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *doc = desktop->getDocument(); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + Geom::Point start = start_p * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + Geom::Point end = end_p * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + Geom::Ray ray(start,end); + SPNamedView *namedview = desktop->namedview; + if(!namedview){ + return; + } + //meassure angle + Inkscape::XML::Node *measure_line; + measure_line = xml_doc->createElement("sodipodi:guide"); + std::stringstream position; + position.imbue(std::locale::classic()); + position << start[Geom::X] << "," << start[Geom::Y]; + measure_line->setAttribute("position", position.str().c_str() ); + Geom::Point unit_vector = Geom::rot90(start.polar(ray.angle())); + std::stringstream angle; + angle.imbue(std::locale::classic()); + angle << unit_vector[Geom::X] << "," << unit_vector[Geom::Y]; + measure_line->setAttribute("orientation", angle.str().c_str()); + namedview->appendChild(measure_line); + Inkscape::GC::release(measure_line); + //base angle + if(explicitBase){ + explicitBase = *explicitBase * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + ray.setPoints(start, *explicitBase); + if(ray.angle() != 0){ + Inkscape::XML::Node *base_line; + base_line = xml_doc->createElement("sodipodi:guide"); + position.str(""); + position.imbue(std::locale::classic()); + position << start[Geom::X] << "," << start[Geom::Y]; + base_line->setAttribute("position", position.str().c_str() ); + Geom::Point unit_vector = Geom::rot90(start.polar(ray.angle())); + std::stringstream angle; + angle.imbue(std::locale::classic()); + angle << unit_vector[Geom::X] << "," << unit_vector[Geom::Y]; + base_line->setAttribute("orientation", angle.str().c_str()); + namedview->appendChild(base_line); + Inkscape::GC::release(base_line); + } + } + //start horizontal + Inkscape::XML::Node *start_horizontal; + start_horizontal = xml_doc->createElement("sodipodi:guide"); + position.str(""); + position.imbue(std::locale::classic()); + position << start[Geom::X] << "," << start[Geom::Y]; + start_horizontal->setAttribute("position", position.str().c_str() ); + start_horizontal->setAttribute("orientation", "0,1"); + namedview->appendChild(start_horizontal); + Inkscape::GC::release(start_horizontal); + //start vertical + Inkscape::XML::Node *start_vertical; + start_vertical = xml_doc->createElement("sodipodi:guide"); + position.str(""); + position.imbue(std::locale::classic()); + position << start[Geom::X] << "," << start[Geom::Y]; + start_vertical->setAttribute("position", position.str().c_str() ); + start_vertical->setAttribute("orientation", "1,0"); + namedview->appendChild(start_vertical); + Inkscape::GC::release(start_vertical); + //end horizontal + Inkscape::XML::Node *end_horizontal; + end_horizontal = xml_doc->createElement("sodipodi:guide"); + position.str(""); + position.imbue(std::locale::classic()); + position << end[Geom::X] << "," << end[Geom::Y]; + end_horizontal->setAttribute("position", position.str().c_str() ); + end_horizontal->setAttribute("orientation", "0,1"); + namedview->appendChild(end_horizontal); + Inkscape::GC::release(end_horizontal); + //start vertical + Inkscape::XML::Node *end_vertical; + end_vertical = xml_doc->createElement("sodipodi:guide"); + position.str(""); + position.imbue(std::locale::classic()); + position << end[Geom::X] << "," << end[Geom::Y]; + end_vertical->setAttribute("position", position.str().c_str() ); + end_vertical->setAttribute("orientation", "1,0"); + namedview->appendChild(end_vertical); + Inkscape::GC::release(end_vertical); + + doc->ensureUpToDate(); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add guides from measure tool")); +} + void MeasureTool::toItem() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index 919152aad..b53131ef9 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -38,6 +38,7 @@ public: virtual bool root_handler(GdkEvent* event); virtual void showCanvasItems(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(); diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 48c781fb3..741d600b4 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -178,6 +178,13 @@ static void sp_to_mark_dimension(void){ } } +static void sp_to_guides(void){ + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->toGuides(); + } +} + static void sp_to_item(void){ MeasureTool *mt = get_measure_tool(); if (mt) { @@ -280,6 +287,16 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_reverse_knots), 0 ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } + //to guides + { + InkAction* act = ink_action_new( "MeasureToGuides", + _("To guides"), + _("Mark Dimension"), + INKSCAPE_ICON("guides"), + secondarySize ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_guides), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } //to mark dimensions { InkAction* act = ink_action_new( "MeasureMarkDimension", diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 665502745..a2bd16978 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -347,6 +347,7 @@ static gchar const * ui_descr = " " " " " " + " " " " " " " " -- cgit v1.2.3 From 08729b1dc767a8b3fd3de4ce0098d325f56fae60 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 16 Oct 2015 20:02:37 +0200 Subject: Fix a regression on mirror measure (bzr r14393.2.5) --- src/ui/tools/measure-tool.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index bf82fb745..1bdccf13b 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -344,6 +344,8 @@ void MeasureTool::reverseKnots() this->knot_start->show(); this->knot_end->moveto(start); this->knot_end->show(); + start_p = end; + end_p = start; this->showCanvasItems(); } -- cgit v1.2.3 From f0cd7f4d9ca2e7f6f59c8030ee57917254816a59 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 16 Oct 2015 20:06:31 +0200 Subject: Fix a wrong string (bzr r14393.2.6) --- src/widgets/measure-toolbar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 741d600b4..28f82ba44 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -291,7 +291,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G { InkAction* act = ink_action_new( "MeasureToGuides", _("To guides"), - _("Mark Dimension"), + _("To guides"), INKSCAPE_ICON("guides"), secondarySize ); g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_guides), 0 ); -- cgit v1.2.3 From 3b66eaf39332144a8545a85bbf8516e0e5024dd8 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 16 Oct 2015 20:44:32 +0200 Subject: fixing guide positions... (bzr r14393.2.7) --- src/ui/tools/measure-tool.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 1bdccf13b..3795a980c 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -657,8 +657,10 @@ void MeasureTool::toGuides() SPDesktop *desktop = SP_ACTIVE_DESKTOP; SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Geom::Point start = start_p * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - Geom::Point end = end_p * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + Geom::Point start = desktop->doc2dt(start_p); + Geom::Point end = desktop->doc2dt(end_p); + start *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + end *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); Geom::Ray ray(start,end); SPNamedView *namedview = desktop->namedview; if(!namedview){ -- cgit v1.2.3 From 257bf92c7eada92b55fa9b68a75feedc0e80eefe Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 17 Oct 2015 18:36:14 +0200 Subject: Fixed guides if current layer has any transform Improved guides code Change color and label to the result guides (bzr r14393.1.23) --- src/ui/tools/measure-tool.cpp | 129 +++++++++++++++++------------------------- src/ui/tools/measure-tool.h | 3 +- 2 files changed, 54 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 3795a980c..b26e528c4 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -39,6 +39,7 @@ #include "sp-flowtext.h" #include "sp-defs.h" #include "sp-item.h" +#include "sp-root.h" #include "macros.h" #include "rubberband.h" #include "path-chemistry.h" @@ -656,91 +657,26 @@ void MeasureTool::toGuides() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; SPDocument *doc = desktop->getDocument(); - Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Geom::Point start = desktop->doc2dt(start_p); - Geom::Point end = desktop->doc2dt(end_p); - start *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - end *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + 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; } - //meassure angle - Inkscape::XML::Node *measure_line; - measure_line = xml_doc->createElement("sodipodi:guide"); - std::stringstream position; - position.imbue(std::locale::classic()); - position << start[Geom::X] << "," << start[Geom::Y]; - measure_line->setAttribute("position", position.str().c_str() ); - Geom::Point unit_vector = Geom::rot90(start.polar(ray.angle())); - std::stringstream angle; - angle.imbue(std::locale::classic()); - angle << unit_vector[Geom::X] << "," << unit_vector[Geom::Y]; - measure_line->setAttribute("orientation", angle.str().c_str()); - namedview->appendChild(measure_line); - Inkscape::GC::release(measure_line); - //base angle + setGuide(start,ray.angle(), _("Meassure")); if(explicitBase){ explicitBase = *explicitBase * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); ray.setPoints(start, *explicitBase); if(ray.angle() != 0){ - Inkscape::XML::Node *base_line; - base_line = xml_doc->createElement("sodipodi:guide"); - position.str(""); - position.imbue(std::locale::classic()); - position << start[Geom::X] << "," << start[Geom::Y]; - base_line->setAttribute("position", position.str().c_str() ); - Geom::Point unit_vector = Geom::rot90(start.polar(ray.angle())); - std::stringstream angle; - angle.imbue(std::locale::classic()); - angle << unit_vector[Geom::X] << "," << unit_vector[Geom::Y]; - base_line->setAttribute("orientation", angle.str().c_str()); - namedview->appendChild(base_line); - Inkscape::GC::release(base_line); + setGuide(start,ray.angle(), _("Base")); } } - //start horizontal - Inkscape::XML::Node *start_horizontal; - start_horizontal = xml_doc->createElement("sodipodi:guide"); - position.str(""); - position.imbue(std::locale::classic()); - position << start[Geom::X] << "," << start[Geom::Y]; - start_horizontal->setAttribute("position", position.str().c_str() ); - start_horizontal->setAttribute("orientation", "0,1"); - namedview->appendChild(start_horizontal); - Inkscape::GC::release(start_horizontal); - //start vertical - Inkscape::XML::Node *start_vertical; - start_vertical = xml_doc->createElement("sodipodi:guide"); - position.str(""); - position.imbue(std::locale::classic()); - position << start[Geom::X] << "," << start[Geom::Y]; - start_vertical->setAttribute("position", position.str().c_str() ); - start_vertical->setAttribute("orientation", "1,0"); - namedview->appendChild(start_vertical); - Inkscape::GC::release(start_vertical); - //end horizontal - Inkscape::XML::Node *end_horizontal; - end_horizontal = xml_doc->createElement("sodipodi:guide"); - position.str(""); - position.imbue(std::locale::classic()); - position << end[Geom::X] << "," << end[Geom::Y]; - end_horizontal->setAttribute("position", position.str().c_str() ); - end_horizontal->setAttribute("orientation", "0,1"); - namedview->appendChild(end_horizontal); - Inkscape::GC::release(end_horizontal); - //start vertical - Inkscape::XML::Node *end_vertical; - end_vertical = xml_doc->createElement("sodipodi:guide"); - position.str(""); - position.imbue(std::locale::classic()); - position << end[Geom::X] << "," << end[Geom::Y]; - end_vertical->setAttribute("position", position.str().c_str() ); - end_vertical->setAttribute("orientation", "1,0"); - namedview->appendChild(end_vertical); - Inkscape::GC::release(end_vertical); - + setGuide(start,0,_("Start")); + setGuide(start,Geom::deg_to_rad(90),_("Start")); + setGuide(end,0,_("End")); + setGuide(end,Geom::deg_to_rad(90),_("End")); + showCanvasItems(true); doc->ensureUpToDate(); DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add guides from measure tool")); } @@ -753,7 +689,7 @@ void MeasureTool::toItem() guint32 line_color_primary = 0x0000ff7f; Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::XML::Node *rgroup = xml_doc->createElement("svg:g"); - showCanvasItems(true, rgroup); + 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); @@ -790,6 +726,39 @@ void MeasureTool::toMarkDimension() DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add global meassure line")); } +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; + //meassure 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); +} + 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; @@ -1023,7 +992,7 @@ void MeasureTool::reset() measure_tmp_items.clear(); } -void MeasureTool::showCanvasItems(bool to_item, Inkscape::XML::Node *measure_repr) +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() || end_p == MAGIC_POINT) { @@ -1193,7 +1162,7 @@ void MeasureTool::showCanvasItems(bool to_item, Inkscape::XML::Node *measure_rep { // TODO cleanup memory, Glib::ustring, etc.: - gchar *angle_str = g_strdup_printf("%.2f °", angle * 180/M_PI); + gchar *angle_str = g_strdup_printf("%.2f °", Geom::rad_to_deg(angle)); SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, @@ -1298,6 +1267,12 @@ void MeasureTool::showCanvasItems(bool to_item, Inkscape::XML::Node *measure_rep if(to_item) { setPoint(desktop->doc2dt(intersections[idx]), measure_repr); } + if(to_guides) { + std::stringstream cross_number; + cross_number.imbue(std::locale::classic()); + cross_number << _("Crossing ") << idx; + setGuide(desktop->doc2dt(intersections[idx]), angle + Geom::deg_to_rad(90), cross_number.str().c_str()); + } } // Since adding goes to the bottom, do all lines last. diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index b53131ef9..05c8296c1 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -36,7 +36,7 @@ public: virtual void finish(); virtual bool root_handler(GdkEvent* event); - virtual void showCanvasItems(bool to_item = false, Inkscape::XML::Node *measure_repr = NULL); + 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(); @@ -45,6 +45,7 @@ public: virtual void setMarkers(); virtual void setMarker(bool isStart); virtual const std::string& getPrefsPath(); + 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 = false, guint32 *color = NULL, Inkscape::XML::Node *measure_repr = NULL); void setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle, guint32 *background = NULL, Inkscape::XML::Node *measure_repr = NULL, CanvasTextAnchorPositionEnum text_anchor = TEXT_ANCHOR_CENTER ); -- cgit v1.2.3 From 19a39e655f7abf8fb9844bb4474fdd908a548870 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 17 Oct 2015 18:42:23 +0200 Subject: String fixes (bzr r14393.1.24) --- src/ui/tools/measure-tool.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index b26e528c4..a461a6b3c 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -664,7 +664,7 @@ void MeasureTool::toGuides() if(!namedview){ return; } - setGuide(start,ray.angle(), _("Meassure")); + setGuide(start,ray.angle(), _("Measure")); if(explicitBase){ explicitBase = *explicitBase * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); ray.setPoints(start, *explicitBase); @@ -723,7 +723,7 @@ void MeasureTool::toMarkDimension() gchar *totallength_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str()); setLabelText(totallength_str, middle, fontsize, Geom::deg_to_rad(180) - ray.angle()); doc->ensureUpToDate(); - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add global meassure line")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add global measure line")); } void MeasureTool::setGuide(Geom::Point origin,double angle, const char *label) @@ -741,7 +741,7 @@ void MeasureTool::setGuide(Geom::Point origin,double angle, const char *label) return; } origin *= affine; - //meassure angle + //measure angle Inkscape::XML::Node *guide; guide = xml_doc->createElement("sodipodi:guide"); std::stringstream position; -- cgit v1.2.3 From c7bf1a0ffbc1e5fc397df2fb8ce7fac90caba9eb Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 17 Oct 2015 18:55:33 +0200 Subject: Fix for numbering crosing labels (bzr r14393.1.25) --- src/ui/tools/measure-tool.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index a461a6b3c..4bb8edcc3 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -672,10 +672,10 @@ void MeasureTool::toGuides() setGuide(start,ray.angle(), _("Base")); } } - setGuide(start,0,_("Start")); + setGuide(start,0,""); setGuide(start,Geom::deg_to_rad(90),_("Start")); setGuide(end,0,_("End")); - setGuide(end,Geom::deg_to_rad(90),_("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")); @@ -1270,8 +1270,16 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N if(to_guides) { std::stringstream cross_number; cross_number.imbue(std::locale::classic()); - cross_number << _("Crossing ") << idx; - setGuide(desktop->doc2dt(intersections[idx]), angle + Geom::deg_to_rad(90), cross_number.str().c_str()); + if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true)){ + cross_number << _("Crossing ") << idx; + } else { + cross_number << _("Crossing ") << idx + 1; + } + 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.str().c_str()); + } } } // Since adding goes to the bottom, do all lines last. -- cgit v1.2.3 From d03a0a3405b10ac4686faac1d4827c01f47114b0 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 17 Oct 2015 19:51:26 +0200 Subject: Add precision to measure. Also change other scalar widgets to a .2 precision instead 3 (bzr r14393.1.26) --- src/ui/tools/measure-tool.cpp | 32 ++++++++++++++++++++++++++------ src/widgets/measure-toolbar.cpp | 37 ++++++++++++++++++++++++++++++++++--- src/widgets/toolbox.cpp | 2 ++ 3 files changed, 62 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 4bb8edcc3..57e519a0e 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -716,11 +716,15 @@ void MeasureTool::toMarkDimension() if (!unit_name.compare("")) { unit_name = "px"; } - double fontsize = prefs->getInt("/tools/measure/fontsize") * (96/72); + double fontsize = prefs->getInt("/tools/measure/fontsize") * (96.0/72.0); + int precision = prefs->getInt("/tools/measure/precision"); + 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); - gchar *totallength_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str()); + gchar *totallength_str = g_strdup_printf(precision_str.str().c_str(), totallengthval, unit_name.c_str()); setLabelText(totallength_str, middle, fontsize, Geom::deg_to_rad(180) - ray.angle()); doc->ensureUpToDate(); DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add global measure line")); @@ -1137,7 +1141,11 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N LabelPlacement &place = *it; // TODO cleanup memory, Glib::ustring, etc.: - gchar *measure_str = g_strdup_printf("%.2f %s", place.lengthVal, unit_name.c_str()); + int precision = prefs->getInt("/tools/measure/precision"); + std::stringstream precision_str; + precision_str.imbue(std::locale::classic()); + precision_str << "%." << precision << "f %s"; + gchar *measure_str = g_strdup_printf(precision_str.str().c_str(), place.lengthVal, unit_name.c_str()); SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, place.end, @@ -1162,7 +1170,11 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N { // TODO cleanup memory, Glib::ustring, etc.: - gchar *angle_str = g_strdup_printf("%.2f °", Geom::rad_to_deg(angle)); + int precision = prefs->getInt("/tools/measure/precision"); + std::stringstream precision_str; + precision_str.imbue(std::locale::classic()); + precision_str << "%." << precision << "f °"; + gchar *angle_str = g_strdup_printf(precision_str.str().c_str(), Geom::rad_to_deg(angle)); SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, @@ -1187,7 +1199,11 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N 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()); + int precision = prefs->getInt("/tools/measure/precision"); + std::stringstream precision_str; + precision_str.imbue(std::locale::classic()); + precision_str << "%." << precision << "f %s"; + gchar *totallength_str = g_strdup_printf(precision_str.str().c_str(), totallengthval, unit_name.c_str()); SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, end_p + desktop->w2d(Geom::Point(3*fontsize, -fontsize)), @@ -1211,7 +1227,11 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N 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()); + int precision = prefs->getInt("/tools/measure/precision"); + std::stringstream precision_str; + precision_str.imbue(std::locale::classic()); + precision_str << "%." << precision << "f %s"; + gchar *total_str = g_strdup_printf(precision_str.str().c_str(), totallengthval, unit_name.c_str()); SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * (dimension_offset * 2), diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 28f82ba44..8256abc76 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -102,6 +102,23 @@ sp_measure_offset_value_changed(GtkAdjustment *adj, GObject *tbl) } } + +static void +sp_measure_precision_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt(Glib::ustring("/tools/measure/precision"), + gtk_adjustment_get_value(adj)); + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } + } +} + static void measure_unit_changed(GtkAction* /*act*/, GObject* tbl) { UnitTracker* tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); @@ -212,8 +229,8 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, 1, 36, 1.0, 4.0, 0, 0, 0, - sp_measure_fontsize_value_changed); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + sp_measure_fontsize_value_changed, NULL, 0 , 2); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact)); } // units label @@ -231,6 +248,20 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G gtk_action_group_add_action( mainActions, act ); } + /* Precission */ + { + eact = create_adjustment_action( "MeasurePrecisionAction", + _("Precision"), _("Precision:"), + _("Decimal precision of measure"), + "/tools/measure/precision", 2, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0, 10, 1, 0, + 0, 0, 0, + sp_measure_precision_value_changed, NULL, 0 ,0); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact)); + } + + /* Offset */ { eact = create_adjustment_action( "MeasureOffsetAction", @@ -240,7 +271,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, 0.0, 90000.0, 1.0, 4.0, 0, 0, 0, - sp_measure_offset_value_changed); + sp_measure_offset_value_changed, NULL, 0 , 2); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index a2bd16978..e7dd69a28 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -339,6 +339,8 @@ static gchar const * ui_descr = " " " " " " + " " + " " " " " " " " -- cgit v1.2.3 From aed527316ca2cff495c32f57f68e37cd5b346f12 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 18 Oct 2015 13:51:14 +0200 Subject: Added Scale option (bzr r14393.1.27) --- src/ui/tools/measure-tool.cpp | 70 ++++++++++++++++++++++------------------- src/widgets/measure-toolbar.cpp | 46 +++++++++++++++++++++------ src/widgets/toolbox.cpp | 2 ++ 3 files changed, 76 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 57e519a0e..e56d0e916 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -106,14 +106,14 @@ bool SortLabelPlacement(LabelPlacement const &first, LabelPlacement const &secon } } -void repositionOverlappingLabels(std::vector &placements, SPDesktop *desktop, Geom::Point const &normal, double fontsize) +void repositionOverlappingLabels(std::vector &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); } @@ -706,12 +706,13 @@ void MeasureTool::toMarkDimension() setMarkers(); Geom::Ray ray(start_p,end_p); Geom::Point start = start_p + Geom::Point::polar(ray.angle(), 5); - start = start + Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -(dimension_offset / 4.0)); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + dimension_offset = prefs->getDouble("/tools/measure/offset"); + 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 / 4.0)); + end = end+ Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -dimension_offset); guint32 color = 0x000000ff; setLine(start, end, true, &color); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring unit_name = prefs->getString("/tools/measure/unit"); if (!unit_name.compare("")) { unit_name = "px"; @@ -724,7 +725,8 @@ void MeasureTool::toMarkDimension() Geom::Point middle = Geom::middle_point(start, end); double totallengthval = (end_p - start_p).length(); totallengthval = Inkscape::Util::Quantity::convert(totallengthval, "px", unit_name); - gchar *totallength_str = g_strdup_printf(precision_str.str().c_str(), totallengthval, unit_name.c_str()); + double scale = prefs->getDouble("/tools/measure/scale") / 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()); doc->ensureUpToDate(); DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add global measure line")); @@ -825,6 +827,8 @@ void MeasureTool::setLine(Geom::Point start_point,Geom::Point end_point, bool ma SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr)); Inkscape::GC::release(repr); item->updateRepr(); + desktop->getSelection()->clear(); + desktop->getSelection()->add(item); } } } @@ -903,13 +907,15 @@ void MeasureTool::setLabelText(const char *value, Geom::Point pos, double fontsi SPCSSAttr *css = sp_repr_css_attr_new(); std::stringstream font_size; font_size.imbue(std::locale::classic()); - font_size << fontsize ; + font_size << fontsize << "px"; 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", "0px"); sp_repr_css_set_property (css, "word-spacing", "0px"); + 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 { @@ -953,10 +959,10 @@ void MeasureTool::setLabelText(const char *value, Geom::Point pos, double fontsi 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", 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); + 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); @@ -1012,7 +1018,7 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool show_in_between = prefs->getBool("/tools/measure/show_in_between"); bool all_layers = prefs->getBool("/tools/measure/all_layers"); - dimension_offset = prefs->getDouble("/tools/measure/offset"); + dimension_offset = 70; Geom::PathVector lineseg; Geom::Path p; p.start(desktop->dt2doc(start_p)); @@ -1102,8 +1108,8 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N if (!unit_name.compare("")) { unit_name = "px"; } - - double fontsize = prefs->getInt("/tools/measure/fontsize") * (96/72); + double scale = prefs->getDouble("/tools/measure/scale") / 100.0; + double fontsize = prefs->getDouble("/tools/measure/fontsize") * (96/72); // 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); @@ -1128,24 +1134,24 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N 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.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"); // Adjust positions - repositionOverlappingLabels(placements, desktop, windowNormal, fontsize); + repositionOverlappingLabels(placements, desktop, windowNormal, fontsize, precision); for (std::vector::iterator it = placements.begin(); it != placements.end(); ++it) { LabelPlacement &place = *it; // TODO cleanup memory, Glib::ustring, etc.: - int precision = prefs->getInt("/tools/measure/precision"); + std::stringstream precision_str; precision_str.imbue(std::locale::classic()); precision_str << "%." << precision << "f %s"; - gchar *measure_str = g_strdup_printf(precision_str.str().c_str(), place.lengthVal, unit_name.c_str()); + gchar *measure_str = g_strdup_printf(precision_str.str().c_str(), place.lengthVal * scale, unit_name.c_str()); SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, place.end, @@ -1203,7 +1209,7 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N std::stringstream precision_str; precision_str.imbue(std::locale::classic()); precision_str << "%." << precision << "f %s"; - gchar *totallength_str = g_strdup_printf(precision_str.str().c_str(), totallengthval, unit_name.c_str()); + gchar *totallength_str = g_strdup_printf(precision_str.str().c_str(), totallengthval * scale, unit_name.c_str()); SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, end_p + desktop->w2d(Geom::Point(3*fontsize, -fontsize)), @@ -1231,10 +1237,10 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N std::stringstream precision_str; precision_str.imbue(std::locale::classic()); precision_str << "%." << precision << "f %s"; - gchar *total_str = g_strdup_printf(precision_str.str().c_str(), totallengthval, unit_name.c_str()); + gchar *total_str = g_strdup_printf(precision_str.str().c_str(), totallengthval * scale, unit_name.c_str()); SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, - desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * (dimension_offset * 2), + desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * dimension_offset, total_str); sp_canvastext_set_fontsize(canvas_tooltip, fontsize); canvas_tooltip->rgba = 0xffffffff; @@ -1245,7 +1251,7 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0)); if(to_item) { guint32 background = canvas_tooltip->rgba_background; - setLabelText(total_str, desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * (dimension_offset * 2), fontsize, 0, &background, measure_repr); + setLabelText(total_str, desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * dimension_offset, fontsize, 0, &background, measure_repr); } g_free(total_str); } @@ -1341,34 +1347,34 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N ControlManager &mgr = ControlManager::getManager(); SPCtrlLine *control_line = 0; control_line = mgr.createControlLine(desktop->getTempGroup(), - desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2), - desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2)); + desktop->doc2dt(intersections[0]) + normal * dimension_offset, + desktop->doc2dt(intersections[intersections.size() - 1]) + normal * dimension_offset); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); if(to_item) { - setLine(desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2), - desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2), + setLine(desktop->doc2dt(intersections[0]) + normal * dimension_offset, + desktop->doc2dt(intersections[intersections.size() - 1]) + normal * dimension_offset, false, &line_color_primary, measure_repr); } control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(intersections[0]), - desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2)); + desktop->doc2dt(intersections[0]) + normal * dimension_offset); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); if(to_item) { setLine(desktop->doc2dt(intersections[0]), - desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2), + desktop->doc2dt(intersections[0]) + normal * dimension_offset, false, &line_color_primary, measure_repr); } control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(intersections[intersections.size() - 1]), - desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2)); + desktop->doc2dt(intersections[intersections.size() - 1]) + normal * dimension_offset); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); if(to_item) { setLine(desktop->doc2dt(intersections[intersections.size() - 1]), - desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2), + desktop->doc2dt(intersections[intersections.size() - 1]) + normal * dimension_offset, false, &line_color_primary, measure_repr); @@ -1397,12 +1403,12 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N ControlManager &mgr = ControlManager::getManager(); SPCtrlLine *control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(measure_text_pos), - desktop->doc2dt(measure_text_pos) - (normal * dimension_offset), + desktop->doc2dt(measure_text_pos) - (normal * dimension_offset / 2), CTLINE_SECONDARY); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); if(to_item) { setLine(desktop->doc2dt(measure_text_pos), - desktop->doc2dt(measure_text_pos) - (normal * dimension_offset), + desktop->doc2dt(measure_text_pos) - (normal * dimension_offset / 2), false, &line_color_secondary, measure_repr); diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 8256abc76..8d7146a46 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -102,6 +102,20 @@ sp_measure_offset_value_changed(GtkAdjustment *adj, GObject *tbl) } } +static void sp_measure_scale_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt(Glib::ustring("/tools/measure/scale"), + gtk_adjustment_get_value(adj)); + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } + } +} static void sp_measure_precision_value_changed(GtkAdjustment *adj, GObject *tbl) @@ -233,7 +247,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G gtk_action_group_add_action( mainActions, GTK_ACTION(eact)); } - // units label + /* units label */ { EgeOutputAction* act = ege_output_action_new( "measure_units_label", _("Units:"), _("The units to be used for the measurements"), 0 ); ege_output_action_set_use_markup( act, TRUE ); @@ -241,7 +255,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); } - // units menu + /* units menu */ { GtkAction* act = tracker->createAction( "MeasureUnitsAction", _("Units:"), _("The units to be used for the measurements") ); g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(measure_unit_changed), holder ); @@ -261,13 +275,25 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G gtk_action_group_add_action( mainActions, GTK_ACTION(eact)); } + /* Scale */ + { + eact = create_adjustment_action( "MeasureScaleAction", + _("Scale %"), _("Scale %:"), + _("Scale the results"), + "/tools/measure/scale", 100.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 90000.0, 1.0, 4.0, + 0, 0, 0, + sp_measure_scale_value_changed, NULL, 0 , 3); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } /* Offset */ { eact = create_adjustment_action( "MeasureOffsetAction", _("Offset"), _("Offset:"), _("The offset size"), - "/tools/measure/offset", 30.0, + "/tools/measure/offset", 5.0, GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, 0.0, 90000.0, 1.0, 4.0, 0, 0, 0, @@ -275,7 +301,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); } - // ignore_1st_and_last + /* ignore_1st_and_last */ { InkToggleAction* act = ink_toggle_action_new( "MeasureIgnore1stAndLast", _("Ignore first and last"), @@ -286,7 +312,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_ignore_1st_and_last), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } - // measure imbetweens + /* measure imbetweens */ { InkToggleAction* act = ink_toggle_action_new( "MeasureInBettween", _("Show measures between items"), @@ -297,7 +323,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_show_in_between), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } - // measure only current layer + /* measure only current layer */ { InkToggleAction* act = ink_toggle_action_new( "MeasureAllLayers", _("Measure all layers"), @@ -308,7 +334,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_all_layers), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } - //toogle start end + /* toogle start end */ { InkAction* act = ink_action_new( "MeasureReverse", _("Reverse measure"), @@ -318,7 +344,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_reverse_knots), 0 ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } - //to guides + /* to guides */ { InkAction* act = ink_action_new( "MeasureToGuides", _("To guides"), @@ -328,7 +354,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_guides), 0 ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } - //to mark dimensions + /* to mark dimensions */ { InkAction* act = ink_action_new( "MeasureMarkDimension", _("Mark Dimension"), @@ -338,7 +364,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_mark_dimension), 0 ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } - //to item + /* to item */ { InkAction* act = ink_action_new( "MeasureToItem", _("Convert to item"), diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index e7dd69a28..5d41d3b10 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -341,6 +341,8 @@ static gchar const * ui_descr = " " " " " " + " " + " " " " " " " " -- cgit v1.2.3 From 7d224d1cf9bfb0d6555721c24c06ebed11b1b15f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 18 Oct 2015 21:13:13 +0200 Subject: Added "Spray Friendly" Parameter to roughen LPE Adds, but not used by the moment a extra parameter to bool and scalar LPE parameter to hide the widget. This allow to store scalar values and bool values inside the LPEObject to intermediate use by the LPE, whithout disturbing to the user. (bzr r14420) --- src/live_effects/lpe-roughen.cpp | 23 +++++++++++++++++--- src/live_effects/lpe-roughen.h | 1 + src/live_effects/parameter/bool.cpp | 32 +++++++++++++++------------ src/live_effects/parameter/bool.h | 4 +++- src/live_effects/parameter/parameter.cpp | 37 ++++++++++++++++++-------------- src/live_effects/parameter/parameter.h | 4 +++- 6 files changed, 66 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index ed1ddcaf8..136190b8f 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -18,6 +18,7 @@ #include "live_effects/lpe-roughen.h" #include "display/curve.h" #include "live_effects/parameter/parameter.h" +#include #include "helper/geom.h" #include #include @@ -56,7 +57,9 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) shift_handles_sym(_("Sym shift node handles"), _("Sym shift node handles"), "shift_handles_sym", &wr, this, false), fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment lenght"), - "fixed_displacement", &wr, this, false) + "fixed_displacement", &wr, this, false), + spray_tool_friendly(_("Spray Tool friendly"), _("For use with spray tool"), + "spray_tool_friendly", &wr, this, false) { registerParameter(&method); registerParameter(&max_segment_size); @@ -69,6 +72,7 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) registerParameter(&retract_handles); registerParameter(&shift_handles_sym); registerParameter(&fixed_displacement); + registerParameter(&spray_tool_friendly); displace_x.param_set_range(0., Geom::infinity()); displace_y.param_set_range(0., Geom::infinity()); global_randomize.param_set_range(0., Geom::infinity()); @@ -86,7 +90,12 @@ void LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem) { displace_x.resetRandomizer(); displace_y.resetRandomizer(); - global_randomize.resetRandomizer(); + if(!spray_tool_friendly){ + global_randomize.resetRandomizer(); + } else { + boost::hash string_hash; + global_randomize.param_set_value(global_randomize.get_value(), static_cast(string_hash(lpeitem->getId()))); + } srand(1); SPLPEItem * item = const_cast(lpeitem); item->apply_to_clippath(item); @@ -131,6 +140,15 @@ Gtk::Widget *LPERoughen::newWidget() vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET); } + if (param->param_key == "shift_nodes") { + Gtk::Label *options = Gtk::manage(new Gtk::Label( + Glib::ustring(_("Options Modify options to rough")), + Gtk::ALIGN_START)); + options->set_use_markup(true); + vbox->pack_start(*options, false, false, 2); + vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), + Gtk::PACK_EXPAND_WIDGET); + } Glib::ustring *tip = param->param_getTooltip(); if (widg) { vbox->pack_start(*widg, true, true, 2); @@ -142,7 +160,6 @@ Gtk::Widget *LPERoughen::newWidget() } } } - ++it; } return dynamic_cast(vbox); diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index 57a516310..178c3b657 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -55,6 +55,7 @@ private: BoolParam retract_handles; BoolParam shift_handles_sym; BoolParam fixed_displacement; + BoolParam spray_tool_friendly; LPERoughen(const LPERoughen &); LPERoughen &operator=(const LPERoughen &); diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index c1e8f8a7b..9ecadbdeb 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -21,8 +21,8 @@ namespace LivePathEffect { BoolParam::BoolParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, bool default_value ) - : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value) + Effect* effect, bool default_value , bool no_widget) + : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value), hide_widget(no_widget) { } @@ -53,20 +53,24 @@ BoolParam::param_getSVGValue() const Gtk::Widget * BoolParam::param_newWidget() { - Inkscape::UI::Widget::RegisteredCheckButton * checkwdg = Gtk::manage( - new Inkscape::UI::Widget::RegisteredCheckButton( param_label, - param_tooltip, - param_key, - *param_wr, - false, - param_effect->getRepr(), - param_effect->getSPDoc()) ); + if(!hide_widget){ + Inkscape::UI::Widget::RegisteredCheckButton * checkwdg = Gtk::manage( + new Inkscape::UI::Widget::RegisteredCheckButton( param_label, + param_tooltip, + param_key, + *param_wr, + false, + param_effect->getRepr(), + param_effect->getSPDoc()) ); - checkwdg->setActive(value); - checkwdg->setProgrammatically = false; - checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change bool parameter")); + checkwdg->setActive(value); + checkwdg->setProgrammatically = false; + checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change bool parameter")); - return dynamic_cast (checkwdg); + return dynamic_cast (checkwdg); + } else { + return NULL; + } } void diff --git a/src/live_effects/parameter/bool.h b/src/live_effects/parameter/bool.h index b45eeb0b3..403dd0b87 100644 --- a/src/live_effects/parameter/bool.h +++ b/src/live_effects/parameter/bool.h @@ -25,7 +25,8 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - bool default_value = false); + bool default_value = false, + bool no_widget = false); virtual ~BoolParam(); virtual Gtk::Widget * param_newWidget(); @@ -46,6 +47,7 @@ private: bool value; bool defvalue; + bool hide_widget; }; diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 98aab287f..d4e213948 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -54,7 +54,7 @@ void Parameter::write_to_SVG(void) */ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, gdouble default_value) + Effect* effect, gdouble default_value, bool no_widget) : Parameter(label, tip, key, wr, effect), value(default_value), min(-SCALARPARAM_G_MAXDOUBLE), @@ -65,7 +65,8 @@ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, inc_step(0.1), inc_page(1), add_slider(false), - overwrite_widget(false) + overwrite_widget(false), + hide_widget(no_widget) { } @@ -153,21 +154,25 @@ ScalarParam::param_overwrite_widget(bool overwrite_widget) Gtk::Widget * ScalarParam::param_newWidget() { - Inkscape::UI::Widget::RegisteredScalar *rsu = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar( - param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) ); - - rsu->setValue(value); - rsu->setDigits(digits); - rsu->setIncrements(inc_step, inc_page); - rsu->setRange(min, max); - rsu->setProgrammatically = false; - if (add_slider) { - rsu->addSlider(); - } - if(!overwrite_widget){ - rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); + if(!hide_widget){ + Inkscape::UI::Widget::RegisteredScalar *rsu = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar( + param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) ); + + rsu->setValue(value); + rsu->setDigits(digits); + rsu->setIncrements(inc_step, inc_page); + rsu->setRange(min, max); + rsu->setProgrammatically = false; + if (add_slider) { + rsu->addSlider(); + } + if(!overwrite_widget){ + rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); + } + return dynamic_cast (rsu); + } else { + return NULL; } - return dynamic_cast (rsu); } void diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h index 8cda42a8e..0ef28650a 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -102,7 +102,8 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - gdouble default_value = 1.0); + gdouble default_value = 1.0, + bool no_widget = false); virtual ~ScalarParam(); virtual bool param_readSVGValue(const gchar * strvalue); @@ -133,6 +134,7 @@ protected: double inc_page; bool add_slider; bool overwrite_widget; + bool hide_widget; private: ScalarParam(const ScalarParam&); -- cgit v1.2.3 From 58dd8e4f061599778f4c6d8c958b13f0fc99f06f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 19 Oct 2015 11:13:44 +0200 Subject: Change oprions of handles to a enum widget Add parameter to limit angle in mode smooth Bug fixes and improvements to "Spray Friendly" option (bzr r14421) --- src/live_effects/lpe-roughen.cpp | 135 ++++++++++++++++++++++++++++----------- src/live_effects/lpe-roughen.h | 22 +++++-- 2 files changed, 113 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 136190b8f..d40d549a7 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -33,13 +33,22 @@ static const Util::EnumData DivisionMethodData[DM_END] = { static const Util::EnumDataConverter DMConverter(DivisionMethodData, DM_END); +static const Util::EnumData HandlesMethodData[HM_END] = { + { HM_ALONG_NODES, N_("Along nodes"), "along" }, + { HM_RAND, N_("Rand"), "rand" }, + { HM_RETRACT, N_("Retract"), "retract" }, + { HM_SMOOTH, N_("Smooth"), "smooth" } +}; +static const Util::EnumDataConverter +HMConverter(HandlesMethodData, HM_END); + LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) : Effect(lpeobject), // initialise your parameters here: method(_("Method"), _("Division method"), "method", DMConverter, &wr, this, DM_SEGMENTS), max_segment_size(_("Max. segment size"), _("Max. segment size"), - "max_segment_size", &wr, this, 10.), + "max_segment_size", &wr, this, 10), segments(_("Number of segments"), _("Number of segments"), "segments", &wr, this, 2), displace_x(_("Max. displacement in X"), _("Max. displacement in X"), @@ -48,14 +57,12 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) "displace_y", &wr, this, 10.), global_randomize(_("Global randomize"), _("Global randomize"), "global_randomize", &wr, this, 1.), + handles(_("Handles"), _("Handles options"), "handles", HMConverter, &wr, + this, HM_ALONG_NODES), + max_smooth_angle(_("Max. smooth handle angle"), _("Max. smooth handle angle"), + "max_smooth_angle", &wr, this, 20), shift_nodes(_("Shift nodes"), _("Shift nodes"), "shift_nodes", &wr, this, true), - shift_handles(_("Shift node handles"), _("Shift node handles"), - "shift_handles", &wr, this, true), - retract_handles(_("Retract node handles"), _("Retract node handles"), - "retract_handles", &wr, this, false), - shift_handles_sym(_("Sym shift node handles"), _("Sym shift node handles"), - "shift_handles_sym", &wr, this, false), fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment lenght"), "fixed_displacement", &wr, this, false), spray_tool_friendly(_("Spray Tool friendly"), _("For use with spray tool"), @@ -67,10 +74,9 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) registerParameter(&displace_x); registerParameter(&displace_y); registerParameter(&global_randomize); + registerParameter(&handles); + registerParameter(&max_smooth_angle); registerParameter(&shift_nodes); - registerParameter(&shift_handles); - registerParameter(&retract_handles); - registerParameter(&shift_handles_sym); registerParameter(&fixed_displacement); registerParameter(&spray_tool_friendly); displace_x.param_set_range(0., Geom::infinity()); @@ -82,20 +88,24 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) segments.param_set_range(1, Geom::infinity()); segments.param_set_increments(1, 1); segments.param_set_digits(0); + max_smooth_angle.param_set_range(0, 359); + max_smooth_angle.param_set_increments(1, 1); + max_smooth_angle.param_set_digits(0); + seed = 0; } LPERoughen::~LPERoughen() {} void LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem) { + if(spray_tool_friendly && seed == 0){ + std::string id_item(SP_OBJECT(lpeitem)->getId()); + long seed = static_cast(boost::hash_value(id_item)); + global_randomize.param_set_value(global_randomize.get_value(), seed); + } displace_x.resetRandomizer(); displace_y.resetRandomizer(); - if(!spray_tool_friendly){ - global_randomize.resetRandomizer(); - } else { - boost::hash string_hash; - global_randomize.param_set_value(global_randomize.get_value(), static_cast(string_hash(lpeitem->getId()))); - } + global_randomize.resetRandomizer(); srand(1); SPLPEItem * item = const_cast(lpeitem); item->apply_to_clippath(item); @@ -140,7 +150,7 @@ Gtk::Widget *LPERoughen::newWidget() vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET); } - if (param->param_key == "shift_nodes") { + if (param->param_key == "handles") { Gtk::Label *options = Gtk::manage(new Gtk::Label( Glib::ustring(_("Options Modify options to rough")), Gtk::ALIGN_START)); @@ -173,11 +183,19 @@ double LPERoughen::sign(double random_number) return random_number; } -Geom::Point LPERoughen::randomize(double max_lenght) +Geom::Point LPERoughen::randomize(double max_lenght, double direction) { double displace_x_parsed = displace_x * global_randomize; double displace_y_parsed = displace_y * global_randomize; Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed)); + if( direction != 0){ + int angle = (int)max_smooth_angle; + if (angle == 0){ + angle = 1; + } + double dist = Geom::distance(Geom::Point(0,0),output); + output = Geom::Point::polar(direction + sign(Geom::deg_to_rad(rand() % angle)), dist); + } if( fixed_displacement ){ Geom::Ray ray(Geom::Point(0,0),output); output = Geom::Point::polar(ray.angle(), max_lenght); @@ -199,6 +217,7 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::Path::const_iterator curve_endit = path_it->end_default(); SPCurve *nCurve = new SPCurve(); Geom::Point prev(0, 0); + Geom::Point last_move(0, 0); nCurve->moveto(curve_it1->initialPoint()); while (curve_it1 != curve_endit) { Geom::CubicBezier const *cubic = NULL; @@ -222,14 +241,14 @@ void LPERoughen::doEffect(SPCurve *curve) } SPCurve const * tmp; if (splits == 1) { - tmp = jitter(nCurve->last_segment(), prev); + tmp = jitter(nCurve->last_segment(), prev, last_move); } else { bool last = false; if(t == splits-1){ last = true; } double time = Geom::nearest_time(original->pointAt((1. / (double)splits) * t), *nCurve->last_segment()); - tmp = addNodesAndJitter(nCurve->last_segment(), prev, time, last); + tmp = addNodesAndJitter(nCurve->last_segment(), prev, last_move, time, last); } if (nCurve->get_segment_count() > 1) { nCurve->backspace(); @@ -243,7 +262,7 @@ void LPERoughen::doEffect(SPCurve *curve) ++curve_it2; } if (path_it->closed()) { - if(shift_handles_sym && curve_it1 == curve_endit && !retract_handles){ + if(handles == HM_SMOOTH && curve_it1 == curve_endit){ SPCurve *out = new SPCurve(); nCurve = nCurve->create_reverse(); Geom::CubicBezier const *cubic_start = dynamic_cast(nCurve->first_segment()); @@ -265,6 +284,18 @@ void LPERoughen::doEffect(SPCurve *curve) nCurve->append_continuous(out, 0.001); nCurve = nCurve->create_reverse(); } + if(handles == HM_ALONG_NODES && curve_it1 == curve_endit){ + SPCurve *out = new SPCurve(); + nCurve = nCurve->create_reverse(); + Geom::CubicBezier const *cubic = dynamic_cast(nCurve->last_segment()); + if(cubic){ + out->moveto((*cubic)[0]); + out->curveto((*cubic)[1], (*cubic)[2] - last_move, (*cubic)[3]); + nCurve->backspace(); + nCurve->append_continuous(out, 0.001); + } + nCurve = nCurve->create_reverse(); + } nCurve->move_endpoints(nCurve->last_segment()->finalPoint(), nCurve->last_segment()->finalPoint()); nCurve->closepath_current(); } @@ -274,7 +305,7 @@ void LPERoughen::doEffect(SPCurve *curve) } } -SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last) +SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move, double t, bool last) { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast(&*A); @@ -291,7 +322,7 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point point_b3 = randomize(max_lenght); } } - if (shift_handles || shift_handles_sym) { + if (handles == HM_RAND || handles == HM_SMOOTH) { point_a1 = randomize(max_lenght); point_a2 = randomize(max_lenght); point_b1 = randomize(max_lenght); @@ -305,7 +336,7 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point point_b2 = point_b3; } } - if(retract_handles){ + if(handles == HM_RETRACT){ out->moveto(A->initialPoint()); out->lineto(A->pointAt(t) + point_a3); if(cubic && !last){ @@ -315,7 +346,7 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point } else { out->lineto(A->finalPoint() + point_b3); } - } else if(shift_handles_sym && cubic) { + } else if(handles == HM_SMOOTH && cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); @@ -324,6 +355,12 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } + ray.setPoints(seg1[3] + point_a3, seg2[1] + point_a3); + point_b1 = randomize(max_lenght, ray.angle()); + if(last){ + ray.setPoints(seg2[3] + point_b3, A->pointAt(1 - (t / 3)) + point_b3); + point_b2 = randomize(max_lenght, ray.angle()); + } ray.setPoints(seg2[1] + point_a3 + point_b1, seg2[0] + point_a3); point_a2 = Geom::Point::polar(ray.angle(), max_lenght); if(last){ @@ -338,12 +375,18 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point } else { out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); } - } else if(shift_handles_sym && !cubic) { + } else if(handles == HM_SMOOTH && !cubic) { Geom::Ray ray(prev,A->initialPoint()); point_a1 = Geom::Point::polar(ray.angle(), max_lenght); if(prev==Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } + ray.setPoints(A->pointAt(t) + point_a3, A->pointAt(t + (t / 3)) + point_a3); + point_b1 = randomize(max_lenght, ray.angle()); + if(last){ + ray.setPoints(A->finalPoint() + point_b3, A->pointAt(t +((t / 3) * 2)) + point_b3); + point_b2 = randomize(max_lenght, ray.angle()); + } ray.setPoints(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t) + point_a3); point_a2 = Geom::Point::polar(ray.angle(), max_lenght); if(last){ @@ -359,9 +402,18 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); out->moveto(seg1[0]); - out->curveto(seg1[1] + point_a1, seg1[2] + point_a2 + point_a3, seg1[3] + point_a3); - out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); - } else if (shift_handles) { + if(handles == HM_ALONG_NODES){ + out->curveto(seg1[1] + last_move, seg1[2] + point_a3, seg1[3] + point_a3); + last_move = point_a3; + if(last){ + last_move = point_b3; + } + out->curveto(seg2[1] + point_a3, seg2[2] + point_b3, seg2[3] + point_b3); + } else { + out->curveto(seg1[1] + point_a1, seg1[2] + point_a2 + point_a3, seg1[3] + point_a3); + out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); + } + } else if (handles == HM_RAND) { out->moveto(A->initialPoint()); out->curveto(A->pointAt(t / 3) + point_a1, A->pointAt((t / 3) * 2) + point_a2 + point_a3, A->pointAt(t) + point_a3); out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); @@ -373,7 +425,7 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point return out; } -SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev) +SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move) { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast(&*A); @@ -384,35 +436,44 @@ SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev) if (shift_nodes) { point_a3 = randomize(max_lenght); } - if (shift_handles || shift_handles_sym) { + if (handles == HM_RAND || handles == HM_SMOOTH) { point_a1 = randomize(max_lenght); point_a2 = randomize(max_lenght); } - if(retract_handles){ + if(handles == HM_RETRACT){ out->moveto(A->initialPoint()); out->lineto(A->finalPoint() + point_a3); - } else if(shift_handles_sym && cubic) { + } else if(handles == HM_SMOOTH && cubic) { Geom::Ray ray(prev,A->initialPoint()); point_a1 = Geom::Point::polar(ray.angle(), max_lenght); if(prev == Geom::Point(0,0)){ point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); } + ray.setPoints((*cubic)[3] + point_a3, (*cubic)[2] + point_a3); + point_a2 = randomize(max_lenght, ray.angle()); prev = (*cubic)[2] + point_a2; out->moveto((*cubic)[0]); out->curveto((*cubic)[0] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); - } else if(shift_handles_sym && !cubic) { + } else if(handles == HM_SMOOTH && !cubic) { Geom::Ray ray(prev,A->initialPoint()); point_a1 = Geom::Point::polar(ray.angle(), max_lenght); if(prev==Geom::Point(0,0)){ point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); } - prev = A->pointAt((1.0/3.0) * 2) + point_a2; + ray.setPoints(A->finalPoint() + point_a3, A->pointAt((1.0/3.0) * 2) + point_a3); + point_a2 = randomize(max_lenght, ray.angle()); + prev = A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3; out->moveto(A->initialPoint()); out->curveto(A->initialPoint() + point_a1, A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3, A->finalPoint() + point_a3); } else if (cubic) { out->moveto((*cubic)[0]); - out->curveto((*cubic)[1] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); - } else if (shift_handles) { + if(handles == HM_ALONG_NODES){ + out->curveto((*cubic)[1] + last_move, (*cubic)[2] + point_a3, (*cubic)[3] + point_a3); + last_move = point_a3; + } else { + out->curveto((*cubic)[1] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); + } + } else if (handles == HM_RAND) { out->moveto(A->initialPoint()); out->curveto(A->pointAt(0.3333) + point_a1, A->pointAt(0.6666) + point_a2 + point_a3, A->finalPoint() + point_a3); diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index 178c3b657..e3ede2c2d 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -28,6 +28,15 @@ enum DivisionMethod { DM_END }; +enum HandlesMethod { + HM_ALONG_NODES, + HM_RAND, + HM_RETRACT, + HM_SMOOTH, + HM_END +}; + + class LPERoughen : public Effect { public: @@ -36,10 +45,10 @@ public: virtual void doEffect(SPCurve *curve); virtual double sign(double randNumber); - virtual Geom::Point randomize(double max_lenght); + virtual Geom::Point randomize(double max_lenght, double direction = 0); virtual void doBeforeEffect(SPLPEItem const * lpeitem); - virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last); - virtual SPCurve *jitter(Geom::Curve const * A, Geom::Point &prev); + virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move, double t, bool last); + virtual SPCurve *jitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move); virtual Geom::Point tPoint(Geom::Point A, Geom::Point B, double t = 0.5); virtual Gtk::Widget *newWidget(); @@ -50,13 +59,12 @@ private: RandomParam displace_x; RandomParam displace_y; RandomParam global_randomize; + EnumParam handles; + ScalarParam max_smooth_angle; BoolParam shift_nodes; - BoolParam shift_handles; - BoolParam retract_handles; - BoolParam shift_handles_sym; BoolParam fixed_displacement; BoolParam spray_tool_friendly; - + long seed; LPERoughen(const LPERoughen &); LPERoughen &operator=(const LPERoughen &); -- cgit v1.2.3 From ec23a0d460ce389d91e3e8d71d786cf0599ab01e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 19 Oct 2015 13:40:43 +0200 Subject: Fix first handle position on along nodes mode (bzr r14422) --- src/live_effects/lpe-roughen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index d40d549a7..cea91509e 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -290,7 +290,7 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::CubicBezier const *cubic = dynamic_cast(nCurve->last_segment()); if(cubic){ out->moveto((*cubic)[0]); - out->curveto((*cubic)[1], (*cubic)[2] - last_move, (*cubic)[3]); + out->curveto((*cubic)[1], (*cubic)[2] - ((*cubic)[3] - nCurve->first_segment()->initialPoint()) , (*cubic)[3]); nCurve->backspace(); nCurve->append_continuous(out, 0.001); } -- cgit v1.2.3 From 78bbb2b4edb14d0c8eb7181c4925c1f89ac30f4e Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Mon, 19 Oct 2015 18:01:08 +0200 Subject: Extensions. Fix for bug #1506043 (PDF import options always default to Poppler/Cairo import). Fixed bugs: - https://launchpad.net/bugs/1506043 (bzr r14423) --- src/extension/internal/pdfinput/pdf-input.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index 363061734..c1940b16a 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -223,6 +223,7 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/) _importViaInternal->set_can_focus(); _importViaInternal->set_relief(Gtk::RELIEF_NORMAL); _importViaInternal->set_mode(true); + _importViaInternal->set_active(true); _labelViaPoppler->set_line_wrap(true); _labelViaInternal->set_line_wrap(true); #endif -- cgit v1.2.3 From cea94017f3a35b0f678affd5b0a012a84885dea6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 19 Oct 2015 19:48:53 +0200 Subject: fixing roughen (bzr r14422.1.1) --- src/live_effects/lpe-roughen.cpp | 69 +++++++++++++++++++++------------------- src/live_effects/lpe-roughen.h | 3 +- 2 files changed, 39 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index cea91509e..44f9c6be5 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -183,19 +183,15 @@ double LPERoughen::sign(double random_number) return random_number; } -Geom::Point LPERoughen::randomize(double max_lenght, double direction) +Geom::Point LPERoughen::randomize(double max_lenght, bool is_node) { - double displace_x_parsed = displace_x * global_randomize; - double displace_y_parsed = displace_y * global_randomize; - Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed)); - if( direction != 0){ - int angle = (int)max_smooth_angle; - if (angle == 0){ - angle = 1; - } - double dist = Geom::distance(Geom::Point(0,0),output); - output = Geom::Point::polar(direction + sign(Geom::deg_to_rad(rand() % angle)), dist); + double factor = 1.0/3.0; + if(is_node){ + factor = 1.0; } + double displace_x_parsed = displace_x * global_randomize * factor; + double displace_y_parsed = displace_y * global_randomize * factor; + Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed)); if( fixed_displacement ){ Geom::Ray ray(Geom::Point(0,0),output); output = Geom::Point::polar(ray.angle(), max_lenght); @@ -203,6 +199,19 @@ Geom::Point LPERoughen::randomize(double max_lenght, double direction) return output; } +Geom::Point LPERoughen::randomize(double lenght, Geom::Point start, Geom::Point end) +{ + int angle = (int)max_smooth_angle; + if (angle == 0){ + angle = 1; + } + Geom::Ray ray(start, end); + if(!fixed_displacement ){ + lenght = Geom::distance(start, end); + } + return Geom::Point::polar(ray.angle() + sign(Geom::deg_to_rad(rand() % angle)), lenght) + start; +} + void LPERoughen::doEffect(SPCurve *curve) { Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); @@ -317,9 +326,9 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point Geom::Point point_b2(0, 0); Geom::Point point_b3(0, 0); if (shift_nodes) { - point_a3 = randomize(max_lenght); + point_a3 = randomize(max_lenght, true); if(last){ - point_b3 = randomize(max_lenght); + point_b3 = randomize(max_lenght, true); } } if (handles == HM_RAND || handles == HM_SMOOTH) { @@ -350,42 +359,38 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); + point_b3 = seg2[3] + point_b3; + point_a3 = seg1[3] + point_a3; + point_b1 = randomize(max_lenght, point_a3, seg2[1]); + point_b2 = seg1[2] + point_b2; Geom::Ray ray(prev,A->initialPoint()); - point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } - ray.setPoints(seg1[3] + point_a3, seg2[1] + point_a3); - point_b1 = randomize(max_lenght, ray.angle()); if(last){ - ray.setPoints(seg2[3] + point_b3, A->pointAt(1 - (t / 3)) + point_b3); - point_b2 = randomize(max_lenght, ray.angle()); + ray.setPoints(point_b3, point_a3); + point_b2 = randomize(max_lenght, point_b3, ray.pointAt(100.0/3.0)); } - ray.setPoints(seg2[1] + point_a3 + point_b1, seg2[0] + point_a3); - point_a2 = Geom::Point::polar(ray.angle(), max_lenght); + ray.setPoints(point_b1, point_a3); + point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); if(last){ - prev = A->pointAt(1 - (t / 3)) + point_b2 + point_b3; + prev = point_b2; } else { - prev = seg1[3] + point_a2 + point_a3; + prev = point_a2; } out->moveto(seg1[0]); - out->curveto(seg1[0] + point_a1, seg1[3] + point_a2 + point_a3, seg1[3] + point_a3); - if(last){ - out->curveto(seg2[1] + point_a3 + point_b1, A->pointAt(1 - (t / 3)) + point_b2 + point_b3, seg2[3] + point_b3); - } else { - out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); - } + out->curveto(point_a1,point_a2,point_a3); + out->curveto(point_b1, point_b2, point_b3); } else if(handles == HM_SMOOTH && !cubic) { Geom::Ray ray(prev,A->initialPoint()); point_a1 = Geom::Point::polar(ray.angle(), max_lenght); if(prev==Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } - ray.setPoints(A->pointAt(t) + point_a3, A->pointAt(t + (t / 3)) + point_a3); - point_b1 = randomize(max_lenght, ray.angle()); + point_b1 = randomize(max_lenght, A->pointAt(t) + point_a3, A->pointAt(t + (t / 3)) + point_a3); if(last){ - ray.setPoints(A->finalPoint() + point_b3, A->pointAt(t +((t / 3) * 2)) + point_b3); - point_b2 = randomize(max_lenght, ray.angle()); + point_b2 = randomize(max_lenght, A->finalPoint() + point_b3, A->pointAt(t +((t / 3) * 2)) + point_b3); } ray.setPoints(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t) + point_a3); point_a2 = Geom::Point::polar(ray.angle(), max_lenght); diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index e3ede2c2d..6224c09fa 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -45,7 +45,8 @@ public: virtual void doEffect(SPCurve *curve); virtual double sign(double randNumber); - virtual Geom::Point randomize(double max_lenght, double direction = 0); + virtual Geom::Point randomize(double max_lenght, bool is_node = false); + virtual Geom::Point randomize(double lenght, Geom::Point start, Geom::Point end); virtual void doBeforeEffect(SPLPEItem const * lpeitem); virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move, double t, bool last); virtual SPCurve *jitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move); -- cgit v1.2.3 From ccdb4ca4cc4aa57445c770c8410d68f777cf6ba2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 20 Oct 2015 01:06:16 +0200 Subject: working 2 ways (bzr r14422.1.2) --- src/live_effects/lpe-roughen.cpp | 34 +++++++++++++++++++-------------- src/ui/tools/spray-tool.cpp | 41 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 44f9c6be5..55ca77e9c 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -359,18 +359,19 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); + point_b1 = randomize(max_lenght, seg1[3] + point_a3, seg2[1] + point_a3); + point_b2 = seg1[2]; point_b3 = seg2[3] + point_b3; point_a3 = seg1[3] + point_a3; - point_b1 = randomize(max_lenght, point_a3, seg2[1]); - point_b2 = seg1[2] + point_b2; Geom::Ray ray(prev,A->initialPoint()); point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } if(last){ - ray.setPoints(point_b3, point_a3); - point_b2 = randomize(max_lenght, point_b3, ray.pointAt(100.0/3.0)); + Geom::Path b2(point_b3); + b2.appendNew(point_a3); + point_b2 = randomize(max_lenght, point_b3, b2.pointAt(1.0/3.0)); } ray.setPoints(point_b1, point_a3); point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); @@ -383,25 +384,30 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point out->curveto(point_a1,point_a2,point_a3); out->curveto(point_b1, point_b2, point_b3); } else if(handles == HM_SMOOTH && !cubic) { + point_b1 = randomize(max_lenght, A->pointAt(t) + point_a3, A->pointAt(t + (t / 3))); + point_b2 = A->pointAt(t +((t / 3) * 2)); + point_b3 = A->finalPoint() + point_b3; + point_a3 = A->pointAt(t) + point_a3; Geom::Ray ray(prev,A->initialPoint()); - point_a1 = Geom::Point::polar(ray.angle(), max_lenght); - if(prev==Geom::Point(0,0)){ + point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); + if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } - point_b1 = randomize(max_lenght, A->pointAt(t) + point_a3, A->pointAt(t + (t / 3)) + point_a3); if(last){ - point_b2 = randomize(max_lenght, A->finalPoint() + point_b3, A->pointAt(t +((t / 3) * 2)) + point_b3); + Geom::Path b2(point_b3); + b2.appendNew(point_a3); + point_b2 = randomize(max_lenght, point_b3, b2.pointAt(1.0/3.0)); } - ray.setPoints(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t) + point_a3); - point_a2 = Geom::Point::polar(ray.angle(), max_lenght); + ray.setPoints(point_b1, point_a3); + point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); if(last){ - prev = A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3; + prev = point_b2; } else { - prev = A->pointAt(t) + point_a3 + point_a2; + prev = point_a2; } out->moveto(A->initialPoint()); - out->curveto(A->initialPoint() + point_a1, A->pointAt(t) + point_a3 + point_a2, A->pointAt(t) + point_a3); - out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); + out->curveto(point_a1,point_a2,point_a3); + out->curveto(point_b1, point_b2, point_b3); } else if (cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index e2be5ca4b..240d002ae 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -380,6 +380,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, Inkscape::XML::Node *old_repr = item->getRepr(); Inkscape::XML::Node *parent = old_repr->parent(); Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); + copy->setAttribute("inkscape:spray-origin", item->getId()); parent->appendChild(copy); SPObject *new_obj = doc->getObjectByRepr(copy); @@ -393,6 +394,46 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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])); did = true; + Geom::OptRect bbox = item_copied->desktopGeometricBounds(); + std::vector items = desktop->getDocument()->getItemsInBox(desktop->dkey, *bbox); + for (std::vector::const_iterator i=items.begin(); i!=items.end(); i++) { + SPItem *item_down = *i; + std::cout << item_down->getAttribute("inkscape:spray-origin") << "asdgfasdasas\n"; + if(item_down->getAttribute("inkscape:spray-origin") &&( strcmp(item_down->getAttribute("inkscape:spray-origin"),item->getId()) == 0 || strcmp(item_down->getId(),item->getId()) == 0)){ + if(!SP_IS_GROUP(item)){ + SPShape *down_item_shape = dynamic_cast(item_down); + if (down_item_shape) { + Geom::PathVector c; + SPPath *down_item_path = dynamic_cast(down_item_shape); + if (down_item_path) { + c = down_item_path->get_curve()->get_pathvector(); + } else { + c = down_item_shape->getCurve()->get_pathvector(); + } + if (c) { + SPShape *copied_item_shape = dynamic_cast(item_copied); + if (copied_item_shape) { + Geom::PathVector d; + SPPath *copied_item_path = dynamic_cast(copied_item_shape); + if (copied_item_path) { + d = copied_item_path->get_curve()->get_pathvector(); + } else { + d = copied_item_shape->getCurve()->get_pathvector(); + } + if (d) { + Geom::CrossingSet cs = Geom::crossings(c,d); + if(cs[0].size() == 0){ + continue; + } + } + } + } + } + item_copied->deleteObject(); + std::cout << item_down->getAttribute("inkscape:spray-origin") << "hasssss\n"; + did = false; + } + } } } #ifdef ENABLE_SPRAY_MODE_SINGLE_PATH -- cgit v1.2.3 From 1c4eee9dacf11acbe1dc9ec1009f46e453aa8725 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 21 Oct 2015 07:40:23 +0200 Subject: Fix for bug #1498444 (Guides flicker under the mouse after changing the label of any guide) and bug #1469514 (Crash when renaming a guideline label in a new session). Fixed bugs: - https://launchpad.net/bugs/1498444 - https://launchpad.net/bugs/1469514 (bzr r14426) --- src/sp-guide.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index b9c124138..bbdf5f260 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -103,8 +103,8 @@ void SPGuide::set(unsigned int key, const gchar *value) { } break; case SP_ATTR_INKSCAPE_LABEL: - if (this->label) g_free(this->label); - + // this->label already freed in sp_guideline_set_label (src/display/guideline.cpp) + // see bug #1498444, bug #1469514 if (value) { this->label = g_strdup(value); } else { -- cgit v1.2.3 From 913cb932fefc97f72cc834beb4129f833ccdd25a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 22 Oct 2015 08:25:32 +0200 Subject: improving spray tool (bzr r14422.2.1) --- src/ui/tools/spray-tool.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 240d002ae..c6448f818 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -57,6 +57,9 @@ #include "livarot/Shape.h" #include <2geom/circle.h> #include <2geom/transforms.h> +#include <2geom/path-intersection.h> +#include <2geom/pathvector.h> +#include <2geom/crossing.h> #include "preferences.h" #include "style.h" #include "box3d.h" @@ -380,7 +383,10 @@ static bool sp_spray_recursive(SPDesktop *desktop, Inkscape::XML::Node *old_repr = item->getRepr(); Inkscape::XML::Node *parent = old_repr->parent(); Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); - copy->setAttribute("inkscape:spray-origin", item->getId()); + std::stringstream original_id; + original_id << "#" << item->getId(); + gchar const * spray_origin = original_id.str().c_str()); + copy->setAttribute("inkscape:spray-origin", spray_origin); parent->appendChild(copy); SPObject *new_obj = doc->getObjectByRepr(copy); @@ -394,44 +400,46 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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])); did = true; - Geom::OptRect bbox = item_copied->desktopGeometricBounds(); + Geom::OptRect bbox = item_copied->documentVisualBounds(); std::vector items = desktop->getDocument()->getItemsInBox(desktop->dkey, *bbox); for (std::vector::const_iterator i=items.begin(); i!=items.end(); i++) { SPItem *item_down = *i; std::cout << item_down->getAttribute("inkscape:spray-origin") << "asdgfasdasas\n"; - if(item_down->getAttribute("inkscape:spray-origin") &&( strcmp(item_down->getAttribute("inkscape:spray-origin"),item->getId()) == 0 || strcmp(item_down->getId(),item->getId()) == 0)){ + if(item_down->getAttribute("inkscape:spray-origin") &&( strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 || strcmp(item_down->getId(),item->getId()) == 0)){ if(!SP_IS_GROUP(item)){ SPShape *down_item_shape = dynamic_cast(item_down); if (down_item_shape) { - Geom::PathVector c; + Geom::PathVector pathv; SPPath *down_item_path = dynamic_cast(down_item_shape); if (down_item_path) { - c = down_item_path->get_curve()->get_pathvector(); + pathv = down_item_path->get_curve()->get_pathvector(); } else { - c = down_item_shape->getCurve()->get_pathvector(); + pathv = down_item_shape->getCurve()->get_pathvector(); } - if (c) { + if (!pathv.empty()) { SPShape *copied_item_shape = dynamic_cast(item_copied); if (copied_item_shape) { - Geom::PathVector d; + Geom::PathVector pathv_other; SPPath *copied_item_path = dynamic_cast(copied_item_shape); if (copied_item_path) { - d = copied_item_path->get_curve()->get_pathvector(); + pathv_other = copied_item_path->get_curve()->get_pathvector(); } else { - d = copied_item_shape->getCurve()->get_pathvector(); + pathv_other = copied_item_shape->getCurve()->get_pathvector(); } - if (d) { - Geom::CrossingSet cs = Geom::crossings(c,d); + if (!pathv_other.empty()) { + Geom::CrossingSet cs = Geom::crossings(pathv, pathv_other); if(cs[0].size() == 0){ continue; } } + } } } } item_copied->deleteObject(); std::cout << item_down->getAttribute("inkscape:spray-origin") << "hasssss\n"; did = false; + break; } } } -- cgit v1.2.3 From 955f8ffeb6debbbd215314624def36f1fe8276b9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 23 Oct 2015 02:22:31 +0200 Subject: Improving spray tool (bzr r14422.1.5) --- src/ui/tools/spray-tool.cpp | 46 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index ad390ed0d..3085a870b 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -341,6 +341,8 @@ static bool fit_item(SPDesktop *desktop, Geom::Point center, double scale, double scale_variation, + Geom::Point p, + Geom::Point move, size_t limit){ Geom::OptRect bbox = item_copied->desktopVisualBounds(); std::vector items = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox); @@ -378,16 +380,20 @@ static bool fit_item(SPDesktop *desktop, // } // } // } - if(limit > 10){ + if(limit > 3){ item_copied->deleteObject(); return false; } else { sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(-scale, -scale)); - scale = (1.0 - scale_variation / 100.0) + ((1.0 + scale_variation / 100.0)/limit); + sp_item_move_rel(item_copied, Geom::Translate(Geom::Point(-move[Geom::X], move[Geom::Y]))); + Geom::Path path; + path.start(Geom::Point(move[Geom::X],-move[Geom::Y])); + path.appendNew(p); + scale = (1.0 - scale_variation / 100.0) + (scale/(limit+2)); sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale, scale)); - sp_item_move_rel(item_copied, Geom::Translate(rand() % 20 -10, rand() % 20 -10)); + sp_item_move_rel(item_copied, Geom::Translate(path.pointAt(1/(limit+2)))); limit += 1; - return fit_item(desktop, item_copied, item, spray_origin, center, scale, scale_variation, limit); + return fit_item(desktop, item_copied, item, spray_origin, center, scale, scale_variation, p, move, limit); } } } @@ -442,10 +448,13 @@ static bool sp_spray_recursive(SPDesktop *desktop, Inkscape::XML::Node *old_repr = item->getRepr(); Inkscape::XML::Node *parent = old_repr->parent(); Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); - std::stringstream original_id; - original_id << "#" << item->getId(); - gchar const * spray_origin = original_id.str().c_str(); - copy->setAttribute("inkscape:spray-origin", spray_origin); + 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); @@ -458,7 +467,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, // 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])); - did = fit_item(desktop, item_copied, item, spray_origin, center, scale_variation, _scale, 0); + Inkscape::GC::release(copy); + did = fit_item(desktop, item_copied, item, spray_origin, center, scale_variation, _scale, p , move , 9); } } #ifdef ENABLE_SPRAY_MODE_SINGLE_PATH @@ -491,6 +501,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(new_obj); @@ -513,7 +530,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, sp_selected_path_union_skip_undo(selection, selection->desktop()); selection->add(parent_item); Inkscape::GC::release(copy); - did = true; + did = fit_item(desktop, item_copied, parent_item, spray_origin, center, scale_variation, _scale, p , move , 9); } } } @@ -533,6 +550,13 @@ 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 + gchar const * spray_origin; + if(!clone->attribute("inkscape:spray-origin")){ + spray_origin = g_strdup_printf("#%s", old_repr->attribute("id")); + clone->setAttribute("inkscape:spray-origin", spray_origin); + } else { + spray_origin = clone->attribute("inkscape:spray-origin"); + } gchar *href_str = g_strdup_printf("#%s", old_repr->attribute("id")); clone->setAttribute("xlink:href", href_str, false); g_free(href_str); @@ -549,7 +573,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, Inkscape::GC::release(clone); - did = true; + did = fit_item(desktop, item_copied, item, spray_origin, center, scale_variation, _scale, p , move , 9); } } } -- cgit v1.2.3 From aba9f9838aca1f4d062dd0c0f336587accf74b44 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 23 Oct 2015 19:47:28 +0200 Subject: Removing some stringsstreams and free gchars (bzr r14393.3.3) --- src/ui/tools/measure-tool.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 81e1bea7d..87e8d5804 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -210,7 +210,7 @@ void setMeasureItem(Geom::PathVector pathv, bool is_curve, bool markers, guint32 Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *repr; repr = xml_doc->createElement("svg:path"); - gchar const *str = sp_svg_write_path(pathv); + 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; @@ -249,6 +249,7 @@ void setMeasureItem(Geom::PathVector pathv, bool is_curve, bool markers, guint32 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); @@ -408,11 +409,10 @@ void MeasureTool::writeMeasurePoint(Geom::Point point, bool is_start) { if(!namedview) { return; } - Inkscape::SVGOStringStream os; - os << point; - gchar * str = g_strdup(os.str().c_str()); - char const * measure_point = is_start ? "inkscape:measure-start" : "inkscape:measure-end"; + gchar *str = g_strdup_printf("%f,%f", point[Geom::X], point[Geom::Y]); + gchar const *measure_point = is_start ? "inkscape:measure-start" : "inkscape:measure-end"; namedview->setAttribute (measure_point, str); + g_free(str); } //This function is used to reverse the Measure, I do it in two steps because when move the knot the @@ -759,7 +759,7 @@ void MeasureTool::toMarkDimension() if (!unit_name.compare("")) { unit_name = "px"; } - double fontsize = prefs->getInt("/tools/measure/fontsize", 10.0); + 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()); @@ -770,6 +770,7 @@ void MeasureTool::toMarkDimension() 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")); } @@ -867,7 +868,7 @@ void MeasureTool::setLabelText(const char *value, Geom::Point pos, double fontsi /* Create */ Inkscape::XML::Node *rtspan = xml_doc->createElement("svg:tspan"); - rtspan->setAttribute("sodipodi:role", "line"); // otherwise, why bother creating the tspan? + rtspan->setAttribute("sodipodi:role", "line"); SPCSSAttr *css = sp_repr_css_attr_new(); std::stringstream font_size; font_size.imbue(std::locale::classic()); @@ -1199,18 +1200,18 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N for (size_t idx = 0; idx < intersections.size(); ++idx) { setMeasureCanvasItem(desktop->doc2dt(intersections[idx]), to_item, measure_repr); if(to_guides) { - std::stringstream cross_number; - cross_number.imbue(std::locale::classic()); + gchar *cross_number; if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true)) { - cross_number << _("Crossing ") << idx; + cross_number= g_strdup_printf(_("Crossing %d"), idx); } else { - cross_number << _("Crossing ") << idx + 1; + cross_number= g_strdup_printf(_("Crossing %d"), idx + 1); } 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.str().c_str()); + 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. -- cgit v1.2.3 From 51c0ac71d4f52566be5f084274a64eb0a2ee38be Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 23 Oct 2015 21:25:43 +0200 Subject: Working on spray tool (bzr r14422.1.6) --- src/ui/tools/spray-tool.cpp | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 3085a870b..040678b51 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -339,16 +339,17 @@ static bool fit_item(SPDesktop *desktop, SPItem * item, gchar const * spray_origin, Geom::Point center, - double scale, + double _scale, double scale_variation, + double &scale, + double angle, Geom::Point p, - Geom::Point move, - size_t limit){ + Geom::Point move){ Geom::OptRect bbox = item_copied->desktopVisualBounds(); std::vector items = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox); for (std::vector::const_iterator i=items.begin(); i!=items.end(); i++) { SPItem *item_down = *i; - Geom::OptRect bbox = item_down->desktopVisualBounds(); + bbox = item_down->desktopVisualBounds(); if(item_down->getId() == item->getId() || (item_down->getAttribute("inkscape:spray-origin") && item_down != item_copied && strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0)){ // if(!SP_IS_GROUP(item) && 1>2){ // SPShape *down_item_shape = dynamic_cast(item_down); @@ -380,20 +381,26 @@ static bool fit_item(SPDesktop *desktop, // } // } // } - if(limit > 3){ + sp_item_move_rel(item_copied, Geom::Translate(-move[Geom::X], move[Geom::Y])); + sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle).inverse()); + sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale,scale).inverse()); + sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale, _scale).inverse()); + + double min_scale = (1.0 - scale_variation / 100.0); + _scale = min_scale + ((_scale - min_scale)/2); + 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)); + sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); + bbox = item_copied->desktopVisualBounds(); + if(bbox->intersects(item_down->desktopVisualBounds())){ + std::cout << "deleted\n"; item_copied->deleteObject(); return false; } else { - sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(-scale, -scale)); - sp_item_move_rel(item_copied, Geom::Translate(Geom::Point(-move[Geom::X], move[Geom::Y]))); - Geom::Path path; - path.start(Geom::Point(move[Geom::X],-move[Geom::Y])); - path.appendNew(p); - scale = (1.0 - scale_variation / 100.0) + (scale/(limit+2)); - sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale, scale)); - sp_item_move_rel(item_copied, Geom::Translate(path.pointAt(1/(limit+2)))); - limit += 1; - return fit_item(desktop, item_copied, item, spray_origin, center, scale, scale_variation, p, move, limit); + std::cout << "applied\n"; + //if the element fit no other can be down so saefly return + return true; } } } @@ -468,7 +475,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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); - did = fit_item(desktop, item_copied, item, spray_origin, center, scale_variation, _scale, p , move , 9); + did = fit_item(desktop, item_copied, item, spray_origin, center, scale_variation, _scale, scale, angle, p , move); } } #ifdef ENABLE_SPRAY_MODE_SINGLE_PATH @@ -530,7 +537,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, sp_selected_path_union_skip_undo(selection, selection->desktop()); selection->add(parent_item); Inkscape::GC::release(copy); - did = fit_item(desktop, item_copied, parent_item, spray_origin, center, scale_variation, _scale, p , move , 9); + did = fit_item(desktop, item_copied, parent_item, spray_origin, center, scale_variation, _scale, scale, angle, p , move); } } } @@ -573,7 +580,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, Inkscape::GC::release(clone); - did = fit_item(desktop, item_copied, item, spray_origin, center, scale_variation, _scale, p , move , 9); + did = fit_item(desktop, item_copied, item, spray_origin, center, scale_variation, _scale, scale, angle, p , move); } } } -- cgit v1.2.3 From 2bd48486ba7584cc0eb6aa2c034f08b9c589ea5f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 24 Oct 2015 16:55:14 +0200 Subject: working in a new way (bzr r14422.1.7) --- src/ui/tools/spray-tool.cpp | 162 +++++++++++++++++++++++++++--------------- src/ui/tools/spray-tool.h | 4 +- src/widgets/spray-toolbar.cpp | 38 ++++++++++ src/widgets/toolbox.cpp | 4 ++ 4 files changed, 151 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 040678b51..21fbeccd0 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -154,6 +154,9 @@ SprayTool::SprayTool() , is_dilating(false) , has_dilated(false) , dilate_area(NULL) + , overlap(false) + , offset(0) + , hidding_items() { } @@ -226,6 +229,8 @@ void SprayTool::setup() { sp_event_context_read(this, "standard_deviation"); sp_event_context_read(this, "usepressure"); sp_event_context_read(this, "Scale"); + sp_event_context_read(this, "offset"); + sp_event_context_read(this, "overlap"); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/tools/spray/selcue")) { @@ -263,6 +268,10 @@ 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 = CLAMP(val.getDouble(), -1000.0, 1000.0); + } else if (path == "overlap") { + this->overlap = val.getBool(); } } @@ -307,6 +316,16 @@ static double get_move_standard_deviation(SprayTool *tc) return tc->standard_deviation; } +static double get_offset(SprayTool *tc) +{ + return tc->offset; +} + +static double get_overlap(SprayTool *tc) +{ + return tc->overlap; +} + /** * Method to handle the distribution of the items * @param[out] radius : radius of the position of the sprayed object @@ -335,22 +354,22 @@ static void random_position(double &radius, double &angle, double &a, double &s, } static bool fit_item(SPDesktop *desktop, - SPItem * item_copied, + Geom::OptRect bbox, SPItem * item, gchar const * spray_origin, - Geom::Point center, - double _scale, + double scale, double scale_variation, - double &scale, - double angle, - Geom::Point p, - Geom::Point move){ - Geom::OptRect bbox = item_copied->desktopVisualBounds(); - std::vector items = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox); - for (std::vector::const_iterator i=items.begin(); i!=items.end(); i++) { + std::vector hidding_items) +{ + std::vector items_down = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox); + for (std::vector::const_iterator i=items_down.begin(); i!=items_down.end(); i++) { SPItem *item_down = *i; - bbox = item_down->desktopVisualBounds(); - if(item_down->getId() == item->getId() || (item_down->getAttribute("inkscape:spray-origin") && item_down != item_copied && strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0)){ + gchar const * item_down_sharp = g_strdup_printf("#%s", item_down->getId()); + if(item_down_sharp == spray_origin || + (item_down->getAttribute("inkscape:spray-origin") && + strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 + ) + ){ // if(!SP_IS_GROUP(item) && 1>2){ // SPShape *down_item_shape = dynamic_cast(item_down); // if (down_item_shape) { @@ -381,28 +400,38 @@ static bool fit_item(SPDesktop *desktop, // } // } // } - sp_item_move_rel(item_copied, Geom::Translate(-move[Geom::X], move[Geom::Y])); - sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle).inverse()); - sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale,scale).inverse()); - sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale, _scale).inverse()); - - double min_scale = (1.0 - scale_variation / 100.0); - _scale = min_scale + ((_scale - min_scale)/2); - 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)); - sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); - bbox = item_copied->desktopVisualBounds(); - if(bbox->intersects(item_down->desktopVisualBounds())){ - std::cout << "deleted\n"; - item_copied->deleteObject(); - return false; - } else { - std::cout << "applied\n"; - //if the element fit no other can be down so saefly return - return true; - } +// sp_item_move_rel(item_copied, Geom::Translate(-move[Geom::X], move[Geom::Y])); +// sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle).inverse()); +// sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale,scale).inverse()); +// sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale, _scale).inverse()); +// +// double min_scale = (1.0 - scale_variation / 100.0); +// _scale = min_scale + ((_scale - min_scale)/2); +// 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)); +// sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); +// Geom::Point center = item_copied->getCenter(); +// sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale).inverse()); +// double min_scale = (1.0 - scale_variation / 100.0); +// scale = g_random_double_range(min_scale, 0.8); +// sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale)); +// bbox = item_copied->desktopVisualBounds(); +// if(bbox->intersects(item_down->desktopVisualBounds()) || +// bbox->contains(item_down->desktopVisualBounds()) +// ) +// { +// //this hack is for speed draw, moved and on release delete all at this point +// //item_copied->deleteObject(); +// item_copied->setHidden(true); +// hidding_items.push_back(item_copied); +// return true; +// } else { +// std::cout << "applied\n"; +// } + return false; } + std::cout << "not\n"; } return true; } @@ -423,7 +452,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, double ratio, double tilt, double rotation_variation, - gint _distrib) + gint _distrib, + std::vector hidding_items) { bool did = false; @@ -446,36 +476,52 @@ static bool sp_spray_recursive(SPDesktop *desktop, if (mode == SPRAY_MODE_COPY) { Geom::OptRect a = item->documentVisualBounds(); if (a) { - SPItem *item_copied; if(_fid <= population) { + 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::Rect rect(Geom::Point(a->top(), a->left()),Geom::Point(a->bottom(), a->right())); + Geom::Translate const s(center); + rect *= item->i2dt_affine() * s.inverse() * Geom::Scale(_scale) * s; + rect *= item->i2dt_affine() * s.inverse() * Geom::Scale(scale) * s; + rect *= item->i2dt_affine() * s.inverse() * Geom::Rotate(angle) * s; + 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()); + rect *= item->i2dt_affine() * s.inverse() * Geom::Translate(move[Geom::X], -move[Geom::Y]) * s; + Geom::OptRect bbox_transformed(Geom::Point(rect.top(), rect.left()),Geom::Point(rect.bottom(), rect.right())); + if(!fit_item(desktop, bbox_transformed, item, spray_origin, _scale, scale_variation, hidding_items)){ + double min_scale = (1.0 - scale_variation / 100.0); + _scale = g_random_double_range(min_scale, 0.8); + center=item->getCenter(); + Geom::Translate const moved_center(center); + rect *= item->i2dt_affine() * moved_center.inverse() * Geom::Scale(_scale) * moved_center; + Geom::OptRect bbox_transformed2(Geom::Point(rect.top(), rect.left()),Geom::Point(rect.bottom(), rect.right())); + if(!fit_item(desktop, bbox_transformed2, item, spray_origin, _scale, scale_variation, hidding_items)){ + return false; + } + } + SPItem *item_copied; // Duplicate SPDocument *doc = item->document; 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); - 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); - + copy->setAttribute("inkscape:spray-origin", spray_origin); SPObject *new_obj = doc->getObjectByRepr(copy); item_copied = dynamic_cast(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_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); - did = fit_item(desktop, item_copied, item, spray_origin, center, scale_variation, _scale, scale, angle, p , move); + did = true; } } #ifdef ENABLE_SPRAY_MODE_SINGLE_PATH @@ -537,7 +583,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, sp_selected_path_union_skip_undo(selection, selection->desktop()); selection->add(parent_item); Inkscape::GC::release(copy); - did = fit_item(desktop, item_copied, parent_item, spray_origin, center, scale_variation, _scale, scale, angle, p , move); + did = true; } } } @@ -579,8 +625,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); Inkscape::GC::release(clone); - - did = fit_item(desktop, item_copied, item, spray_origin, center, scale_variation, _scale, scale, angle, p , move); + did = true; } } } @@ -588,7 +633,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, return did; } -static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point p, Geom::Point vector, bool reverse) +static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point p, Geom::Point vector, bool reverse, std::vector hidding_items) { SPDesktop *desktop = tc->desktop; Inkscape::Selection *selection = desktop->getSelection(); @@ -627,7 +672,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point 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, hidding_items)) { did = true; } } @@ -687,7 +732,7 @@ bool SprayTool::root_handler(GdkEvent* event) { this->has_dilated = false; if(this->is_dilating && event->button.button == 1 && !this->space_panning) { - sp_spray_dilate(this, motion_w, desktop->dt2doc(motion_dt), Geom::Point(0,0), MOD__SHIFT(event)); + sp_spray_dilate(this, motion_w, desktop->dt2doc(motion_dt), Geom::Point(0,0), MOD__SHIFT(event), this->hidding_items); } this->has_dilated = true; @@ -717,7 +762,7 @@ bool SprayTool::root_handler(GdkEvent* event) { // Dilating: if (this->is_drawing && ( event->motion.state & GDK_BUTTON1_MASK )) { - sp_spray_dilate(this, motion_w, motion_doc, motion_doc - this->last_push, event->button.state & GDK_SHIFT_MASK? true : false); + sp_spray_dilate(this, motion_w, motion_doc, motion_doc - this->last_push, event->button.state & GDK_SHIFT_MASK? true : false, this->hidding_items); //this->last_push = motion_doc; this->has_dilated = true; @@ -750,7 +795,7 @@ bool SprayTool::root_handler(GdkEvent* event) { this->is_dilating = true; this->has_dilated = false; if(this->is_dilating && !this->space_panning) { - sp_spray_dilate(this, scroll_w, desktop->dt2doc(scroll_dt), Geom::Point(0,0), false); + sp_spray_dilate(this, scroll_w, desktop->dt2doc(scroll_dt), Geom::Point(0,0), false, this->hidding_items); } this->has_dilated = true; @@ -780,7 +825,7 @@ bool SprayTool::root_handler(GdkEvent* event) { if (!this->has_dilated) { // If we did not rub, do a light tap this->pressure = 0.03; - sp_spray_dilate(this, motion_w, desktop->dt2doc(motion_dt), Geom::Point(0,0), MOD__SHIFT(event)); + sp_spray_dilate(this, motion_w, desktop->dt2doc(motion_dt), Geom::Point(0,0), MOD__SHIFT(event), this->hidding_items); } this->is_dilating = false; this->has_dilated = false; @@ -798,6 +843,11 @@ bool SprayTool::root_handler(GdkEvent* event) { SP_VERB_CONTEXT_SPRAY, _("Spray in single path")); break; } + for (std::vector::const_iterator i=this->hidding_items.begin(); i!=this->hidding_items.end(); i++) { + SPItem *item = *i; + this->hidding_items.erase(i); + item->deleteObject(); + } } break; } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index 8df730201..1a931135f 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -86,7 +86,9 @@ public: bool has_dilated; Geom::Point last_push; SPCanvasItem *dilate_area; - + bool overlap; + double offset; + std::vector hidding_items; sigc::connection style_set_connection; static const std::string prefsPath; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 183814b7e..1d45f1796 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -102,6 +102,19 @@ static void sp_spray_scale_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ gtk_adjustment_get_value(adj)); } +static void sp_spray_offset_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/spray/offset", + gtk_adjustment_get_value(adj)); +} + +static void sp_not_overlap( GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/spray/overlap", + gtk_adjustment_get_value(adj)); +} void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { @@ -266,6 +279,31 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); g_object_set_data( holder, "spray_scale", eact ); } + + /* dont_overlap */ + { + InkAction* act = ink_action_new( "SprayNotOverlapAction", + _("Not overlap"), + _("Not overlap"), + INKSCAPE_ICON("distribute-randomize"), + secondarySize ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_not_overlap), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Offset */ + { + EgeAdjustmentAction *eact = create_adjustment_action( "SprayToolOffsetAction", + _("Min offset"), _("Min offset:"), + _("The min offset size"), + "/tools/spray/offset", 0.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + -9000.0, 9000.0, 1.0, 4.0, + 0, 0, 0, + sp_spray_offset_value_changed, NULL, 0 , 2); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index a1c32352c..c904fc356 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -317,6 +317,10 @@ static gchar const * ui_descr = " " " " " " + " " + " " + " " + " " " " -- cgit v1.2.3 From 648022706dc3a441eb79436f319540dd53cba629 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 24 Oct 2015 23:42:10 +0200 Subject: Improving Spray tool (bzr r14422.1.8) --- src/ui/tools/spray-tool.cpp | 125 +++++++++++++++++++++++++++++--------------- src/ui/tools/spray-tool.h | 1 - 2 files changed, 82 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 21fbeccd0..cc5536173 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -49,6 +49,7 @@ #include "path-chemistry.h" #include "sp-text.h" +#include "sp-root.h" #include "sp-flowtext.h" #include "display/sp-canvas.h" #include "display/canvas-bpath.h" @@ -131,6 +132,29 @@ static void sp_spray_scale_rel(Geom::Point c, SPDesktop */*desktop*/, SPItem *it item->set_i2d_affine(item->i2dt_affine() * s.inverse() * scale * s); item->doWriteTransform(item->getRepr(), item->transform); } +///* Method to scale items */ +//static Geom::Affine sp_spray_scale_rel(Geom::Point c, SPDesktop *desktop, SPItem *item, Geom::Scale const &scale, bool write) +//{ +// //Maybe isbetter create a metod inverse to set_i2d_affine to calculate transforms +// // whith objects not in tree +// Geom::Translate const s(c); +// Geom::Affine scale_computed = item->i2dt_affine() * s.inverse() * scale * s; +// Geom::Affine dt2p; /* desktop to item parent transform */ +// if (item->parent) { +// dt2p = static_cast(item->parent)->i2dt_affine().inverse(); +// } else { +// dt2p = desktop->dt2doc(); +// } +// Geom::Affine i2p( scale_computed * dt2p ); +// if(!write){ +// i2p = scale_computed * dt2p * desktop->dt2doc().inverse(); +// } +// if(write) { +// item->set_item_transform(i2p); +// item->doWriteTransform(item->getRepr(), item->transform); +// } +// return i2p; +//} SprayTool::SprayTool() : ToolBase(cursor_spray_xpm, 4, 4, false) @@ -156,7 +180,6 @@ SprayTool::SprayTool() , dilate_area(NULL) , overlap(false) , offset(0) - , hidding_items() { } @@ -355,21 +378,21 @@ static void random_position(double &radius, double &angle, double &a, double &s, } static bool fit_item(SPDesktop *desktop, Geom::OptRect bbox, - SPItem * item, - gchar const * spray_origin, - double scale, - double scale_variation, - std::vector hidding_items) + gchar const * spray_origin) { std::vector items_down = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox); + //std::cout << bbox->top() << "top" << bbox->left() << "left" << bbox->bottom() << "bottom" << bbox->right() << "rightINSIDE\n"; + std::cout << "eeeeeenter\n"; for (std::vector::const_iterator i=items_down.begin(); i!=items_down.end(); i++) { SPItem *item_down = *i; gchar const * item_down_sharp = g_strdup_printf("#%s", item_down->getId()); - if(item_down_sharp == spray_origin || + std::cout << "BUUUCCCLLLLEEEE\n"; + 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(!SP_IS_GROUP(item) && 1>2){ // SPShape *down_item_shape = dynamic_cast(item_down); // if (down_item_shape) { @@ -429,11 +452,12 @@ static bool fit_item(SPDesktop *desktop, // } else { // std::cout << "applied\n"; // } - return false; +std::cout << "coincide\n"; + return true; } std::cout << "not\n"; } - return true; + return false; } static bool sp_spray_recursive(SPDesktop *desktop, @@ -452,8 +476,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, double ratio, double tilt, double rotation_variation, - gint _distrib, - std::vector hidding_items) + gint _distrib) { bool did = false; @@ -478,6 +501,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, if (a) { if(_fid <= population) { + SPDocument *doc = item->document; gchar const * spray_origin; if(!item->getAttribute("inkscape:spray-origin")){ spray_origin = g_strdup_printf("#%s", item->getId()); @@ -485,43 +509,63 @@ static bool sp_spray_recursive(SPDesktop *desktop, spray_origin = item->getAttribute("inkscape:spray-origin"); } Geom::Point center=item->getCenter(); - Geom::Rect rect(Geom::Point(a->top(), a->left()),Geom::Point(a->bottom(), a->right())); + Geom::Path path; + path.start(Geom::Point(a->left(), a->top())); + path.appendNew(Geom::Point(a->right(), a->top())); + path.appendNew(Geom::Point(a->right(), a->bottom())); + path.appendNew(Geom::Point(a->left(), a->bottom())); + path.close(true); Geom::Translate const s(center); - rect *= item->i2dt_affine() * s.inverse() * Geom::Scale(_scale) * s; - rect *= item->i2dt_affine() * s.inverse() * Geom::Scale(scale) * s; - rect *= item->i2dt_affine() * s.inverse() * Geom::Rotate(angle) * s; + path *= item->transform.inverse() * doc->getRoot()->c2p.inverse() * item->i2dt_affine() * s.inverse() * Geom::Scale(_scale) * s * item->i2dt_affine().inverse() * doc->getRoot()->c2p * item->transform; + path *= item->transform.inverse() * doc->getRoot()->c2p.inverse() * item->i2dt_affine() * s.inverse() * Geom::Scale(scale) * s * item->i2dt_affine().inverse() * doc->getRoot()->c2p * item->transform; + path *= item->transform.inverse() * doc->getRoot()->c2p.inverse() * item->i2dt_affine() * s.inverse() * Geom::Rotate(angle) * s * item->i2dt_affine().inverse() * doc->getRoot()->c2p * item->transform; 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()); - rect *= item->i2dt_affine() * s.inverse() * Geom::Translate(move[Geom::X], -move[Geom::Y]) * s; - Geom::OptRect bbox_transformed(Geom::Point(rect.top(), rect.left()),Geom::Point(rect.bottom(), rect.right())); - if(!fit_item(desktop, bbox_transformed, item, spray_origin, _scale, scale_variation, hidding_items)){ - double min_scale = (1.0 - scale_variation / 100.0); - _scale = g_random_double_range(min_scale, 0.8); - center=item->getCenter(); - Geom::Translate const moved_center(center); - rect *= item->i2dt_affine() * moved_center.inverse() * Geom::Scale(_scale) * moved_center; - Geom::OptRect bbox_transformed2(Geom::Point(rect.top(), rect.left()),Geom::Point(rect.bottom(), rect.right())); - if(!fit_item(desktop, bbox_transformed2, item, spray_origin, _scale, scale_variation, hidding_items)){ - return false; - } - } + path *= Geom::Translate(move[Geom::X], move[Geom::Y]); + path *= desktop->doc2dt(); + //std::cout << rect.top() << "top" << rect.left() << "left" << rect.bottom() << "bottom" << rect.right() << "transformed\n"; + Geom::OptRect bbox = path.boundsFast(); + std::cout << bbox->top() << "top" << bbox->left() << "left" << bbox->bottom() << "bottom" << bbox->right() << "PREV\n"; + //std::cout << "ppp\n"; + if(!fit_item(desktop, bbox, spray_origin)){ + //std::cout << "aaa\n"; + + //return true; + +// double min_scale = (1.0 - scale_variation / 100.0); +// _scale = g_random_double_range(min_scale, 0.8); +// center=item->getCenter(); +// Geom::Translate const moved_center(center); +// rect *= item->i2dt_affine() * moved_center.inverse() * Geom::Scale(_scale) * moved_center; +// Geom::OptRect bbox_transformed2(Geom::Point(rect.left(), rect.top()),Geom::Point(rect.right(), rect.bottom())); +// if(!fit_item(desktop, bbox_transformed2, spray_origin)){ +// return true; +// } + + //std::cout << "ccc"; SPItem *item_copied; // Duplicate - SPDocument *doc = item->document; 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); - copy->setAttribute("inkscape:spray-origin", spray_origin); SPObject *new_obj = doc->getObjectByRepr(copy); item_copied = dynamic_cast(new_obj); // Conversion object->item - 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 sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); + bbox = item_copied->documentVisualBounds(); + std::cout << bbox->top() << "top" << bbox->left() << "left" << bbox->bottom() << "bottom" << bbox->right() << "POST\n"; Inkscape::GC::release(copy); did = true; + } else { + did = false; + } } } #ifdef ENABLE_SPRAY_MODE_SINGLE_PATH @@ -633,7 +677,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, return did; } -static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point p, Geom::Point vector, bool reverse, std::vector hidding_items) +static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point p, Geom::Point vector, bool reverse) { SPDesktop *desktop = tc->desktop; Inkscape::Selection *selection = desktop->getSelection(); @@ -672,7 +716,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point 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, hidding_items)) { + 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)) { did = true; } } @@ -732,7 +776,7 @@ bool SprayTool::root_handler(GdkEvent* event) { this->has_dilated = false; if(this->is_dilating && event->button.button == 1 && !this->space_panning) { - sp_spray_dilate(this, motion_w, desktop->dt2doc(motion_dt), Geom::Point(0,0), MOD__SHIFT(event), this->hidding_items); + sp_spray_dilate(this, motion_w, desktop->dt2doc(motion_dt), Geom::Point(0,0), MOD__SHIFT(event)); } this->has_dilated = true; @@ -762,7 +806,7 @@ bool SprayTool::root_handler(GdkEvent* event) { // Dilating: if (this->is_drawing && ( event->motion.state & GDK_BUTTON1_MASK )) { - sp_spray_dilate(this, motion_w, motion_doc, motion_doc - this->last_push, event->button.state & GDK_SHIFT_MASK? true : false, this->hidding_items); + sp_spray_dilate(this, motion_w, motion_doc, motion_doc - this->last_push, event->button.state & GDK_SHIFT_MASK? true : false); //this->last_push = motion_doc; this->has_dilated = true; @@ -795,7 +839,7 @@ bool SprayTool::root_handler(GdkEvent* event) { this->is_dilating = true; this->has_dilated = false; if(this->is_dilating && !this->space_panning) { - sp_spray_dilate(this, scroll_w, desktop->dt2doc(scroll_dt), Geom::Point(0,0), false, this->hidding_items); + sp_spray_dilate(this, scroll_w, desktop->dt2doc(scroll_dt), Geom::Point(0,0), false); } this->has_dilated = true; @@ -825,7 +869,7 @@ bool SprayTool::root_handler(GdkEvent* event) { if (!this->has_dilated) { // If we did not rub, do a light tap this->pressure = 0.03; - sp_spray_dilate(this, motion_w, desktop->dt2doc(motion_dt), Geom::Point(0,0), MOD__SHIFT(event), this->hidding_items); + sp_spray_dilate(this, motion_w, desktop->dt2doc(motion_dt), Geom::Point(0,0), MOD__SHIFT(event)); } this->is_dilating = false; this->has_dilated = false; @@ -843,11 +887,6 @@ bool SprayTool::root_handler(GdkEvent* event) { SP_VERB_CONTEXT_SPRAY, _("Spray in single path")); break; } - for (std::vector::const_iterator i=this->hidding_items.begin(); i!=this->hidding_items.end(); i++) { - SPItem *item = *i; - this->hidding_items.erase(i); - item->deleteObject(); - } } break; } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index 1a931135f..acdff4cb0 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -88,7 +88,6 @@ public: SPCanvasItem *dilate_area; bool overlap; double offset; - std::vector hidding_items; sigc::connection style_set_connection; static const std::string prefsPath; -- cgit v1.2.3 From 7f606e3eb5e38a645c4dc5e0c22bbe1136a1f674 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 25 Oct 2015 02:55:48 +0100 Subject: Fixed some toolbox definition and minor tweaks (bzr r14393.1.30) --- src/ui/tools/measure-tool.cpp | 23 +++++++++++++++---- src/widgets/measure-toolbar.cpp | 51 ++++++++++++++++++++++++----------------- 2 files changed, 49 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 87e8d5804..e6f56674a 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -347,14 +347,20 @@ MeasureTool::MeasureTool() 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 () ; + 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)); @@ -612,7 +618,6 @@ bool MeasureTool::root_handler(GdkEvent* event) case GDK_BUTTON_RELEASE: { this->knot_start->moveto(start_p); this->knot_start->show(); - end_p = end_p; if(last_end) { end_p = desktop->w2d(*last_end); if (event->button.state & GDK_CONTROL_MASK) { @@ -630,6 +635,7 @@ bool MeasureTool::root_handler(GdkEvent* event) this->knot_end->moveto(end_p); this->knot_end->show(); showCanvasItems(); + if (this->grabbed) { sp_canvas_item_ungrab(this->grabbed, event->button.time); this->grabbed = NULL; @@ -698,6 +704,9 @@ void MeasureTool::setMarker(bool isStart) 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(); @@ -726,12 +735,15 @@ void MeasureTool::toGuides() 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); + 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); @@ -744,6 +756,9 @@ void MeasureTool::toItem() 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); @@ -1218,7 +1233,7 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N // draw main control line { - setMeasureCanvasControlLine(start_p, end_p, false, CTLINE_SECONDARY, measure_repr); + 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; diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 0e083924e..67c128dd2 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -77,7 +77,7 @@ sp_measure_fontsize_value_changed(GtkAdjustment *adj, GObject *tbl) if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt(Glib::ustring("/tools/measure/fontsize"), + prefs->setDouble(Glib::ustring("/tools/measure/fontsize"), gtk_adjustment_get_value(adj)); MeasureTool *mt = get_measure_tool(); if (mt) { @@ -93,7 +93,7 @@ sp_measure_offset_value_changed(GtkAdjustment *adj, GObject *tbl) if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt(Glib::ustring("/tools/measure/offset"), + prefs->setDouble(Glib::ustring("/tools/measure/offset"), gtk_adjustment_get_value(adj)); MeasureTool *mt = get_measure_tool(); if (mt) { @@ -108,7 +108,7 @@ static void sp_measure_scale_value_changed(GtkAdjustment *adj, GObject *tbl) if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt(Glib::ustring("/tools/measure/scale"), + prefs->setDouble(Glib::ustring("/tools/measure/scale"), gtk_adjustment_get_value(adj)); MeasureTool *mt = get_measure_tool(); if (mt) { @@ -133,7 +133,8 @@ sp_measure_precision_value_changed(GtkAdjustment *adj, GObject *tbl) } } -static void measure_unit_changed(GtkAction* /*act*/, GObject* tbl) +static void +sp_measure_unit_changed(GtkAction* /*act*/, GObject* tbl) { UnitTracker* tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); Glib::ustring const unit = tracker->getActiveUnit()->abbr; @@ -145,11 +146,12 @@ static void measure_unit_changed(GtkAction* /*act*/, GObject* tbl) } } -static void toggle_ignore_1st_and_last( GtkToggleAction* act, gpointer data ) +static void +sp_toggle_ignore_1st_and_last( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setInt("/tools/measure/ignore_1st_and_last", active); + prefs->setBool("/tools/measure/ignore_1st_and_last", active); SPDesktop *desktop = static_cast(data); if ( active ) { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Start and end measures inactive.")); @@ -162,11 +164,12 @@ static void toggle_ignore_1st_and_last( GtkToggleAction* act, gpointer data ) } } -static void toggle_only_visible( GtkToggleAction* act, gpointer data ) +static void +sp_toggle_only_visible( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setInt("/tools/measure/only_visible", active); + prefs->setBool("/tools/measure/only_visible", active); SPDesktop *desktop = static_cast(data); if ( active ) { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Show only visible crossings.")); @@ -179,11 +182,12 @@ static void toggle_only_visible( GtkToggleAction* act, gpointer data ) } } -static void toggle_all_layers( GtkToggleAction* act, gpointer data ) +static void +sp_toggle_all_layers( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setInt("/tools/measure/all_layers", active); + prefs->setBool("/tools/measure/all_layers", active); SPDesktop *desktop = static_cast(data); if ( active ) { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Use all layers in the measure.")); @@ -196,11 +200,12 @@ static void toggle_all_layers( GtkToggleAction* act, gpointer data ) } } -static void toggle_show_in_between( GtkToggleAction* act, gpointer data ) +static void +sp_toggle_show_in_between( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setInt("/tools/measure/show_in_between", active); + prefs->setBool("/tools/measure/show_in_between", active); SPDesktop *desktop = static_cast(data); if ( active ) { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Compute all elements.")); @@ -212,28 +217,32 @@ static void toggle_show_in_between( GtkToggleAction* act, gpointer data ) mt->showCanvasItems(); } } -static void sp_reverse_knots(void){ +static void +sp_reverse_knots(void){ MeasureTool *mt = get_measure_tool(); if (mt) { mt->reverseKnots(); } } -static void sp_to_mark_dimension(void){ +static void +sp_to_mark_dimension(void){ MeasureTool *mt = get_measure_tool(); if (mt) { mt->toMarkDimension(); } } -static void sp_to_guides(void){ +static void +sp_to_guides(void){ MeasureTool *mt = get_measure_tool(); if (mt) { mt->toGuides(); } } -static void sp_to_item(void){ +static void +sp_to_item(void){ MeasureTool *mt = get_measure_tool(); if (mt) { mt->toItem(); @@ -275,7 +284,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G /* units menu */ { GtkAction* act = tracker->createAction( "MeasureUnitsAction", _("Units:"), _("The units to be used for the measurements") ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(measure_unit_changed), holder ); + g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_measure_unit_changed), holder ); gtk_action_group_add_action( mainActions, act ); } @@ -326,7 +335,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G INKSCAPE_ICON("draw-geometry-line-segment"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/ignore_1st_and_last", true) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_ignore_1st_and_last), desktop) ; + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_ignore_1st_and_last), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } /* only visible */ @@ -337,7 +346,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G INKSCAPE_ICON("zoom"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/only_visible", true) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_only_visible), desktop) ; + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_only_visible), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } /* measure imbetweens */ @@ -348,7 +357,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G INKSCAPE_ICON("distribute-randomize"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/show_in_between", true) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_show_in_between), desktop) ; + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_show_in_between), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } /* measure only current layer */ @@ -359,7 +368,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G INKSCAPE_ICON("dialog-layers"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/all_layers", true) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_all_layers), desktop) ; + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_all_layers), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } /* toogle start end */ -- cgit v1.2.3 From 6b73445c7de7d4dd58b47056f6ace72e3e49223c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 25 Oct 2015 17:47:19 +0100 Subject: End adding no overlap to spray tool (bzr r14422.1.9) --- src/ui/tools/spray-tool.cpp | 275 +++++++++++++++++++----------------------- src/ui/tools/spray-tool.h | 1 + src/widgets/spray-toolbar.cpp | 31 ++--- src/widgets/spray-toolbar.h | 2 +- src/widgets/toolbox.cpp | 3 +- 5 files changed, 143 insertions(+), 169 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index cc5536173..69a6f0435 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 * Abhishek Sharma + * Jabiertxo Arraiza * * Copyright (C) 2009 authors * @@ -132,29 +133,6 @@ static void sp_spray_scale_rel(Geom::Point c, SPDesktop */*desktop*/, SPItem *it item->set_i2d_affine(item->i2dt_affine() * s.inverse() * scale * s); item->doWriteTransform(item->getRepr(), item->transform); } -///* Method to scale items */ -//static Geom::Affine sp_spray_scale_rel(Geom::Point c, SPDesktop *desktop, SPItem *item, Geom::Scale const &scale, bool write) -//{ -// //Maybe isbetter create a metod inverse to set_i2d_affine to calculate transforms -// // whith objects not in tree -// Geom::Translate const s(c); -// Geom::Affine scale_computed = item->i2dt_affine() * s.inverse() * scale * s; -// Geom::Affine dt2p; /* desktop to item parent transform */ -// if (item->parent) { -// dt2p = static_cast(item->parent)->i2dt_affine().inverse(); -// } else { -// dt2p = desktop->dt2doc(); -// } -// Geom::Affine i2p( scale_computed * dt2p ); -// if(!write){ -// i2p = scale_computed * dt2p * desktop->dt2doc().inverse(); -// } -// if(write) { -// item->set_item_transform(i2p); -// item->doWriteTransform(item->getRepr(), item->transform); -// } -// return i2p; -//} SprayTool::SprayTool() : ToolBase(cursor_spray_xpm, 4, 4, false) @@ -339,16 +317,6 @@ static double get_move_standard_deviation(SprayTool *tc) return tc->standard_deviation; } -static double get_offset(SprayTool *tc) -{ - return tc->offset; -} - -static double get_overlap(SprayTool *tc) -{ - return tc->overlap; -} - /** * Method to handle the distribution of the items * @param[out] radius : radius of the position of the sprayed object @@ -376,88 +344,63 @@ static void random_position(double &radius, double &angle, double &a, double &s, radius = pow(radius_temp, 0.5); } + +static void sp_spray_transform_path(SPItem * item, Geom::Path &path, Geom::Affine affine, Geom::Point center){ + SPDocument *doc = item->document; + path *= doc->getRoot()->c2p.inverse(); + path *= item->transform.inverse(); + Geom::Affine dt2p; + if (item->parent) { + dt2p = static_cast(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 *= doc->getRoot()->c2p; +} + static bool fit_item(SPDesktop *desktop, + SPItem *item, Geom::OptRect bbox, - gchar const * spray_origin) + gchar const * spray_origin, + Geom::Point move, + Geom::Point center, + double angle, + double _scale, + double scale, + double offset) { + if(offset < 0){ + offset = std::min(std::min(std::abs(offset), bbox->width()/2.0),std::min(std::abs(offset), bbox->height()/2.0)) * -1; + } + bbox = Geom::Rect(Geom::Point(bbox->left() - offset, bbox->top() - offset),Geom::Point(bbox->right() + offset, bbox->bottom() + offset)); + Geom::Path path; + path.start(Geom::Point(bbox->left(), bbox->top())); + path.appendNew(Geom::Point(bbox->right(), bbox->top())); + path.appendNew(Geom::Point(bbox->right(), bbox->bottom())); + path.appendNew(Geom::Point(bbox->left(), bbox->bottom())); + path.close(true); + Geom::Translate const s(center); + 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[Geom::X], move[Geom::Y]); + path *= desktop->doc2dt(); + bbox = path.boundsFast(); std::vector items_down = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox); - //std::cout << bbox->top() << "top" << bbox->left() << "left" << bbox->bottom() << "bottom" << bbox->right() << "rightINSIDE\n"; - std::cout << "eeeeeenter\n"; for (std::vector::const_iterator i=items_down.begin(); i!=items_down.end(); i++) { SPItem *item_down = *i; gchar const * item_down_sharp = g_strdup_printf("#%s", item_down->getId()); - std::cout << "BUUUCCCLLLLEEEE\n"; 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(!SP_IS_GROUP(item) && 1>2){ -// SPShape *down_item_shape = dynamic_cast(item_down); -// if (down_item_shape) { -// Geom::PathVector pathv; -// SPPath *down_item_path = dynamic_cast(down_item_shape); -// if (down_item_path) { -// pathv = down_item_path->get_curve()->get_pathvector(); -// } else { -// pathv = down_item_shape->getCurve()->get_pathvector(); -// } -// if (!pathv.empty()) { -// SPShape *copied_item_shape = dynamic_cast(item_copied); -// if (copied_item_shape) { -// Geom::PathVector pathv_other; -// SPPath *copied_item_path = dynamic_cast(copied_item_shape); -// if (copied_item_path) { -// pathv_other = copied_item_path->get_curve()->get_pathvector(); -// } else { -// pathv_other = copied_item_shape->getCurve()->get_pathvector(); -// } -// if (!pathv_other.empty()) { -// Geom::CrossingSet cs = Geom::crossings(pathv, pathv_other); -// if(cs[0].size() == 0){ -// continue; -// } -// } -// } -// } -// } -// } -// sp_item_move_rel(item_copied, Geom::Translate(-move[Geom::X], move[Geom::Y])); -// sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle).inverse()); -// sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale,scale).inverse()); -// sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale, _scale).inverse()); -// -// double min_scale = (1.0 - scale_variation / 100.0); -// _scale = min_scale + ((_scale - min_scale)/2); -// 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)); -// sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); -// Geom::Point center = item_copied->getCenter(); -// sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale).inverse()); -// double min_scale = (1.0 - scale_variation / 100.0); -// scale = g_random_double_range(min_scale, 0.8); -// sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale)); -// bbox = item_copied->desktopVisualBounds(); -// if(bbox->intersects(item_down->desktopVisualBounds()) || -// bbox->contains(item_down->desktopVisualBounds()) -// ) -// { -// //this hack is for speed draw, moved and on release delete all at this point -// //item_copied->deleteObject(); -// item_copied->setHidden(true); -// hidding_items.push_back(item_copied); -// return true; -// } else { -// std::cout << "applied\n"; -// } -std::cout << "coincide\n"; - return true; + strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 )) + { + return false; } - std::cout << "not\n"; } - return false; + return true; } static bool sp_spray_recursive(SPDesktop *desktop, @@ -476,7 +419,10 @@ static bool sp_spray_recursive(SPDesktop *desktop, double ratio, double tilt, double rotation_variation, - gint _distrib) + gint _distrib, + bool overlap, + double offset, + size_t &limit) { bool did = false; @@ -508,40 +454,39 @@ static bool sp_spray_recursive(SPDesktop *desktop, } else { spray_origin = item->getAttribute("inkscape:spray-origin"); } - Geom::Point center=item->getCenter(); - Geom::Path path; - path.start(Geom::Point(a->left(), a->top())); - path.appendNew(Geom::Point(a->right(), a->top())); - path.appendNew(Geom::Point(a->right(), a->bottom())); - path.appendNew(Geom::Point(a->left(), a->bottom())); - path.close(true); - Geom::Translate const s(center); - path *= item->transform.inverse() * doc->getRoot()->c2p.inverse() * item->i2dt_affine() * s.inverse() * Geom::Scale(_scale) * s * item->i2dt_affine().inverse() * doc->getRoot()->c2p * item->transform; - path *= item->transform.inverse() * doc->getRoot()->c2p.inverse() * item->i2dt_affine() * s.inverse() * Geom::Scale(scale) * s * item->i2dt_affine().inverse() * doc->getRoot()->c2p * item->transform; - path *= item->transform.inverse() * doc->getRoot()->c2p.inverse() * item->i2dt_affine() * s.inverse() * Geom::Rotate(angle) * s * item->i2dt_affine().inverse() * doc->getRoot()->c2p * item->transform; + 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()); - path *= Geom::Translate(move[Geom::X], move[Geom::Y]); - path *= desktop->doc2dt(); - //std::cout << rect.top() << "top" << rect.left() << "left" << rect.bottom() << "bottom" << rect.right() << "transformed\n"; - Geom::OptRect bbox = path.boundsFast(); - std::cout << bbox->top() << "top" << bbox->left() << "left" << bbox->bottom() << "bottom" << bbox->right() << "PREV\n"; - //std::cout << "ppp\n"; - if(!fit_item(desktop, bbox, spray_origin)){ - //std::cout << "aaa\n"; - - //return true; - -// double min_scale = (1.0 - scale_variation / 100.0); -// _scale = g_random_double_range(min_scale, 0.8); -// center=item->getCenter(); -// Geom::Translate const moved_center(center); -// rect *= item->i2dt_affine() * moved_center.inverse() * Geom::Scale(_scale) * moved_center; -// Geom::OptRect bbox_transformed2(Geom::Point(rect.left(), rect.top()),Geom::Point(rect.right(), rect.bottom())); -// if(!fit_item(desktop, bbox_transformed2, spray_origin)){ -// return true; -// } - - //std::cout << "ccc"; + if(overlap){ + if(!fit_item(desktop, item, a, spray_origin, move, center, angle, _scale, scale, offset)){ + limit += 1; + //Limit recursion to 10 levels + //Seems enoght to chech if thete is place to put new copie + if(limit < 11){ + return sp_spray_recursive(desktop, + selection, + item, + p, + Geom::Point(), + mode, + radius, + population, + scale, + scale_variation, + false, + mean, + standard_deviation, + ratio, + tilt, + rotation_variation, + _distrib, + overlap, + offset, + limit); + } else { + return false; + } + } + } SPItem *item_copied; // Duplicate Inkscape::XML::Document* xml_doc = doc->getReprDoc(); @@ -559,13 +504,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle)); // Move the cursor p sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); - bbox = item_copied->documentVisualBounds(); - std::cout << bbox->top() << "top" << bbox->left() << "left" << bbox->bottom() << "bottom" << bbox->right() << "POST\n"; Inkscape::GC::release(copy); did = true; - } else { - did = false; - } } } #ifdef ENABLE_SPRAY_MODE_SINGLE_PATH @@ -636,8 +576,45 @@ 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()); + if(overlap){ + if(!fit_item(desktop, item, a, spray_origin, move, center, angle, _scale, scale, offset)){ + limit += 1; + if(limit < 11){ + return sp_spray_recursive(desktop, + selection, + item, + p, + Geom::Point(), + mode, + radius, + population, + scale, + scale_variation, + false, + mean, + standard_deviation, + ratio, + tilt, + rotation_variation, + _distrib, + overlap, + offset, + limit); + } else { + 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(); @@ -647,12 +624,8 @@ 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 - gchar const * spray_origin; if(!clone->attribute("inkscape:spray-origin")){ - spray_origin = g_strdup_printf("#%s", old_repr->attribute("id")); clone->setAttribute("inkscape:spray-origin", spray_origin); - } else { - spray_origin = clone->attribute("inkscape:spray-origin"); } gchar *href_str = g_strdup_printf("#%s", old_repr->attribute("id")); clone->setAttribute("xlink:href", href_str, false); @@ -661,11 +634,9 @@ static bool sp_spray_recursive(SPDesktop *desktop, SPObject *clone_object = doc->getObjectByRepr(clone); // Conversion object->item item_copied = dynamic_cast(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])); Inkscape::GC::release(clone); @@ -715,8 +686,8 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for(std::vector::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)) { + size_t limit = 0; + 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->overlap, tc->offset, limit)) { did = true; } } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index acdff4cb0..a46f2cc90 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 JABIERTXOF * * Copyright (C) 2009 authors * diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 1d45f1796..6a062bc46 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -15,10 +15,11 @@ * Tavmjong Bah * Abhishek Sharma * Kris De Gussem + * Jabiertxo Arraiza * * Copyright (C) 2004 David Turner * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors + * Copyright (C) 1999-2015 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -109,11 +110,11 @@ static void sp_spray_offset_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ gtk_adjustment_get_value(adj)); } -static void sp_not_overlap( GtkAdjustment *adj, GObject * /*tbl*/ ) +static void sp_toggle_not_overlap( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/overlap", - gtk_adjustment_get_value(adj)); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/overlap", active); } void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) @@ -279,26 +280,26 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); g_object_set_data( holder, "spray_scale", eact ); } - - /* dont_overlap */ + { - InkAction* act = ink_action_new( "SprayNotOverlapAction", - _("Not overlap"), - _("Not overlap"), - INKSCAPE_ICON("distribute-randomize"), - secondarySize ); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_not_overlap), 0 ); + InkToggleAction* act = ink_toggle_action_new( "SprayNotOverlapAction", + _("Not overlap"), + _("Not overlap"), + INKSCAPE_ICON("distribute-randomize"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overlap", true) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_not_overlap), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } /* Offset */ { EgeAdjustmentAction *eact = create_adjustment_action( "SprayToolOffsetAction", - _("Min offset"), _("Min offset:"), - _("The min offset size"), + _("Offset"), _("Offset:"), + _("Base offset size"), "/tools/spray/offset", 0.0, GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - -9000.0, 9000.0, 1.0, 4.0, + -1000.0, 1000.0, 1.0, 4.0, 0, 0, 0, sp_spray_offset_value_changed, NULL, 0 , 2); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); diff --git a/src/widgets/spray-toolbar.h b/src/widgets/spray-toolbar.h index d1d5c7b4c..30d8233ca 100644 --- a/src/widgets/spray-toolbar.h +++ b/src/widgets/spray-toolbar.h @@ -21,7 +21,7 @@ * * Copyright (C) 2004 David Turner * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors + * Copyright (C) 1999-2015 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index c904fc356..f512819e9 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -16,10 +16,11 @@ * Tavmjong Bah * Abhishek Sharma * Kris De Gussem + * Jabiertxo Arraiza * * Copyright (C) 2004 David Turner * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors + * Copyright (C) 1999-2015 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information -- cgit v1.2.3 From cd7e100476cf935ebbac947109012bcba2f44875 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 25 Oct 2015 17:52:07 +0100 Subject: Removing new roughen changes to create a new Spray branch (bzr r14422.1.11) --- src/live_effects/lpe-roughen.cpp | 91 ++++++++++++++++++---------------------- src/live_effects/lpe-roughen.h | 3 +- 2 files changed, 41 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 55ca77e9c..cea91509e 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -183,15 +183,19 @@ double LPERoughen::sign(double random_number) return random_number; } -Geom::Point LPERoughen::randomize(double max_lenght, bool is_node) +Geom::Point LPERoughen::randomize(double max_lenght, double direction) { - double factor = 1.0/3.0; - if(is_node){ - factor = 1.0; - } - double displace_x_parsed = displace_x * global_randomize * factor; - double displace_y_parsed = displace_y * global_randomize * factor; + double displace_x_parsed = displace_x * global_randomize; + double displace_y_parsed = displace_y * global_randomize; Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed)); + if( direction != 0){ + int angle = (int)max_smooth_angle; + if (angle == 0){ + angle = 1; + } + double dist = Geom::distance(Geom::Point(0,0),output); + output = Geom::Point::polar(direction + sign(Geom::deg_to_rad(rand() % angle)), dist); + } if( fixed_displacement ){ Geom::Ray ray(Geom::Point(0,0),output); output = Geom::Point::polar(ray.angle(), max_lenght); @@ -199,19 +203,6 @@ Geom::Point LPERoughen::randomize(double max_lenght, bool is_node) return output; } -Geom::Point LPERoughen::randomize(double lenght, Geom::Point start, Geom::Point end) -{ - int angle = (int)max_smooth_angle; - if (angle == 0){ - angle = 1; - } - Geom::Ray ray(start, end); - if(!fixed_displacement ){ - lenght = Geom::distance(start, end); - } - return Geom::Point::polar(ray.angle() + sign(Geom::deg_to_rad(rand() % angle)), lenght) + start; -} - void LPERoughen::doEffect(SPCurve *curve) { Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); @@ -326,9 +317,9 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point Geom::Point point_b2(0, 0); Geom::Point point_b3(0, 0); if (shift_nodes) { - point_a3 = randomize(max_lenght, true); + point_a3 = randomize(max_lenght); if(last){ - point_b3 = randomize(max_lenght, true); + point_b3 = randomize(max_lenght); } } if (handles == HM_RAND || handles == HM_SMOOTH) { @@ -359,55 +350,53 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); - point_b1 = randomize(max_lenght, seg1[3] + point_a3, seg2[1] + point_a3); - point_b2 = seg1[2]; - point_b3 = seg2[3] + point_b3; - point_a3 = seg1[3] + point_a3; Geom::Ray ray(prev,A->initialPoint()); - point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } + ray.setPoints(seg1[3] + point_a3, seg2[1] + point_a3); + point_b1 = randomize(max_lenght, ray.angle()); if(last){ - Geom::Path b2(point_b3); - b2.appendNew(point_a3); - point_b2 = randomize(max_lenght, point_b3, b2.pointAt(1.0/3.0)); + ray.setPoints(seg2[3] + point_b3, A->pointAt(1 - (t / 3)) + point_b3); + point_b2 = randomize(max_lenght, ray.angle()); } - ray.setPoints(point_b1, point_a3); - point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); + ray.setPoints(seg2[1] + point_a3 + point_b1, seg2[0] + point_a3); + point_a2 = Geom::Point::polar(ray.angle(), max_lenght); if(last){ - prev = point_b2; + prev = A->pointAt(1 - (t / 3)) + point_b2 + point_b3; } else { - prev = point_a2; + prev = seg1[3] + point_a2 + point_a3; } out->moveto(seg1[0]); - out->curveto(point_a1,point_a2,point_a3); - out->curveto(point_b1, point_b2, point_b3); + out->curveto(seg1[0] + point_a1, seg1[3] + point_a2 + point_a3, seg1[3] + point_a3); + if(last){ + out->curveto(seg2[1] + point_a3 + point_b1, A->pointAt(1 - (t / 3)) + point_b2 + point_b3, seg2[3] + point_b3); + } else { + out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); + } } else if(handles == HM_SMOOTH && !cubic) { - point_b1 = randomize(max_lenght, A->pointAt(t) + point_a3, A->pointAt(t + (t / 3))); - point_b2 = A->pointAt(t +((t / 3) * 2)); - point_b3 = A->finalPoint() + point_b3; - point_a3 = A->pointAt(t) + point_a3; Geom::Ray ray(prev,A->initialPoint()); - point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); - if(prev == Geom::Point(0,0)){ + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + if(prev==Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } + ray.setPoints(A->pointAt(t) + point_a3, A->pointAt(t + (t / 3)) + point_a3); + point_b1 = randomize(max_lenght, ray.angle()); if(last){ - Geom::Path b2(point_b3); - b2.appendNew(point_a3); - point_b2 = randomize(max_lenght, point_b3, b2.pointAt(1.0/3.0)); + ray.setPoints(A->finalPoint() + point_b3, A->pointAt(t +((t / 3) * 2)) + point_b3); + point_b2 = randomize(max_lenght, ray.angle()); } - ray.setPoints(point_b1, point_a3); - point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); + ray.setPoints(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t) + point_a3); + point_a2 = Geom::Point::polar(ray.angle(), max_lenght); if(last){ - prev = point_b2; + prev = A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3; } else { - prev = point_a2; + prev = A->pointAt(t) + point_a3 + point_a2; } out->moveto(A->initialPoint()); - out->curveto(point_a1,point_a2,point_a3); - out->curveto(point_b1, point_b2, point_b3); + out->curveto(A->initialPoint() + point_a1, A->pointAt(t) + point_a3 + point_a2, A->pointAt(t) + point_a3); + out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); } else if (cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index 6224c09fa..e3ede2c2d 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -45,8 +45,7 @@ public: virtual void doEffect(SPCurve *curve); virtual double sign(double randNumber); - virtual Geom::Point randomize(double max_lenght, bool is_node = false); - virtual Geom::Point randomize(double lenght, Geom::Point start, Geom::Point end); + virtual Geom::Point randomize(double max_lenght, double direction = 0); virtual void doBeforeEffect(SPLPEItem const * lpeitem); virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move, double t, bool last); virtual SPCurve *jitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move); -- cgit v1.2.3 From d3e163d627550bf1016b35d4afb75c024a508922 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 25 Oct 2015 17:54:27 +0100 Subject: Cleanup Spray tool improvements (bzr r14422.3.1) --- src/live_effects/lpe-roughen.cpp | 91 ++++++++++--------- src/live_effects/lpe-roughen.h | 3 +- src/ui/tools/spray-tool.cpp | 187 ++++----------------------------------- src/ui/tools/spray-tool.h | 4 +- src/widgets/spray-toolbar.cpp | 41 +-------- src/widgets/spray-toolbar.h | 2 +- src/widgets/toolbox.cpp | 7 +- 7 files changed, 72 insertions(+), 263 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index cea91509e..55ca77e9c 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -183,19 +183,15 @@ double LPERoughen::sign(double random_number) return random_number; } -Geom::Point LPERoughen::randomize(double max_lenght, double direction) +Geom::Point LPERoughen::randomize(double max_lenght, bool is_node) { - double displace_x_parsed = displace_x * global_randomize; - double displace_y_parsed = displace_y * global_randomize; - Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed)); - if( direction != 0){ - int angle = (int)max_smooth_angle; - if (angle == 0){ - angle = 1; - } - double dist = Geom::distance(Geom::Point(0,0),output); - output = Geom::Point::polar(direction + sign(Geom::deg_to_rad(rand() % angle)), dist); + double factor = 1.0/3.0; + if(is_node){ + factor = 1.0; } + double displace_x_parsed = displace_x * global_randomize * factor; + double displace_y_parsed = displace_y * global_randomize * factor; + Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed)); if( fixed_displacement ){ Geom::Ray ray(Geom::Point(0,0),output); output = Geom::Point::polar(ray.angle(), max_lenght); @@ -203,6 +199,19 @@ Geom::Point LPERoughen::randomize(double max_lenght, double direction) return output; } +Geom::Point LPERoughen::randomize(double lenght, Geom::Point start, Geom::Point end) +{ + int angle = (int)max_smooth_angle; + if (angle == 0){ + angle = 1; + } + Geom::Ray ray(start, end); + if(!fixed_displacement ){ + lenght = Geom::distance(start, end); + } + return Geom::Point::polar(ray.angle() + sign(Geom::deg_to_rad(rand() % angle)), lenght) + start; +} + void LPERoughen::doEffect(SPCurve *curve) { Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); @@ -317,9 +326,9 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point Geom::Point point_b2(0, 0); Geom::Point point_b3(0, 0); if (shift_nodes) { - point_a3 = randomize(max_lenght); + point_a3 = randomize(max_lenght, true); if(last){ - point_b3 = randomize(max_lenght); + point_b3 = randomize(max_lenght, true); } } if (handles == HM_RAND || handles == HM_SMOOTH) { @@ -350,53 +359,55 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); + point_b1 = randomize(max_lenght, seg1[3] + point_a3, seg2[1] + point_a3); + point_b2 = seg1[2]; + point_b3 = seg2[3] + point_b3; + point_a3 = seg1[3] + point_a3; Geom::Ray ray(prev,A->initialPoint()); - point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } - ray.setPoints(seg1[3] + point_a3, seg2[1] + point_a3); - point_b1 = randomize(max_lenght, ray.angle()); if(last){ - ray.setPoints(seg2[3] + point_b3, A->pointAt(1 - (t / 3)) + point_b3); - point_b2 = randomize(max_lenght, ray.angle()); + Geom::Path b2(point_b3); + b2.appendNew(point_a3); + point_b2 = randomize(max_lenght, point_b3, b2.pointAt(1.0/3.0)); } - ray.setPoints(seg2[1] + point_a3 + point_b1, seg2[0] + point_a3); - point_a2 = Geom::Point::polar(ray.angle(), max_lenght); + ray.setPoints(point_b1, point_a3); + point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); if(last){ - prev = A->pointAt(1 - (t / 3)) + point_b2 + point_b3; + prev = point_b2; } else { - prev = seg1[3] + point_a2 + point_a3; + prev = point_a2; } out->moveto(seg1[0]); - out->curveto(seg1[0] + point_a1, seg1[3] + point_a2 + point_a3, seg1[3] + point_a3); - if(last){ - out->curveto(seg2[1] + point_a3 + point_b1, A->pointAt(1 - (t / 3)) + point_b2 + point_b3, seg2[3] + point_b3); - } else { - out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); - } + out->curveto(point_a1,point_a2,point_a3); + out->curveto(point_b1, point_b2, point_b3); } else if(handles == HM_SMOOTH && !cubic) { + point_b1 = randomize(max_lenght, A->pointAt(t) + point_a3, A->pointAt(t + (t / 3))); + point_b2 = A->pointAt(t +((t / 3) * 2)); + point_b3 = A->finalPoint() + point_b3; + point_a3 = A->pointAt(t) + point_a3; Geom::Ray ray(prev,A->initialPoint()); - point_a1 = Geom::Point::polar(ray.angle(), max_lenght); - if(prev==Geom::Point(0,0)){ + point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); + if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } - ray.setPoints(A->pointAt(t) + point_a3, A->pointAt(t + (t / 3)) + point_a3); - point_b1 = randomize(max_lenght, ray.angle()); if(last){ - ray.setPoints(A->finalPoint() + point_b3, A->pointAt(t +((t / 3) * 2)) + point_b3); - point_b2 = randomize(max_lenght, ray.angle()); + Geom::Path b2(point_b3); + b2.appendNew(point_a3); + point_b2 = randomize(max_lenght, point_b3, b2.pointAt(1.0/3.0)); } - ray.setPoints(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t) + point_a3); - point_a2 = Geom::Point::polar(ray.angle(), max_lenght); + ray.setPoints(point_b1, point_a3); + point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); if(last){ - prev = A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3; + prev = point_b2; } else { - prev = A->pointAt(t) + point_a3 + point_a2; + prev = point_a2; } out->moveto(A->initialPoint()); - out->curveto(A->initialPoint() + point_a1, A->pointAt(t) + point_a3 + point_a2, A->pointAt(t) + point_a3); - out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); + out->curveto(point_a1,point_a2,point_a3); + out->curveto(point_b1, point_b2, point_b3); } else if (cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index e3ede2c2d..6224c09fa 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -45,7 +45,8 @@ public: virtual void doEffect(SPCurve *curve); virtual double sign(double randNumber); - virtual Geom::Point randomize(double max_lenght, double direction = 0); + virtual Geom::Point randomize(double max_lenght, bool is_node = false); + virtual Geom::Point randomize(double lenght, Geom::Point start, Geom::Point end); virtual void doBeforeEffect(SPLPEItem const * lpeitem); virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move, double t, bool last); virtual SPCurve *jitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move); diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 69a6f0435..e2be5ca4b 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -12,7 +12,6 @@ * Steren GIANNINI (steren.giannini@gmail.com) * Jon A. Cruz * Abhishek Sharma - * Jabiertxo Arraiza * * Copyright (C) 2009 authors * @@ -50,7 +49,6 @@ #include "path-chemistry.h" #include "sp-text.h" -#include "sp-root.h" #include "sp-flowtext.h" #include "display/sp-canvas.h" #include "display/canvas-bpath.h" @@ -59,9 +57,6 @@ #include "livarot/Shape.h" #include <2geom/circle.h> #include <2geom/transforms.h> -#include <2geom/path-intersection.h> -#include <2geom/pathvector.h> -#include <2geom/crossing.h> #include "preferences.h" #include "style.h" #include "box3d.h" @@ -156,8 +151,6 @@ SprayTool::SprayTool() , is_dilating(false) , has_dilated(false) , dilate_area(NULL) - , overlap(false) - , offset(0) { } @@ -230,8 +223,6 @@ void SprayTool::setup() { sp_event_context_read(this, "standard_deviation"); sp_event_context_read(this, "usepressure"); sp_event_context_read(this, "Scale"); - sp_event_context_read(this, "offset"); - sp_event_context_read(this, "overlap"); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/tools/spray/selcue")) { @@ -269,10 +260,6 @@ 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 = CLAMP(val.getDouble(), -1000.0, 1000.0); - } else if (path == "overlap") { - this->overlap = val.getBool(); } } @@ -345,64 +332,6 @@ 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){ - SPDocument *doc = item->document; - path *= doc->getRoot()->c2p.inverse(); - path *= item->transform.inverse(); - Geom::Affine dt2p; - if (item->parent) { - dt2p = static_cast(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 *= doc->getRoot()->c2p; -} - -static bool fit_item(SPDesktop *desktop, - SPItem *item, - Geom::OptRect bbox, - gchar const * spray_origin, - Geom::Point move, - Geom::Point center, - double angle, - double _scale, - double scale, - double offset) -{ - if(offset < 0){ - offset = std::min(std::min(std::abs(offset), bbox->width()/2.0),std::min(std::abs(offset), bbox->height()/2.0)) * -1; - } - bbox = Geom::Rect(Geom::Point(bbox->left() - offset, bbox->top() - offset),Geom::Point(bbox->right() + offset, bbox->bottom() + offset)); - Geom::Path path; - path.start(Geom::Point(bbox->left(), bbox->top())); - path.appendNew(Geom::Point(bbox->right(), bbox->top())); - path.appendNew(Geom::Point(bbox->right(), bbox->bottom())); - path.appendNew(Geom::Point(bbox->left(), bbox->bottom())); - path.close(true); - Geom::Translate const s(center); - 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[Geom::X], move[Geom::Y]); - path *= desktop->doc2dt(); - bbox = path.boundsFast(); - std::vector items_down = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox); - for (std::vector::const_iterator i=items_down.begin(); i!=items_down.end(); i++) { - SPItem *item_down = *i; - gchar const * item_down_sharp = g_strdup_printf("#%s", item_down->getId()); - if(strcmp(item_down_sharp, spray_origin) == 0 || - (item_down->getAttribute("inkscape:spray-origin") && - strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 )) - { - return false; - } - } - return true; -} - static bool sp_spray_recursive(SPDesktop *desktop, Inkscape::Selection *selection, SPItem *item, @@ -419,10 +348,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, double ratio, double tilt, double rotation_variation, - gint _distrib, - bool overlap, - double offset, - size_t &limit) + gint _distrib) { bool did = false; @@ -445,66 +371,27 @@ static bool sp_spray_recursive(SPDesktop *desktop, if (mode == SPRAY_MODE_COPY) { Geom::OptRect a = item->documentVisualBounds(); if (a) { + SPItem *item_copied; if(_fid <= population) { - 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()); - if(overlap){ - if(!fit_item(desktop, item, a, spray_origin, move, center, angle, _scale, scale, offset)){ - limit += 1; - //Limit recursion to 10 levels - //Seems enoght to chech if thete is place to put new copie - if(limit < 11){ - return sp_spray_recursive(desktop, - selection, - item, - p, - Geom::Point(), - mode, - radius, - population, - scale, - scale_variation, - false, - mean, - standard_deviation, - ratio, - tilt, - rotation_variation, - _distrib, - overlap, - offset, - limit); - } else { - return false; - } - } - } - SPItem *item_copied; // Duplicate + SPDocument *doc = item->document; 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(new_obj); // Conversion object->item - sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale)); - sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale)); + 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)); // 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); did = true; } } @@ -538,13 +425,6 @@ 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(new_obj); @@ -576,45 +456,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, Geom::OptRect a = item->documentVisualBounds(); if (a) { if(_fid <= population) { - 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()); - if(overlap){ - if(!fit_item(desktop, item, a, spray_origin, move, center, angle, _scale, scale, offset)){ - limit += 1; - if(limit < 11){ - return sp_spray_recursive(desktop, - selection, - item, - p, - Geom::Point(), - mode, - radius, - population, - scale, - scale_variation, - false, - mean, - standard_deviation, - ratio, - tilt, - rotation_variation, - _distrib, - overlap, - offset, - limit); - } else { - return false; - } - } - } SPItem *item_copied; + SPDocument *doc = item->document; Inkscape::XML::Document* xml_doc = doc->getReprDoc(); Inkscape::XML::Node *old_repr = item->getRepr(); Inkscape::XML::Node *parent = old_repr->parent(); @@ -624,9 +467,6 @@ 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); @@ -634,12 +474,15 @@ static bool sp_spray_recursive(SPDesktop *desktop, SPObject *clone_object = doc->getObjectByRepr(clone); // Conversion object->item item_copied = dynamic_cast(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])); Inkscape::GC::release(clone); + did = true; } } @@ -686,8 +529,8 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ SPItem *item = *i; g_assert(item != NULL); - size_t limit = 0; - 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->overlap, tc->offset, limit)) { + + 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)) { did = true; } } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index a46f2cc90..8df730201 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -12,7 +12,6 @@ * BenoĆ®t LAVORATA * Vincent MONTAGNE * Pierre BARBRY-BLOT - * Jabiertxo Arraiza JABIERTXOF * * Copyright (C) 2009 authors * @@ -87,8 +86,7 @@ public: bool has_dilated; Geom::Point last_push; SPCanvasItem *dilate_area; - bool overlap; - double offset; + sigc::connection style_set_connection; static const std::string prefsPath; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 6a062bc46..183814b7e 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -15,11 +15,10 @@ * Tavmjong Bah * Abhishek Sharma * Kris De Gussem - * Jabiertxo Arraiza * * Copyright (C) 2004 David Turner * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2015 authors + * Copyright (C) 1999-2011 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -103,19 +102,6 @@ static void sp_spray_scale_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ gtk_adjustment_get_value(adj)); } -static void sp_spray_offset_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/offset", - gtk_adjustment_get_value(adj)); -} - -static void sp_toggle_not_overlap( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/overlap", active); -} void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { @@ -281,31 +267,6 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_object_set_data( holder, "spray_scale", eact ); } - { - InkToggleAction* act = ink_toggle_action_new( "SprayNotOverlapAction", - _("Not overlap"), - _("Not overlap"), - INKSCAPE_ICON("distribute-randomize"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overlap", true) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_not_overlap), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - /* Offset */ - { - EgeAdjustmentAction *eact = create_adjustment_action( "SprayToolOffsetAction", - _("Offset"), _("Offset:"), - _("Base offset size"), - "/tools/spray/offset", 0.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - -1000.0, 1000.0, 1.0, 4.0, - 0, 0, 0, - sp_spray_offset_value_changed, NULL, 0 , 2); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - } diff --git a/src/widgets/spray-toolbar.h b/src/widgets/spray-toolbar.h index 30d8233ca..d1d5c7b4c 100644 --- a/src/widgets/spray-toolbar.h +++ b/src/widgets/spray-toolbar.h @@ -21,7 +21,7 @@ * * Copyright (C) 2004 David Turner * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2015 authors + * Copyright (C) 1999-2011 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index f512819e9..a1c32352c 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -16,11 +16,10 @@ * Tavmjong Bah * Abhishek Sharma * Kris De Gussem - * Jabiertxo Arraiza * * Copyright (C) 2004 David Turner * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2015 authors + * Copyright (C) 1999-2011 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -318,10 +317,6 @@ static gchar const * ui_descr = " " " " " " - " " - " " - " " - " " " " -- cgit v1.2.3 From 443350ec9520e6cf501c8d1137d276df18f58b4f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 25 Oct 2015 23:57:41 +0100 Subject: working on roughen (bzr r14422.3.2) --- src/live_effects/lpe-roughen.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 55ca77e9c..37a244603 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -201,15 +201,15 @@ Geom::Point LPERoughen::randomize(double max_lenght, bool is_node) Geom::Point LPERoughen::randomize(double lenght, Geom::Point start, Geom::Point end) { - int angle = (int)max_smooth_angle; - if (angle == 0){ - angle = 1; + int angle = 0; + if((int)max_smooth_angle != 0){ + angle = sign(Geom::deg_to_rad(rand() % (int)max_smooth_angle)); } Geom::Ray ray(start, end); if(!fixed_displacement ){ lenght = Geom::distance(start, end); } - return Geom::Point::polar(ray.angle() + sign(Geom::deg_to_rad(rand() % angle)), lenght) + start; + return Geom::Point::polar(ray.angle() + angle , lenght) + start; } void LPERoughen::doEffect(SPCurve *curve) @@ -360,7 +360,7 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); point_b1 = randomize(max_lenght, seg1[3] + point_a3, seg2[1] + point_a3); - point_b2 = seg1[2]; + point_b2 = seg2[2]; point_b3 = seg2[3] + point_b3; point_a3 = seg1[3] + point_a3; Geom::Ray ray(prev,A->initialPoint()); @@ -371,7 +371,10 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point if(last){ Geom::Path b2(point_b3); b2.appendNew(point_a3); - point_b2 = randomize(max_lenght, point_b3, b2.pointAt(1.0/3.0)); + double dist = Geom::distance(b2.pointAt(1.0/3.0), point_b3); + ray.setPoints(point_b3, b2.pointAt(1.0/3.0)); + point_b2 = point_b3 + Geom::Point::polar(ray.angle(), dist); + point_b2 = randomize(max_lenght, point_b3, point_b2); } ray.setPoints(point_b1, point_a3); point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); @@ -396,7 +399,10 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point if(last){ Geom::Path b2(point_b3); b2.appendNew(point_a3); - point_b2 = randomize(max_lenght, point_b3, b2.pointAt(1.0/3.0)); + double dist = Geom::distance(b2.pointAt(1.0/3.0), point_b3); + ray.setPoints(point_b3, b2.pointAt(1.0/3.0)); + point_b2 = point_b3 + Geom::Point::polar(ray.angle(), dist); + point_b2 = randomize(max_lenght, point_b3, point_b2); } ray.setPoints(point_b1, point_a3); point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); -- cgit v1.2.3 From 0ab5eb11dba2f130c7582753f5717ab002dd383e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 26 Oct 2015 10:36:22 +0100 Subject: Fixed typos from Mc Removed unnecesary added headers Put overlap default to false (bzr r14422.1.12) --- src/ui/tools/spray-tool.cpp | 5 +---- src/ui/tools/spray-tool.h | 2 +- src/widgets/spray-toolbar.cpp | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 69a6f0435..67502591f 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -59,9 +59,6 @@ #include "livarot/Shape.h" #include <2geom/circle.h> #include <2geom/transforms.h> -#include <2geom/path-intersection.h> -#include <2geom/pathvector.h> -#include <2geom/crossing.h> #include "preferences.h" #include "style.h" #include "box3d.h" @@ -460,7 +457,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, if(!fit_item(desktop, item, a, spray_origin, move, center, angle, _scale, scale, offset)){ limit += 1; //Limit recursion to 10 levels - //Seems enoght to chech if thete is place to put new copie + //Seems enough to chech if there is place to put new copie if(limit < 11){ return sp_spray_recursive(desktop, selection, diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index a46f2cc90..20c59bcf7 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -12,7 +12,7 @@ * BenoĆ®t LAVORATA * Vincent MONTAGNE * Pierre BARBRY-BLOT - * Jabiertxo Arraiza JABIERTXOF + * Jabiertxo ARRAIZA * * Copyright (C) 2009 authors * diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 6a062bc46..2279845de 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -287,7 +287,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj _("Not overlap"), INKSCAPE_ICON("distribute-randomize"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overlap", true) ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overlap", false) ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_not_overlap), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } -- cgit v1.2.3 From 7211d5adafb749b04d2de1ed3a2e679f4f9f869e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 26 Oct 2015 17:22:18 +0100 Subject: Add option to not overlap if multiple elements are selected to spray (bzr r14422.1.13) --- src/ui/tools/spray-tool.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 67502591f..a49887f89 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -361,7 +361,6 @@ static void sp_spray_transform_path(SPItem * item, Geom::Path &path, Geom::Affin static bool fit_item(SPDesktop *desktop, SPItem *item, Geom::OptRect bbox, - gchar const * spray_origin, Geom::Point move, Geom::Point center, double angle, @@ -387,14 +386,28 @@ static bool fit_item(SPDesktop *desktop, path *= desktop->doc2dt(); bbox = path.boundsFast(); std::vector items_down = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox); + Inkscape::Selection *selection = desktop->getSelection(); + if (selection->isEmpty()) { + return false; + } + std::vector const items_selected(selection->itemList()); for (std::vector::const_iterator i=items_down.begin(); i!=items_down.end(); i++) { SPItem *item_down = *i; gchar const * item_down_sharp = g_strdup_printf("#%s", item_down->getId()); - if(strcmp(item_down_sharp, spray_origin) == 0 || - (item_down->getAttribute("inkscape:spray-origin") && - strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 )) - { - return false; + for (std::vector::const_iterator j=items_selected.begin(); j!=items_selected.end(); j++) { + SPItem *item_selected = *j; + gchar const * spray_origin; + if(!item->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 )) + { + return false; + } } } return true; @@ -454,7 +467,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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()); if(overlap){ - if(!fit_item(desktop, item, a, spray_origin, move, center, angle, _scale, scale, offset)){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, offset)){ limit += 1; //Limit recursion to 10 levels //Seems enough to chech if there is place to put new copie @@ -583,7 +596,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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()); if(overlap){ - if(!fit_item(desktop, item, a, spray_origin, move, center, angle, _scale, scale, offset)){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, offset)){ limit += 1; if(limit < 11){ return sp_spray_recursive(desktop, -- cgit v1.2.3 From 0d4e511c524d9102d90adbf2defea4f644eb3edd Mon Sep 17 00:00:00 2001 From: Shlomi Fish Date: Mon, 26 Oct 2015 23:50:52 +0100 Subject: add gtk3 experimental support in CMake Fixed bugs: - https://launchpad.net/bugs/1509969 (bzr r14430) --- src/CMakeLists.txt | 5 ++- src/libgdl/CMakeLists.txt | 87 +++++++++++++++++++++++---------------------- src/ui/dialog/text-edit.cpp | 14 ++++++++ 3 files changed, 63 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ec7713464..30af55925 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -531,6 +531,10 @@ endif() add_dependencies(inkscape inkscape_version) +if (NOT "${WITH_EXT_GDL}") + list (APPEND INKSCAPE_LIBS "gdl_LIB") +endif() + set(INKSCAPE_TARGET_LIBS # order from automake #sp_LIB @@ -542,7 +546,6 @@ set(INKSCAPE_TARGET_LIBS croco_LIB avoid_LIB - gdl_LIB cola_LIB vpsc_LIB livarot_LIB diff --git a/src/libgdl/CMakeLists.txt b/src/libgdl/CMakeLists.txt index d59d017f0..a452320f7 100644 --- a/src/libgdl/CMakeLists.txt +++ b/src/libgdl/CMakeLists.txt @@ -1,47 +1,50 @@ +if (NOT "${WITH_EXT_GDL}") -set(libgdl_SRC - gdl-dock-bar.c - gdl-dock-item-button-image.c - gdl-dock-item-grip.c - gdl-dock-item.c - gdl-dock-master.c - gdl-dock-notebook.c - gdl-dock-object.c - gdl-dock-paned.c - gdl-dock-placeholder.c - gdl-dock-tablabel.c - gdl-dock.c - gdl-i18n.c - gdl-switcher.c - libgdlmarshal.c - libgdltypebuiltins.c + set(libgdl_SRC + gdl-dock-bar.c + gdl-dock-item-button-image.c + gdl-dock-item-grip.c + gdl-dock-item.c + gdl-dock-master.c + gdl-dock-notebook.c + gdl-dock-object.c + gdl-dock-paned.c + gdl-dock-placeholder.c + gdl-dock-tablabel.c + gdl-dock.c + gdl-i18n.c + gdl-switcher.c + libgdlmarshal.c + libgdltypebuiltins.c - # ------- - # Headers - gdl-dock-bar.h - gdl-dock-item-button-image.h - gdl-dock-item-grip.h - gdl-dock-item.h - gdl-dock-master.h - gdl-dock-notebook.h - gdl-dock-object.h - gdl-dock-paned.h - gdl-dock-placeholder.h - gdl-dock-tablabel.h - gdl-dock.h - gdl-i18n.h - gdl-switcher.h - gdl.h - libgdlmarshal.h - libgdltypebuiltins.h -) + # ------- + # Headers + gdl-dock-bar.h + gdl-dock-item-button-image.h + gdl-dock-item-grip.h + gdl-dock-item.h + gdl-dock-master.h + gdl-dock-notebook.h + gdl-dock-object.h + gdl-dock-paned.h + gdl-dock-placeholder.h + gdl-dock-tablabel.h + gdl-dock.h + gdl-i18n.h + gdl-switcher.h + gdl.h + libgdlmarshal.h + libgdltypebuiltins.h + ) -if(WIN32) - list(APPEND libgdl_SRC - gdl-win32.c - gdl-win32.h - ) -endif() + if(WIN32) + list(APPEND libgdl_SRC + gdl-win32.c + gdl-win32.h + ) + endif() + + add_inkscape_lib(gdl_LIB "${libgdl_SRC}") -add_inkscape_lib(gdl_LIB "${libgdl_SRC}") +endif() diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 7575cc854..cf53e1441 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; /* @@ -187,6 +200,7 @@ TextEdit::TextEdit() g_print("gtkspell error: %s\n", error->message); g_error_free(error); } +#endif #endif gtk_widget_set_size_request (text_view, -1, 64); -- cgit v1.2.3 From ce4d5cefcf234870d5f345f184256c9fab354777 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 27 Oct 2015 00:07:29 +0100 Subject: Added a option to pick down color (bzr r14422.1.14) --- src/ui/tools/spray-tool.cpp | 70 +++++++++++++++++++++++++++++++++++++++---- src/ui/tools/spray-tool.h | 1 + src/widgets/spray-toolbar.cpp | 20 +++++++++++++ src/widgets/toolbox.cpp | 1 + 4 files changed, 86 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index a49887f89..4f02d9b33 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -49,6 +49,13 @@ #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" @@ -154,6 +161,7 @@ SprayTool::SprayTool() , has_dilated(false) , dilate_area(NULL) , overlap(false) + , picker(false) , offset(0) { } @@ -228,6 +236,7 @@ void SprayTool::setup() { sp_event_context_read(this, "usepressure"); sp_event_context_read(this, "Scale"); sp_event_context_read(this, "offset"); + sp_event_context_read(this, "picker"); sp_event_context_read(this, "overlap"); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -268,6 +277,8 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) { this->ratio = CLAMP(val.getDouble(), 0.0, 0.9); } else if (path == "offset") { this->offset = CLAMP(val.getDouble(), -1000.0, 1000.0); + } else if (path == "picker") { + this->picker = val.getBool(); } else if (path == "overlap") { this->overlap = val.getBool(); } @@ -366,7 +377,9 @@ static bool fit_item(SPDesktop *desktop, double angle, double _scale, double scale, - double offset) + bool picker, + double offset, + SPCSSAttr *css) { if(offset < 0){ offset = std::min(std::min(std::abs(offset), bbox->width()/2.0),std::min(std::abs(offset), bbox->height()/2.0)) * -1; @@ -378,7 +391,6 @@ static bool fit_item(SPDesktop *desktop, path.appendNew(Geom::Point(bbox->right(), bbox->bottom())); path.appendNew(Geom::Point(bbox->left(), bbox->bottom())); path.close(true); - Geom::Translate const s(center); 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); @@ -410,6 +422,42 @@ static bool fit_item(SPDesktop *desktop, } } } + if(picker){ + Geom::IntRect area = Geom::IntRect::from_xywh(floor(desktop->d2w(bbox->midpoint())[Geom::X]), floor(desktop->d2w(bbox->midpoint())[Geom::Y]), 1, 1); + double R = 0, G = 0, B = 0, A = 0; + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); + sp_canvas_arena_render_surface(SP_CANVAS_ARENA(desktop->getDrawing()), s, area); + ink_cairo_surface_average_color_premul(s, R, G, B, A); + cairo_surface_destroy(s); + + // Inkscape::Drawing *pick_drawing = new Inkscape::Drawing(); + // pick_drawing->update(); + // Geom::Rect box( center_bbox[Geom::X]-1, center_bbox[Geom::Y]-1, + // center_bbox[Geom::X]+1, center_bbox[Geom::Y]+1 ); + + // /* Item integer bbox in points */ + // Geom::IntRect ibox = box.roundOutwards(); + + // /* Find visible area */ + // cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ibox.width(), ibox.height()); + // Inkscape::DrawingContext dc(s, ibox.min()); + + // /* Render copy and pick color */ + // pick_drawing->render(dc, ibox); + // double R = 0, G = 0, B = 0, A = 0; + // ink_cairo_surface_average_color(s, R, G, B, A); + // cairo_surface_destroy(s); + // status message + guint32 c32 = SP_RGBA32_F_COMPOSE(R, G, B, A); + gchar c[64]; + sp_svg_write_color(c, sizeof(c), c32); + sp_repr_css_set_property(css, "fill", c); + gchar const * fill_opacity = g_strdup_printf("%f", A); + sp_repr_css_set_property(css, "fill-opacity", fill_opacity); + if(R == 1 && G == 1 && B == 1 && A == 0){ + return false; + } + } return true; } @@ -431,6 +479,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, double rotation_variation, gint _distrib, bool overlap, + bool picker, double offset, size_t &limit) { @@ -466,8 +515,9 @@ static bool sp_spray_recursive(SPDesktop *desktop, } 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(overlap){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, offset)){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, offset, css)){ limit += 1; //Limit recursion to 10 levels //Seems enough to chech if there is place to put new copie @@ -490,6 +540,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, rotation_variation, _distrib, overlap, + picker, offset, limit); } else { @@ -515,6 +566,9 @@ static bool sp_spray_recursive(SPDesktop *desktop, // Move the cursor p 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; } } @@ -595,8 +649,9 @@ static bool sp_spray_recursive(SPDesktop *desktop, } 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(overlap){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, offset)){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, offset, css)){ limit += 1; if(limit < 11){ return sp_spray_recursive(desktop, @@ -617,6 +672,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, rotation_variation, _distrib, overlap, + picker, offset, limit); } else { @@ -648,7 +704,9 @@ static bool sp_spray_recursive(SPDesktop *desktop, sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale, scale)); sp_spray_rotate_rel(center, desktop, item_copied, Geom::Rotate(angle)); 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; } @@ -697,7 +755,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point SPItem *item = *i; g_assert(item != NULL); size_t limit = 0; - 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->overlap, tc->offset, limit)) { + 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->overlap,tc->picker, tc->offset, limit)) { did = true; } } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index 20c59bcf7..f65e0a223 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -88,6 +88,7 @@ public: Geom::Point last_push; SPCanvasItem *dilate_area; bool overlap; + bool picker; double offset; sigc::connection style_set_connection; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 2279845de..944355053 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -117,6 +117,13 @@ static void sp_toggle_not_overlap( GtkToggleAction* act, gpointer data ) prefs->setBool("/tools/spray/overlap", active); } +static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/picker", active); +} + void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); @@ -281,6 +288,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_object_set_data( holder, "spray_scale", eact ); } + /* Overlap */ { InkToggleAction* act = ink_toggle_action_new( "SprayNotOverlapAction", _("Not overlap"), @@ -291,6 +299,18 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_not_overlap), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } + + /* Picker */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction", + _("Pick down color"), + _("Pick down color"), + INKSCAPE_ICON("color-picker"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picker", false) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_picker), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } /* Offset */ { diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index f512819e9..57f804d99 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -320,6 +320,7 @@ static gchar const * ui_descr = " " " " " " + " " " " " " -- cgit v1.2.3 From bb1f811f9932106d5fd4aaba87f3194fc55de6be Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 27 Oct 2015 00:09:21 +0100 Subject: removed dead code (bzr r14422.1.16) --- src/ui/tools/spray-tool.cpp | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 4f02d9b33..bacb1105c 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -429,25 +429,6 @@ static bool fit_item(SPDesktop *desktop, sp_canvas_arena_render_surface(SP_CANVAS_ARENA(desktop->getDrawing()), s, area); ink_cairo_surface_average_color_premul(s, R, G, B, A); cairo_surface_destroy(s); - - // Inkscape::Drawing *pick_drawing = new Inkscape::Drawing(); - // pick_drawing->update(); - // Geom::Rect box( center_bbox[Geom::X]-1, center_bbox[Geom::Y]-1, - // center_bbox[Geom::X]+1, center_bbox[Geom::Y]+1 ); - - // /* Item integer bbox in points */ - // Geom::IntRect ibox = box.roundOutwards(); - - // /* Find visible area */ - // cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ibox.width(), ibox.height()); - // Inkscape::DrawingContext dc(s, ibox.min()); - - // /* Render copy and pick color */ - // pick_drawing->render(dc, ibox); - // double R = 0, G = 0, B = 0, A = 0; - // ink_cairo_surface_average_color(s, R, G, B, A); - // cairo_surface_destroy(s); - // status message guint32 c32 = SP_RGBA32_F_COMPOSE(R, G, B, A); gchar c[64]; sp_svg_write_color(c, sizeof(c), c32); -- cgit v1.2.3 From 8e0ef884486bac630f021bb1b33155e4826edb0d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 27 Oct 2015 00:51:58 +0100 Subject: Fixed some typos pointed by Mc (bzr r14422.1.17) --- src/widgets/spray-toolbar.cpp | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 944355053..57b582903 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -128,6 +128,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj { Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool overlap = prefs->getBool("/tools/spray/overlap", false); { /* Width */ @@ -291,8 +293,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Overlap */ { InkToggleAction* act = ink_toggle_action_new( "SprayNotOverlapAction", - _("Not overlap"), - _("Not overlap"), + _("Prevent overlapping objects"), + _("Prevent overlapping objects"), INKSCAPE_ICON("distribute-randomize"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overlap", false) ); @@ -303,30 +305,39 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Picker */ { InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction", - _("Pick down color"), - _("Pick down color"), + _("Pick down color. Fill must be unset on original when spraying clones"), + _("Pick down color. Fill must be unset on original when spraying clones"), INKSCAPE_ICON("color-picker"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picker", false) ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_picker), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + + //if ( offset ) { + // gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + //} else { + // gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + //} } /* Offset */ { EgeAdjustmentAction *eact = create_adjustment_action( "SprayToolOffsetAction", _("Offset"), _("Offset:"), - _("Base offset size"), + _("Increase to segregate objects more (value in px)"), "/tools/spray/offset", 0.0, GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, -1000.0, 1000.0, 1.0, 4.0, 0, 0, 0, sp_spray_offset_value_changed, NULL, 0 , 2); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - + //if ( offset ) { + // gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + //} else { + // gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + //} + } } -- cgit v1.2.3 From b0de24888aea4410596e237f947a201b349b0097 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 27 Oct 2015 20:10:06 +0100 Subject: Now the picker work with alphas and also in no overlap mode Offset dropdown disabled if no overlap Changed offset to percent based (bzr r14422.1.18) --- src/ui/tools/spray-tool.cpp | 78 +++++++++++++++++++++++++++++++++++-------- src/widgets/spray-toolbar.cpp | 70 ++++++++++++++++++++------------------ src/widgets/toolbox.cpp | 2 +- 3 files changed, 102 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index bacb1105c..25e9dbd73 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -378,13 +378,19 @@ static bool fit_item(SPDesktop *desktop, double _scale, double scale, bool picker, + bool overlap, double offset, SPCSSAttr *css) { - if(offset < 0){ - offset = std::min(std::min(std::abs(offset), bbox->width()/2.0),std::min(std::abs(offset), bbox->height()/2.0)) * -1; + SPDocument *doc = item->document; + double width = bbox->width(); + double height = bbox->height(); + double size = std::min(width,height); + double offset_min = (offset * size)/100.0 - (size); + if(offset_min < 0 ){ + offset_min = 0; } - bbox = Geom::Rect(Geom::Point(bbox->left() - offset, bbox->top() - offset),Geom::Point(bbox->right() + offset, bbox->bottom() + offset)); + bbox = Geom::Rect(Geom::Point(bbox->left() - offset_min, bbox->top() - offset_min),Geom::Point(bbox->right() + offset_min, bbox->bottom() + offset_min)); Geom::Path path; path.start(Geom::Point(bbox->left(), bbox->top())); path.appendNew(Geom::Point(bbox->right(), bbox->top())); @@ -397,6 +403,16 @@ static bool fit_item(SPDesktop *desktop, path *= Geom::Translate(move[Geom::X], move[Geom::Y]); path *= desktop->doc2dt(); bbox = path.boundsFast(); + double bbox_left_main = bbox->left(); + double bbox_top_main = bbox->top(); + double width_transformed = bbox->width(); + double height_transformed = bbox->height(); + size = std::min(width_transformed,height_transformed); + if(offset < 100 ){ + offset_min = ((99.0 - offset) * size)/100.0 - size; + } else { + offset_min = 0; + } std::vector items_down = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox); Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { @@ -405,6 +421,11 @@ static bool fit_item(SPDesktop *desktop, std::vector const items_selected(selection->itemList()); for (std::vector::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()); for (std::vector::const_iterator j=items_selected.begin(); j!=items_selected.end(); j++) { SPItem *item_selected = *j; @@ -415,27 +436,56 @@ static bool fit_item(SPDesktop *desktop, 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 )) + (item_down->getAttribute("inkscape:spray-origin") && + strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 )) { - return false; + if(overlap){ + if(!(offset_min < 0 && std::abs(bbox_left - bbox_left_main) > std::abs(offset_min) && + std::abs(bbox_top - bbox_top_main) > std::abs(offset_min))){ + return false; + } + } else if(picker){ + item_down->setHidden(true); + item_down->updateRepr(); + } } } } if(picker){ - Geom::IntRect area = Geom::IntRect::from_xywh(floor(desktop->d2w(bbox->midpoint())[Geom::X]), floor(desktop->d2w(bbox->midpoint())[Geom::Y]), 1, 1); + if(!overlap){ + doc->ensureUpToDate(); + } + Geom::Point mid_point = bbox->midpoint(); + Geom::IntRect area = Geom::IntRect::from_xywh(floor(desktop->d2w(mid_point)[Geom::X]), floor(desktop->d2w(mid_point)[Geom::Y]), 1, 1); double R = 0, G = 0, B = 0, A = 0; cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); sp_canvas_arena_render_surface(SP_CANVAS_ARENA(desktop->getDrawing()), s, area); ink_cairo_surface_average_color_premul(s, R, G, B, A); cairo_surface_destroy(s); + if (fabs(A) < 1e-4) { + A = 0; // suppress exponentials, CSS does not allow that + } + if (A > 0) { + R /= A; + G /= A; + B /= A; + } guint32 c32 = SP_RGBA32_F_COMPOSE(R, G, B, A); gchar c[64]; sp_svg_write_color(c, sizeof(c), c32); sp_repr_css_set_property(css, "fill", c); - gchar const * fill_opacity = g_strdup_printf("%f", A); - sp_repr_css_set_property(css, "fill-opacity", fill_opacity); - if(R == 1 && G == 1 && B == 1 && A == 0){ + std::stringstream fill_opacity; + fill_opacity.imbue(std::locale::classic()); + fill_opacity << float(A); + sp_repr_css_set_property(css, "fill-opacity", fill_opacity.str().c_str()); + if(!overlap){ + for (std::vector::const_iterator k=items_down.begin(); k!=items_down.end(); k++) { + SPItem *item_hidden = *k; + item_hidden->setHidden(false); + item_hidden->updateRepr(); + } + } + if(A == 0){ return false; } } @@ -497,8 +547,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(overlap){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, offset, css)){ + if(overlap || picker){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, overlap, offset, css)){ limit += 1; //Limit recursion to 10 levels //Seems enough to chech if there is place to put new copie @@ -631,8 +681,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(overlap){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, offset, css)){ + if(overlap || picker){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, overlap, offset, css)){ limit += 1; if(limit < 11){ return sp_spray_recursive(desktop, diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 57b582903..9f7a7cb1d 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -54,6 +54,17 @@ using Inkscape::UI::PrefPusher; //## Spray ## //######################## +static void sp_stb_sensitivize( GObject *tbl ) +{ + GtkAction* offset = GTK_ACTION( g_object_get_data(tbl, "offset") ); + GtkToggleAction *overlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "overlap") ); + if (gtk_toggle_action_get_active(overlap)) { + gtk_action_set_sensitive( offset, TRUE ); + } else { + gtk_action_set_sensitive( offset, FALSE ); + } +} + static void sp_spray_width_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -110,11 +121,14 @@ static void sp_spray_offset_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ gtk_adjustment_get_value(adj)); } -static void sp_toggle_not_overlap( GtkToggleAction* act, gpointer data ) +static void sp_toggle_not_overlap( GtkToggleAction* act, gpointer data) { + + GObject *tbl = G_OBJECT(data); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); prefs->setBool("/tools/spray/overlap", active); + sp_stb_sensitivize(tbl); } static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) @@ -128,9 +142,6 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj { Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool overlap = prefs->getBool("/tools/spray/overlap", false); - { /* Width */ gchar const* labels[] = {_("(narrow spray)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad spray)")}; @@ -290,18 +301,6 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_object_set_data( holder, "spray_scale", eact ); } - /* Overlap */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayNotOverlapAction", - _("Prevent overlapping objects"), - _("Prevent overlapping objects"), - INKSCAPE_ICON("distribute-randomize"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overlap", false) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_not_overlap), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - /* Picker */ { InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction", @@ -310,35 +309,40 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj INKSCAPE_ICON("color-picker"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picker", false) ); + g_object_set_data( holder, "picker", act ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_picker), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } - //if ( offset ) { - // gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - //} else { - // gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - //} + /* Overlap */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayNotOverlapAction", + _("Prevent overlapping objects"), + _("Prevent overlapping objects"), + INKSCAPE_ICON("distribute-randomize"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overlap", false) ); + g_object_set_data( holder, "overlap", act ); + //g_object_set_data (context_object, "holder", holder); + //g_object_set_data (context_object, "desktop", desktop); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_not_overlap), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } /* Offset */ { EgeAdjustmentAction *eact = create_adjustment_action( "SprayToolOffsetAction", - _("Offset"), _("Offset:"), - _("Increase to segregate objects more (value in px)"), - "/tools/spray/offset", 0.0, + _("Offset precent"), _("Offset percent:"), + _("Increase to segregate objects more (value in percent)"), + "/tools/spray/offset", 100, GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - -1000.0, 1000.0, 1.0, 4.0, + 0, 10000, 1, 4, 0, 0, 0, - sp_spray_offset_value_changed, NULL, 0 , 2); + sp_spray_offset_value_changed, NULL, 0 , 0); + g_object_set_data( holder, "offset", eact ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - - //if ( offset ) { - // gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - //} else { - // gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - //} } - + sp_stb_sensitivize(holder); } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 57f804d99..f4bc367d0 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -319,8 +319,8 @@ static gchar const * ui_descr = " " " " " " - " " " " + " " " " " " -- cgit v1.2.3 From 18dd2576ee9fa17b4d8d31f6d6e4150e4e92caac Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 27 Oct 2015 20:45:58 +0100 Subject: little tweak (bzr r14422.1.19) --- src/ui/tools/spray-tool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 25e9dbd73..269afbbbf 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -455,8 +455,8 @@ static bool fit_item(SPDesktop *desktop, if(!overlap){ doc->ensureUpToDate(); } - Geom::Point mid_point = bbox->midpoint(); - Geom::IntRect area = Geom::IntRect::from_xywh(floor(desktop->d2w(mid_point)[Geom::X]), floor(desktop->d2w(mid_point)[Geom::Y]), 1, 1); + Geom::Point mid_point = desktop->d2w(bbox->midpoint()); + Geom::IntRect area = Geom::IntRect::from_xywh(floor(mid_point[Geom::X]), floor(mid_point[Geom::Y]), 1, 1); double R = 0, G = 0, B = 0, A = 0; cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); sp_canvas_arena_render_surface(SP_CANVAS_ARENA(desktop->getDrawing()), s, area); -- cgit v1.2.3 From ce697d7ebfb1e4affce10805c89445244d29388a Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 28 Oct 2015 14:40:01 +0100 Subject: Implement 'text-orientation' with user interface. Update 'writing-mode', adding 'vertical-lr'. Overhaul vertical text. Eliminate any use of "internal" leading in glyph metrics. Etc. (bzr r14430.1.1) --- src/desktop-style.cpp | 62 +++++- src/desktop-style.h | 1 + src/display/nr-style.cpp | 2 - src/display/nr-style.h | 1 - src/libnrtype/FontInstance.cpp | 25 ++- src/libnrtype/Layout-TNG-Compute.cpp | 284 ++++++++++++++++----------- src/libnrtype/Layout-TNG-OutIter.cpp | 14 +- src/libnrtype/Layout-TNG-Output.cpp | 27 ++- src/libnrtype/Layout-TNG-Scanline-Maker.h | 14 +- src/libnrtype/Layout-TNG-Scanline-Makers.cpp | 32 ++- src/libnrtype/Layout-TNG.h | 51 ++++- src/style-enums.h | 8 +- src/style-internal.h | 1 - src/widgets/text-toolbar.cpp | 179 +++++++++++++++-- src/widgets/toolbox.cpp | 2 + 15 files changed, 507 insertions(+), 196 deletions(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 02c18339b..2260d851f 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -500,7 +500,7 @@ objects_query_fillstroke (const std::vector &objects, SPStyle *style_re SPIPaint *paint_res = isfill? &style_res->fill : &style_res->stroke; bool paintImpossible = true; - paint_res->set = TRUE; + paint_res->set = true; SVGICCColor* iccColor = 0; @@ -1144,7 +1144,7 @@ objects_query_fontstyle (const std::vector &objects, SPStyle *style_res different = true; // different styles } - set = TRUE; + set = true; style_res->font_weight.value = style_res->font_weight.computed = style->font_weight.computed; style_res->font_style.value = style_res->font_style.computed = style->font_style.computed; style_res->font_stretch.value = style_res->font_stretch.computed = style->font_stretch.computed; @@ -1256,6 +1256,56 @@ objects_query_fontvariants (const std::vector &objects, SPStyle *style_ } +/** + * Write to style_res the average writing modes style of objects. + */ +int +objects_query_writing_modes (const std::vector &objects, SPStyle *style_res) +{ + bool different = false; + bool set = false; + + int texts = 0; + + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + SPObject *obj = *i; + + if (!isTextualItem(obj)) { + continue; + } + + SPStyle *style = obj->style; + if (!style) { + continue; + } + + texts ++; + + if (set && + ( ( style_res->writing_mode.computed != style->writing_mode.computed ) || + ( style_res->text_orientation.computed != style->text_orientation.computed ) ) ) { + different = true; // different styles + } + + set = true; + style_res->writing_mode.computed = style->writing_mode.computed; + style_res->text_orientation.computed = style->text_orientation.computed; + } + + if (texts == 0 || !set) + return QUERY_STYLE_NOTHING; + + if (texts > 1) { + if (different) { + return QUERY_STYLE_MULTIPLE_DIFFERENT; + } else { + return QUERY_STYLE_MULTIPLE_SAME; + } + } else { + return QUERY_STYLE_SINGLE; + } +} + int objects_query_fontfeaturesettings (const std::vector &objects, SPStyle *style_res) { @@ -1293,7 +1343,7 @@ objects_query_fontfeaturesettings (const std::vector &objects, SPStyle style_res->font_feature_settings.value = NULL; } - style_res->font_feature_settings.set = TRUE; + style_res->font_feature_settings.set = true; style_res->font_feature_settings.value = g_strdup(style->font_feature_settings.value); } @@ -1449,7 +1499,7 @@ objects_query_fontfamily (const std::vector &objects, SPStyle *style_re style_res->font_family.value = NULL; } - style_res->font_family.set = TRUE; + style_res->font_family.set = true; style_res->font_family.value = g_strdup(style->font_family.value); } @@ -1508,7 +1558,7 @@ objects_query_fontspecification (const std::vector &objects, SPStyle *s style_res->font_specification.value = NULL; } - style_res->font_specification.set = TRUE; + style_res->font_specification.set = true; style_res->font_specification.value = g_strdup(style->font_specification.value); } } @@ -1728,6 +1778,8 @@ sp_desktop_query_style_from_list (const std::vector &list, SPStyle *sty return objects_query_fontfeaturesettings (list, style); } else if (property == QUERY_STYLE_PROPERTY_FONTNUMBERS) { return objects_query_fontnumbers (list, style); + } else if (property == QUERY_STYLE_PROPERTY_WRITINGMODES) { + return objects_query_writing_modes (list, style); } else if (property == QUERY_STYLE_PROPERTY_BASELINES) { return objects_query_baselines (list, style); diff --git a/src/desktop-style.h b/src/desktop-style.h index 95c434844..b9199b615 100644 --- a/src/desktop-style.h +++ b/src/desktop-style.h @@ -51,6 +51,7 @@ enum { // which property was queried (add when you need more) QUERY_STYLE_PROPERTY_FONTFEATURESETTINGS, // font feature settings (OpenType features) QUERY_STYLE_PROPERTY_FONTNUMBERS, // size, spacings QUERY_STYLE_PROPERTY_BASELINES, // baseline-shift + QUERY_STYLE_PROPERTY_WRITINGMODES, // writing-mode, text-orientation QUERY_STYLE_PROPERTY_MASTEROPACITY, // opacity QUERY_STYLE_PROPERTY_BLEND, // blend QUERY_STYLE_PROPERTY_BLUR // blur diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index 1740785e2..8b82a1dff 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -68,7 +68,6 @@ NRStyle::NRStyle() , tspan_width(0) , ascender(0) , descender(0) - , line_gap(0) , underline_thickness(0) , underline_position(0) , line_through_thickness(0) @@ -330,7 +329,6 @@ void NRStyle::set(SPStyle *style, SPStyle *context_style) tspan_width = style->text_decoration_data.tspan_width; ascender = style->text_decoration_data.ascender; descender = style->text_decoration_data.descender; - line_gap = style->text_decoration_data.line_gap; underline_thickness = style->text_decoration_data.underline_thickness; underline_position = style->text_decoration_data.underline_position; line_through_thickness = style->text_decoration_data.line_through_thickness; diff --git a/src/display/nr-style.h b/src/display/nr-style.h index 5f78795d3..6c652311a 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -115,7 +115,6 @@ struct NRStyle { float tspan_width; float ascender; float descender; - float line_gap; float underline_thickness; float underline_position; float line_through_thickness; diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index a5572c517..6b2e030d1 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -374,10 +374,10 @@ void font_instance::LoadGlyph(int glyph_id) GLYPHMETRICS metrics; DWORD bufferSize=GetGlyphOutline (parent->hScreenDC, glyph_id, GGO_GLYPH_INDEX | GGO_NATIVE | GGO_UNHINTED, &metrics, 0, NULL, &identity); double scale=1.0/parent->fontSize; - n_g.h_advance=metrics.gmCellIncX*scale; - n_g.v_advance=otm.otmTextMetrics.tmHeight*scale; - n_g.h_width=metrics.gmBlackBoxX*scale; - n_g.v_width=metrics.gmBlackBoxY*scale; + n_g.h_advance = metrics.gmCellIncX * scale; + n_g.v_advance = otm.otmTextMetrics.tmHeight * scale; + n_g.h_width = metrics.gmBlackBoxX * scale; + n_g.v_width = metrics.gmBlackBoxY * scale; if ( bufferSize == GDI_ERROR) { // shit happened } else if ( bufferSize == 0) { @@ -459,7 +459,13 @@ void font_instance::LoadGlyph(int glyph_id) n_g.v_advance=((double)theFace->glyph->metrics.vertAdvance)/((double)theFace->units_per_EM); n_g.v_width=((double)theFace->glyph->metrics.height)/((double)theFace->units_per_EM); } else { - n_g.v_width=n_g.v_advance=((double)theFace->height)/((double)theFace->units_per_EM); + // CSS3 Writing modes dictates that if vertical font metrics are missing we must + // synthisize them. No method is specified. The SVG 1.1 spec suggests using the em + // height (which is not theFace->height as that includes leading). The em height + // is ascender + descender (descender positive). Note: The "Requirements for + // Japanese Text Layout" W3C document says that Japanese kanji should be "set + // solid" which implies that vertical (and horizontal) advance should be 1em. + n_g.v_width=n_g.v_advance= 1.0; } if ( theFace->glyph->format == ft_glyph_format_outline ) { FT_Outline_Funcs ft2_outline_funcs = { @@ -529,6 +535,15 @@ bool font_instance::FontMetrics(double &ascent,double &descent,double &leading) leading=fabs(((double)theFace->height)/((double)theFace->units_per_EM)); leading-=ascent+descent; #endif + + // CSS dictates em size is ascent + descent + double em = ascent + descent; + if( em <= 0 ) { + return false; // Pathological + } + ascent /= em; + descent /= em; + leading /= em; return true; } diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index c4b0a5bee..4201d052c 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -23,33 +23,6 @@ namespace Text { #define TRACE(_args) IFTRACE(g_print _args) -// ******* enum conversion tables - -// These enums are probably from the SVG 1.0 era where one could interpret 'writing-mode' as setting direction. -// SVG 1.1 makes it clear that 'direction' should be used. 'direction' has only two values 'ltr' and 'rtl'. -// The first two values for the 'writing-mode' enum just happen to match the first two value of 'direction' so the -// existing code worked when 'writing-mode' was changed to 'direction'. -// static Layout::EnumConversionItem const enum_convert_spstyle_direction_to_pango_direction[] = { -// {SP_CSS_WRITING_MODE_LR_TB, PANGO_DIRECTION_LTR}, -// {SP_CSS_WRITING_MODE_RL_TB, PANGO_DIRECTION_RTL}, -// {SP_CSS_WRITING_MODE_TB_LR, PANGO_DIRECTION_LTR}}; // this is correct - -// static Layout::EnumConversionItem const enum_convert_spstyle_direction_to_my_direction[] = { -// {SP_CSS_WRITING_MODE_LR_TB, Layout::LEFT_TO_RIGHT}, -// {SP_CSS_WRITING_MODE_RL_TB, Layout::RIGHT_TO_LEFT}, -// {SP_CSS_WRITING_MODE_TB_LR, Layout::LEFT_TO_RIGHT}}; // this is correct - -// Proper 'direction' enums -static Layout::EnumConversionItem const enum_convert_spstyle_direction_to_pango_direction[] = { - {SP_CSS_DIRECTION_LTR, PANGO_DIRECTION_LTR}, - {SP_CSS_DIRECTION_RTL, PANGO_DIRECTION_RTL}}; - -static Layout::EnumConversionItem const enum_convert_spstyle_direction_to_my_direction[] = { - {SP_CSS_DIRECTION_LTR, Layout::LEFT_TO_RIGHT}, - {SP_CSS_DIRECTION_RTL, Layout::RIGHT_TO_LEFT}}; - - - /** \brief private to Layout. Does the real work of text flowing. This class does a standard greedy paragraph wrapping algorithm. @@ -140,9 +113,10 @@ class Layout::Calculator unsigned input_index; /// index into Layout::_input_stream Glib::ustring::const_iterator input_stream_first_character; double font_size; - LineHeight line_height; /// This is not the CSS line-height attribute! + FontMetrics line_height; /// This is not the CSS line-height attribute! double line_height_multiplier; /// calculated from the font-height css property double baseline_shift; /// calculated from the baseline-shift css property + SPCSSTextOrientation text_orientation; unsigned text_bytes; unsigned char_index_in_para; /// the index of the first character in this span in the paragraph, for looking up char_attributes SVGLength x, y, dx, dy, rotate; // these are reoriented copies of the attributes. We change span when we encounter one. @@ -221,7 +195,7 @@ class Layout::Calculator void _buildPangoItemizationForPara(ParagraphInfo *para) const; static void _computeFontLineHeight(font_instance *font, double font_size, - SPStyle const *style, LineHeight *line_height, + SPStyle const *style, FontMetrics *line_height, double *line_height_multiplier); unsigned _buildSpansForPara(ParagraphInfo *para) const; @@ -270,7 +244,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ bool _goToNextWrapShape(); bool _findChunksForLine(ParagraphInfo const ¶, UnbrokenSpanPosition *start_span_pos, - std::vector *chunk_info, LineHeight *line_height); + std::vector *chunk_info, FontMetrics *line_height); static inline PangoLogAttr const &_charAttributes(ParagraphInfo const ¶, UnbrokenSpanPosition const &span_pos) @@ -282,7 +256,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ UnbrokenSpanPosition const &start_span_pos, ScanlineMaker::ScanRun const &scan_run, std::vector *chunk_info, - LineHeight *line_height) const; + FontMetrics *line_height) const; /** computes the width of a single UnbrokenSpan (pointed to by span->start.iter_span) and outputs its vital statistics into the other fields of \a span. @@ -300,8 +274,11 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ span->setZero(); if (span->start.iter_span->dx._set && span->start.char_byte == 0){ - if(para.direction == RIGHT_TO_LEFT){ span->width -= span->start.iter_span->dx.computed; } - else { span->width += span->start.iter_span->dx.computed; } + if(para.direction == RIGHT_TO_LEFT){ + span->width -= span->start.iter_span->dx.computed; + } else { + span->width += span->start.iter_span->dx.computed; + } } if (span->start.iter_span->pango_item_index == -1) { @@ -382,10 +359,22 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ double char_width = 0.0; while (span->end_glyph_index < (unsigned)span->end.iter_span->glyph_string->num_glyphs && span->end.iter_span->glyph_string->log_clusters[span->end_glyph_index] <= (int)span->end.char_byte) { - if (_block_progression == LEFT_TO_RIGHT || _block_progression == RIGHT_TO_LEFT) - char_width += span->start.iter_span->font_size * para.pango_items[span->end.iter_span->pango_item_index].font->Advance(span->end.iter_span->glyph_string->glyphs[span->end_glyph_index].glyph, true); - else + if (_block_progression == LEFT_TO_RIGHT || _block_progression == RIGHT_TO_LEFT) { + // Vertical text + + if( text_source->style->text_orientation.computed == SP_CSS_TEXT_ORIENTATION_SIDEWAYS || + (text_source->style->text_orientation.computed == SP_CSS_TEXT_ORIENTATION_MIXED && + para.pango_items[span->end.iter_span->pango_item_index].item->analysis.gravity == 0) ) { + // Sideways orientation + char_width += span->start.iter_span->font_size * para.pango_items[span->end.iter_span->pango_item_index].font->Advance(span->end.iter_span->glyph_string->glyphs[span->end_glyph_index].glyph, false); + } else { + // Upright orientation + char_width += span->start.iter_span->font_size * para.pango_items[span->end.iter_span->pango_item_index].font->Advance(span->end.iter_span->glyph_string->glyphs[span->end_glyph_index].glyph, true); + } + } else { + // Horizontal text char_width += font_size_multiplier * span->end.iter_span->glyph_string->glyphs[span->end_glyph_index].geometry.width; + } span->end_glyph_index++; } if (char_attributes.is_cursor_position) @@ -474,7 +463,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ are ready to output the final result to #_flow. This method takes its input parameters and does that. */ - void _outputLine(ParagraphInfo const ¶, LineHeight const &line_height, std::vector const &chunk_info) + void _outputLine(ParagraphInfo const ¶, FontMetrics const &line_height, std::vector const &chunk_info) { TRACE(("Start _outputLine\n")); if (chunk_info.empty()) { @@ -486,7 +475,17 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ TRACE(("found line fit; creating output\n")); Layout::Line new_line; new_line.in_paragraph = _flow._paragraphs.size() - 1; - new_line.baseline_y = _scanline_maker->yCoordinate() + line_height.ascent; + new_line.baseline_y = _scanline_maker->yCoordinate(); + if( !_flow._input_wrap_shapes.empty() ) { + // Flowed text + if( _block_progression == RIGHT_TO_LEFT || _block_progression == LEFT_TO_RIGHT ) { + // Vertical text, use em box center as baseline + new_line.baseline_y += 0.5 * line_height.emSize(); + } else { + new_line.baseline_y += line_height.getAscent(); + } + } + new_line.in_shape = _current_shape_index; _flow._lines.push_back(new_line); @@ -527,17 +526,16 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ // If "y" attribute is set, use it (initial "y" attributes in // other than the first have already been stripped for // marked with role="line", see sp-text.cpp: SPText::_buildLayoutInput). + // NOTE: for vertical text, "y" is the user-space "x" value. if( it_chunk->broken_spans.front().start.iter_span->y._set ) { // Use set "y" attribute new_line.baseline_y = it_chunk->broken_spans.front().start.iter_span->y.computed; - // Save baseline _flow._lines.back().baseline_y = new_line.baseline_y; - // Save new y coordinate - _scanline_maker->setNewYCoordinate(new_line.baseline_y - line_height.ascent); - + // Set the initial y coordinate of the next line. + _scanline_maker->setNewYCoordinate(new_line.baseline_y); } // Reset relative y_offset ("dy" attribute is relative but should be reset at @@ -556,21 +554,21 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ } _flow._chunks.push_back(new_chunk); - double x; + double current_x; double direction_sign; Direction previous_direction = para.direction; double counter_directional_width_remaining = 0.0; float glyph_rotate = 0.0; if (para.direction == LEFT_TO_RIGHT) { direction_sign = +1.0; - x = 0.0; + current_x = 0.0; } else { direction_sign = -1.0; if (para.alignment == FULL && !_flow._input_wrap_shapes.empty()){ - x = it_chunk->scanrun_width; + current_x = it_chunk->scanrun_width; } else { - x = it_chunk->text_width; + current_x = it_chunk->text_width; } } @@ -583,7 +581,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ if (it_span->start.char_byte == 0) { // Start of an unbroken span, we might have dx, dy or rotate still to process // (x and y are done per chunk) - if (unbroken_span.dx._set) x += unbroken_span.dx.computed; + if (unbroken_span.dx._set) current_x += unbroken_span.dx.computed; if (unbroken_span.dy._set) _y_offset += unbroken_span.dy.computed; if (unbroken_span.rotate._set) glyph_rotate = unbroken_span.rotate.computed * (M_PI/180); } @@ -601,6 +599,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ new_span.in_input_stream_item = unbroken_span.input_index; new_span.baseline_shift = 0.0; new_span.block_progression = _block_progression; + new_span.text_orientation = unbroken_span.text_orientation; if ((_flow._input_stream[unbroken_span.input_index]->Type() == TEXT_SOURCE) && (new_span.font = para.pango_items[unbroken_span.pango_item_index].font)) { new_span.font->Ref(); @@ -609,12 +608,12 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ new_span.input_stream_first_character = Glib::ustring::const_iterator(unbroken_span.input_stream_first_character.base() + it_span->start.char_byte); } else { // a control code new_span.font = NULL; - new_span.font_size = new_span.line_height.ascent + new_span.line_height.descent; + new_span.font_size = new_span.line_height.emSize(); new_span.direction = para.direction; } if (new_span.direction == para.direction) { - x -= counter_directional_width_remaining; + current_x -= counter_directional_width_remaining; counter_directional_width_remaining = 0.0; } else if (new_span.direction != previous_direction) { // measure width of spans we need to switch round @@ -630,10 +629,10 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ } counter_directional_width_remaining += direction_sign * (it_following_span->width + it_following_span->whitespace_count * add_to_each_whitespace); } - x += counter_directional_width_remaining; + current_x += counter_directional_width_remaining; counter_directional_width_remaining = 0.0; // we want to go increasingly negative } - new_span.x_start = x; + new_span.x_start = current_x; if (_flow._input_stream[unbroken_span.input_index]->Type() == TEXT_SOURCE) { // the span is set up, push the glyphs and chars @@ -673,10 +672,12 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ } // create the Layout::Glyph + PangoGlyphInfo *unbroken_span_glyph_info = &unbroken_span.glyph_string->glyphs[glyph_index]; Layout::Glyph new_glyph; - new_glyph.glyph = unbroken_span.glyph_string->glyphs[glyph_index].glyph; + new_glyph.glyph = unbroken_span_glyph_info->glyph; new_glyph.in_character = _flow._characters.size(); new_glyph.rotation = glyph_rotate; + new_glyph.orientation = ORIENTATION_UPRIGHT; // Only effects vertical text // We may have scaled font size to fit textLength; now, if // @lengthAdjust=spacingAndGlyphs, this scaling must be only horizontal, @@ -686,28 +687,52 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ else new_glyph.vertical_scale = 1.0; - /* put something like this back in when we do glyph-rotation-horizontal/vertical - if (new_span.block_progression == LEFT_TO_RIGHT || new_span.block_progression == RIGHT_TO_LEFT) { - new_glyph.x += new_span.line_height.ascent; - new_glyph.y -= unbroken_span.glyph_string->glyphs[glyph_index].geometry.width * font_size_multiplier * 0.5; - new_glyph.width = new_span.line_height.ascent + new_span.line_height.descent; - } else */ - if (_block_progression == LEFT_TO_RIGHT || _block_progression == RIGHT_TO_LEFT) { - new_glyph.x = x + unbroken_span.glyph_string->glyphs[glyph_index].geometry.x_offset * font_size_multiplier + new_span.line_height.ascent; - new_glyph.y = _y_offset - - unbroken_span.baseline_shift + - (unbroken_span.glyph_string->glyphs[glyph_index].geometry.y_offset - - unbroken_span.glyph_string->glyphs[glyph_index].geometry.width * 0.5) * font_size_multiplier; - new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span.glyph_string->glyphs[glyph_index].glyph, true); + // Vertical text + + // TODO: Should also check 'glyph_orientation_vertical' if 'text-orientation' is unset... + if( new_span.text_orientation == SP_CSS_TEXT_ORIENTATION_SIDEWAYS || + (new_span.text_orientation == SP_CSS_TEXT_ORIENTATION_MIXED && + para.pango_items[unbroken_span.pango_item_index].item->analysis.gravity == 0) ) { + + // Sideways orientation (Latin characters, CJK punctuation), 90deg rotation done at output stage. + new_glyph.orientation = ORIENTATION_SIDEWAYS; + + new_glyph.x = current_x + unbroken_span_glyph_info->geometry.x_offset * font_size_multiplier; + + new_glyph.y =_y_offset + + unbroken_span.baseline_shift + + (unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier) + + 0.5 * (new_span.line_height.descent - new_span.line_height.ascent); + + new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, false); + + } else { + + // Upright orientation + new_glyph.x = current_x + unbroken_span_glyph_info->geometry.x_offset * font_size_multiplier + + new_span.line_height.ascent; + + new_glyph.y = _y_offset + // Does baseline shift have any meaning here? + unbroken_span.baseline_shift + + (unbroken_span_glyph_info->geometry.y_offset - + unbroken_span_glyph_info->geometry.width * 0.5) * font_size_multiplier; + + new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, true); + if( new_glyph.width == 0 ) { + new_glyph.width = unbroken_span_glyph_info->geometry.width * font_size_multiplier; + } + + } } else { - new_glyph.x = x + unbroken_span.glyph_string->glyphs[glyph_index].geometry.x_offset * font_size_multiplier; + // Horizontal text + new_glyph.x = current_x + unbroken_span_glyph_info->geometry.x_offset * font_size_multiplier; new_glyph.y = _y_offset - unbroken_span.baseline_shift + - unbroken_span.glyph_string->glyphs[glyph_index].geometry.y_offset * font_size_multiplier; - new_glyph.width = unbroken_span.glyph_string->glyphs[glyph_index].geometry.width * font_size_multiplier; + unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier; + new_glyph.width = unbroken_span_glyph_info->geometry.width * font_size_multiplier; if ((new_glyph.width == 0) && (para.pango_items[unbroken_span.pango_item_index].font)) - new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span.glyph_string->glyphs[glyph_index].glyph, false); + new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, false); // for some reason pango returns zero width for invalid glyph characters (those empty boxes), so go to freetype for the info } if (new_span.direction == RIGHT_TO_LEFT) { @@ -718,8 +743,10 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ if (unbroken_span.glyph_string->glyphs[rtl_index].attr.is_cluster_start && rtl_index != glyph_index) break; if (_block_progression == LEFT_TO_RIGHT || _block_progression == RIGHT_TO_LEFT) + // Vertical text cluster_width += new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span.glyph_string->glyphs[rtl_index].glyph, true); else + // Horizontal text cluster_width += font_size_multiplier * unbroken_span.glyph_string->glyphs[rtl_index].geometry.width; } new_glyph.x -= cluster_width; @@ -781,15 +808,15 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ advance_width *= direction_sign; if (new_span.direction != para.direction) { counter_directional_width_remaining -= advance_width; - x -= advance_width; + current_x -= advance_width; x_in_span_last -= advance_width; } else { - x += advance_width; + current_x += advance_width; x_in_span_last += advance_width; } } } else if (_flow._input_stream[unbroken_span.input_index]->Type() == CONTROL_CODE) { - x += static_cast(_flow._input_stream[unbroken_span.input_index])->width; + current_x += static_cast(_flow._input_stream[unbroken_span.input_index])->width; } new_span.x_end = new_span.x_start + x_in_span_last; @@ -978,6 +1005,7 @@ void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) con #if PANGO_VERSION_CHECK(1,37,1) TRACE((" ... compiled for font features\n")); #endif + Glib::ustring para_text; PangoAttrList *attributes_list; unsigned input_index; @@ -999,10 +1027,10 @@ void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) con } else if (_flow._input_stream[input_index]->Type() == TEXT_SOURCE) { Layout::InputStreamTextSource *text_source = static_cast(_flow._input_stream[input_index]); - // create the font_instance - font_instance *font = text_source->styleGetFontInstance(); - if (font == NULL) - continue; // bad news: we'll have to ignore all this text because we know of no font to render it + // create the font_instance + font_instance *font = text_source->styleGetFontInstance(); + if (font == NULL) + continue; // bad news: we'll have to ignore all this text because we know of no font to render it PangoAttribute *attribute_font_description = pango_attr_font_desc_new(font->descr); attribute_font_description->start_index = para_text.bytes(); @@ -1028,25 +1056,23 @@ void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) con TRACE(("whole para: \"%s\"\n", para_text.data())); TRACE(("%d input sources used\n", input_index - para->first_input_index)); - // do the pango_itemize() GList *pango_items_glist = NULL; + para->direction = LEFT_TO_RIGHT; // CSS default if (_flow._input_stream[para->first_input_index]->Type() == TEXT_SOURCE) { Layout::InputStreamTextSource const *text_source = static_cast(_flow._input_stream[para->first_input_index]); if (text_source->style->direction.set) { - PangoDirection pango_direction = (PangoDirection)_enum_converter(text_source->style->direction.computed, enum_convert_spstyle_direction_to_pango_direction, sizeof(enum_convert_spstyle_direction_to_pango_direction)/sizeof(enum_convert_spstyle_direction_to_pango_direction[0])); + para->direction = (text_source->style->direction.computed == SP_CSS_DIRECTION_LTR) ? LEFT_TO_RIGHT : RIGHT_TO_LEFT; + PangoDirection pango_direction = (text_source->style->direction.computed == SP_CSS_DIRECTION_LTR) ? PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL; pango_items_glist = pango_itemize_with_base_dir(_pango_context, pango_direction, para_text.data(), 0, para_text.bytes(), attributes_list, NULL); - para->direction = (Layout::Direction)_enum_converter(text_source->style->direction.computed, enum_convert_spstyle_direction_to_my_direction, sizeof(enum_convert_spstyle_direction_to_my_direction)/sizeof(enum_convert_spstyle_direction_to_my_direction[0])); } } - if (pango_items_glist == NULL) { // no direction specified, guess it - pango_items_glist = pango_itemize(_pango_context, para_text.data(), 0, para_text.bytes(), attributes_list, NULL); - // I think according to the css spec this is wrong and we're never allowed to guess the directionality - // of a paragraph. Need to talk to an rtl speaker. - if (pango_items_glist == NULL || pango_items_glist->data == NULL) para->direction = LEFT_TO_RIGHT; - else para->direction = (((PangoItem*)pango_items_glist->data)->analysis.level & 1) ? RIGHT_TO_LEFT : LEFT_TO_RIGHT; + if( pango_items_glist == NULL ) { + // Type wasn't TEXT_SOURCE or direction was not set. + pango_items_glist = pango_itemize(_pango_context, para_text.data(), 0, para_text.bytes(), attributes_list, NULL); } + pango_attr_list_unref(attributes_list); // convert the GList to our vector<> and make the font_instance for each PangoItem at the same time @@ -1070,43 +1096,45 @@ void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) con } /** - * Gets the ascent, descent and leading for a font and the alteration that has to be performed - * according to the value specified by the line-height css property. The result of multiplying - * \a line_height by \a line_height_multiplier is the inline box height as specified in css2 - * section 10.8. + * Gets the ascent and descent for a font given the 'font-size' propert and finds the value of + * line_height_multiplier given the 'line-height' property. The result of multiplying + * \a l by \a line_height_multiplier is the inline box height as specified in css2 + * section 10.8. http://www.w3.org/TR/CSS2/visudet.html#line-height */ +// THIS FUNCTION SHOULD NOT BE NECESSARY void Layout::Calculator::_computeFontLineHeight(font_instance *font, double font_size, - SPStyle const *style, LineHeight *line_height, + SPStyle const *style, FontMetrics *font_metrics, double *line_height_multiplier) { if (font == NULL) { - line_height->setZero(); + font_metrics->setZero(); *line_height_multiplier = 1.0; } else { - font->FontMetrics(line_height->ascent, line_height->descent, line_height->leading); + font->FontMetrics(font_metrics->ascent, font_metrics->descent, font_metrics->leading); } - *line_height *= font_size; + *font_metrics *= font_size; // yet another borked SPStyle member that we're going to have to fix ourselves + // To do: check if it really is still borked. for ( ; ; ) { if (style->line_height.set && !style->line_height.inherit) { if (style->line_height.normal) break; switch (style->line_height.unit) { case SP_CSS_UNIT_NONE: - *line_height_multiplier = style->line_height.computed * font_size / line_height->total(); + *line_height_multiplier = style->line_height.computed; return; case SP_CSS_UNIT_EX: - *line_height_multiplier = style->line_height.value * 0.5 * font_size / line_height->total(); + *line_height_multiplier = style->line_height.value * 0.5; // 0.5 is an approximation of the x-height. Fixme. return; case SP_CSS_UNIT_EM: case SP_CSS_UNIT_PERCENT: - *line_height_multiplier = style->line_height.value * font_size / line_height->total(); + *line_height_multiplier = style->line_height.value; return; default: // absolute values - *line_height_multiplier = style->line_height.computed / line_height->total(); + *line_height_multiplier = style->line_height.computed / font_metrics->emSize(); return; } break; @@ -1115,7 +1143,7 @@ void Layout::Calculator::_computeFontLineHeight(font_instance *font, double font style = style->object->parent->style; if (style == NULL) break; } - *line_height_multiplier = LINE_HEIGHT_NORMAL * font_size / line_height->total(); + *line_height_multiplier = LINE_HEIGHT_NORMAL; } bool compareGlyphWidth(const PangoGlyphInfo &a, const PangoGlyphInfo &b) @@ -1155,7 +1183,6 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const new_span.input_index = input_index; new_span.line_height.ascent = control_code->ascent * _flow.getTextLengthMultiplierDue(); new_span.line_height.descent = control_code->descent * _flow.getTextLengthMultiplierDue(); - new_span.line_height.leading = 0.0; new_span.text_bytes = 0; new_span.char_index_in_para = char_index_in_para; para->unbroken_spans.push_back(new_span); @@ -1194,11 +1221,13 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const new_span.dy._set = false; new_span.rotate._set = false; if (_block_progression == TOP_TO_BOTTOM || _block_progression == BOTTOM_TO_TOP) { + // Horizontal text if (text_source->x.size() > char_index_in_source) new_span.x = text_source->x[char_index_in_source]; if (text_source->y.size() > char_index_in_source) new_span.y = text_source->y[char_index_in_source]; if (text_source->dx.size() > char_index_in_source) new_span.dx = text_source->dx[char_index_in_source].computed * _flow.getTextLengthMultiplierDue(); if (text_source->dy.size() > char_index_in_source) new_span.dy = text_source->dy[char_index_in_source].computed * _flow.getTextLengthMultiplierDue(); } else { + // Vertical text if (text_source->x.size() > char_index_in_source) new_span.y = text_source->x[char_index_in_source]; if (text_source->y.size() > char_index_in_source) new_span.x = text_source->y[char_index_in_source]; if (text_source->dx.size() > char_index_in_source) new_span.dy = text_source->dx[char_index_in_source].computed * _flow.getTextLengthMultiplierDue(); @@ -1240,6 +1269,7 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const g_assert( span_start_byte_in_source + new_span.text_bytes <= text_source->text->bytes() ); g_assert( memchr(text_source->text->data() + span_start_byte_in_source, '\0', static_cast(new_span.text_bytes)) == NULL ); + /* Notes as of 4/29/13. Pango_shape is not generating English language ligatures, but it is generating them for Hebrew (and probably other similar languages). In the case observed 3 unicode characters (a base and 2 Mark, nonspacings) are merged into two glyphs (the base + first Mn, the 2nd Mn). All of these map @@ -1247,6 +1277,8 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const characters and glyphs. A big chunk of the conditional code which immediately follows this call is there to clean up the resulting mess. */ + + // Convert characters to glyphs pango_shape(text_source->text->data() + span_start_byte_in_source, new_span.text_bytes, ¶->pango_items[pango_item_index].item->analysis, @@ -1329,6 +1361,7 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const // At some point we may want to calculate baseline_shift here (to take advantage // of otm features like superscript baseline), but for now we use style baseline_shift. new_span.baseline_shift = text_source->style->baseline_shift.computed; + new_span.text_orientation = (SPCSSTextOrientation)text_source->style->text_orientation.computed; // TODO: metrics for vertical text TRACE(("add text span %lu \"%s\"\n", para->unbroken_spans.size(), text_source->text->raw().substr(span_start_byte_in_source, new_span.text_bytes).c_str())); @@ -1399,7 +1432,7 @@ bool Layout::Calculator::_goToNextWrapShape() bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, UnbrokenSpanPosition *start_span_pos, std::vector *chunk_info, - LineHeight *line_height) + FontMetrics *line_height) { // init the initial line_height if (start_span_pos->iter_span == para.unbroken_spans.end()) { @@ -1422,7 +1455,6 @@ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, // if we're not wrapping set the line_height big and negative so we can use negative line height line_height->ascent = -1.0e10; line_height->descent = -1.0e10; - line_height->leading = -1.0e10; } else line_height->setZero(); @@ -1474,7 +1506,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, UnbrokenSpanPosition const &start_span_pos, ScanlineMaker::ScanRun const &scan_run, std::vector *chunk_info, - LineHeight *line_height) const + FontMetrics *line_height) const { ChunkInfo new_chunk; new_chunk.text_width = 0.0; @@ -1511,16 +1543,17 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, } // see if this span is too tall to fit on the current line - LineHeight total_height = new_span.start.iter_span->line_height; - total_height *= new_span.start.iter_span->line_height_multiplier; + FontMetrics new_span_height = new_span.start.iter_span->line_height; + new_span_height.computeEffective( new_span.start.iter_span->line_height_multiplier ); /* floating point 80-bit/64-bit rounding problems require epsilon. See discussion http://inkscape.gristle.org/2005-03-16.txt around 22:00 */ - if ( total_height.ascent > line_height->ascent + FLT_EPSILON - || total_height.descent > line_height->descent + FLT_EPSILON - || total_height.leading > line_height->leading + FLT_EPSILON) { - line_height->max(total_height); - if (!_scanline_maker->canExtendCurrentScanline(*line_height)) + if ( new_span_height.ascent > line_height->ascent + FLT_EPSILON || + new_span_height.descent > line_height->descent + FLT_EPSILON) { + // Take larger of each of the two ascents and two descents per CSS + line_height->max(new_span_height); + if (!_scanline_maker->canExtendCurrentScanline(*line_height)) { return false; + } } bool span_fitted = _measureUnbrokenSpan(para, &new_span, &last_span_at_break, &last_span_at_emergency_break, new_chunk.scanrun_width - new_chunk.text_width); @@ -1540,7 +1573,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, TRACE(("chunk complete, used %f width (%d whitespaces, %lu brokenspans)\n", new_chunk.text_width, new_chunk.whitespace_count, new_chunk.broken_spans.size())); chunk_info->push_back(new_chunk); - if (scan_run.width() >= 4.0 * line_height->total() && last_span_at_break.end == start_span_pos) { + if (scan_run.width() >= 4.0 * line_height->emSize() && last_span_at_break.end == start_span_pos) { /* **non-SVG spec bit**: See bug #1191102 If the user types a very long line with no spaces, the way the spec is written at the moment means that when the length of the text @@ -1619,14 +1652,27 @@ bool Layout::Calculator::calculate() _flow._clearOutputObjects(); _pango_context = (font_factory::Default())->fontContext; + _font_factory_size_multiplier = (font_factory::Default())->fontSize; + // Reset gravity hint in case it was changed via previous use of 'text-orientation' + // (scripts take their natural gravity given base gravity). + pango_context_set_gravity_hint(_pango_context, PANGO_GRAVITY_HINT_NATURAL); + _block_progression = _flow._blockProgression(); + if( _block_progression == RIGHT_TO_LEFT || _block_progression == LEFT_TO_RIGHT ) { + // Vertical text, CJK + pango_context_set_base_gravity(_pango_context, PANGO_GRAVITY_EAST); + } else { + // Horizontal text + pango_context_set_base_gravity(_pango_context, PANGO_GRAVITY_AUTO); + } + _y_offset = 0.0; _createFirstScanlineMaker(); ParagraphInfo para; - LineHeight line_height; // needs to be maintained across paragraphs to be able to deal with blank paras + FontMetrics line_height; // needs to be maintained across paragraphs to be able to deal with blank paras for(para.first_input_index = 0 ; para.first_input_index < _flow._input_stream.size() ; ) { // jump to the next wrap shape if this is a SHAPE_BREAK control code if (_flow._input_stream[para.first_input_index]->Type() == CONTROL_CODE) { @@ -1640,7 +1686,10 @@ bool Layout::Calculator::calculate() if (_scanline_maker == NULL) break; // we're trying to flow past the last wrap shape - _buildPangoItemizationForPara(¶); + // Break things up into little pango units with unique direction, gravity, etc. + _buildPangoItemizationForPara(¶); + + // Do shaping (convert characters to glyphs) unsigned para_end_input_index = _buildSpansForPara(¶); if (_flow._input_stream[para.first_input_index]->Type() == TEXT_SOURCE) @@ -1679,7 +1728,7 @@ bool Layout::Calculator::calculate() Layout::Span new_span; if (_flow._spans.empty()) { new_span.font = NULL; - new_span.font_size = line_height.ascent + line_height.descent; + new_span.font_size = line_height.emSize(); new_span.line_height = line_height; new_span.x_end = 0.0; } else { @@ -1757,7 +1806,7 @@ void Layout::_calculateCursorShapeForEmpty() font_instance *font = text_source->styleGetFontInstance(); double font_size = text_source->styleComputeFontSize(); double caret_slope_run = 0.0, caret_slope_rise = 1.0; - LineHeight line_height; + FontMetrics line_height; if (font) { const_cast(font)->FontSlope(caret_slope_run, caret_slope_rise); font->FontMetrics(line_height.ascent, line_height.descent, line_height.leading); @@ -1780,10 +1829,13 @@ void Layout::_calculateCursorShapeForEmpty() ShapeScanlineMaker scanline_maker(_input_wrap_shapes.front().shape, block_progression); std::vector scan_runs = scanline_maker.makeScanline(line_height); if (!scan_runs.empty()) { - if (block_progression == LEFT_TO_RIGHT || block_progression == RIGHT_TO_LEFT) + if (block_progression == LEFT_TO_RIGHT || block_progression == RIGHT_TO_LEFT) { + // Vertical text _empty_cursor_shape.position = Geom::Point(scan_runs.front().y + font_size, scan_runs.front().x_start); - else + } else { + // Horizontal text _empty_cursor_shape.position = Geom::Point(scan_runs.front().x_start, scan_runs.front().y + font_size); + } } } } diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index 137fe0a0f..c7275c24e 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -120,7 +120,7 @@ Layout::iterator Layout::getNearestCursorPositionTo(double x, double y) const double best_y_range = DBL_MAX; double best_x_range = DBL_MAX; for (chunk_index = 0 ; chunk_index < _chunks.size() ; chunk_index++) { - LineHeight line_height = {0.0, 0.0, 0.0}; + FontMetrics line_height = {0.0, 0.0, 0.0}; double chunk_width = 0.0; for ( ; span_index < _spans.size() && _spans[span_index].in_chunk == chunk_index ; span_index++) { line_height.max(_spans[span_index].line_height); @@ -340,8 +340,8 @@ Geom::Rect Layout::characterBoundingBox(iterator const &it, double *rotation) co double baseline_y = _characters[char_index].line(this).baseline_y + _characters[char_index].span(this).baseline_shift; if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { - double span_height = _spans[_characters[char_index].in_span].line_height.ascent + _spans[_characters[char_index].in_span].line_height.descent; - top_left[Geom::Y] = top_left[Geom::X]; + double span_height = _spans[_characters[char_index].in_span].line_height.emSize(); + top_left[Geom::Y] = top_left[Geom::X]; top_left[Geom::X] = baseline_y - span_height * 0.5; bottom_right[Geom::Y] = bottom_right[Geom::X]; bottom_right[Geom::X] = baseline_y + span_height * 0.5; @@ -404,7 +404,7 @@ std::vector Layout::createSelectionShape(iterator const &it_start, double vertical_scale = _glyphs.back().vertical_scale; if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { - double span_height = vertical_scale * (_spans[span_index].line_height.ascent + _spans[span_index].line_height.descent); + double span_height = vertical_scale * _spans[span_index].line_height.emSize(); top_left[Geom::Y] = top_left[Geom::X]; top_left[Geom::X] = baseline_y - span_height * 0.5; bottom_right[Geom::Y] = bottom_right[Geom::X]; @@ -510,17 +510,19 @@ void Layout::queryCursorShape(iterator const &it, Geom::Point &position, double double vertical_scale = _glyphs.empty() ? 1.0 : _glyphs.back().vertical_scale; if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { - height = vertical_scale * span->line_height.ascent + span->line_height.descent; + // Vertical text + height = vertical_scale * span->line_height.emSize(); rotation += M_PI / 2; std::swap(position[Geom::X], position[Geom::Y]); position[Geom::X] -= vertical_scale * sin(rotation) * height * 0.5; position[Geom::Y] += vertical_scale * cos(rotation) * height * 0.5; } else { + // Horizontal text double caret_slope_run = 0.0, caret_slope_rise = 1.0; if (span->font) const_cast(span->font)->FontSlope(caret_slope_run, caret_slope_rise); double caret_slope = atan2(caret_slope_run, caret_slope_rise); - height = vertical_scale * (span->line_height.ascent + span->line_height.descent) / cos(caret_slope); + height = vertical_scale * (span->line_height.emSize()) / cos(caret_slope); rotation += caret_slope; position[Geom::X] -= sin(rotation) * vertical_scale * span->line_height.descent; position[Geom::Y] += cos(rotation) * vertical_scale * span->line_height.descent; diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 6e3faf33b..0bbf266c7 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -93,26 +93,41 @@ void Layout::_clearOutputObjects() _path_fitted = NULL; } -void Layout::LineHeight::max(LineHeight const &other) +void Layout::FontMetrics::max(FontMetrics const &other) { if (other.ascent > ascent) ascent = other.ascent; if (other.descent > descent) descent = other.descent; - if (other.leading > leading) leading = other.leading; +} + +void Layout::FontMetrics::computeEffective( const double &line_height_multiplier ) { + double half_leading = 0.5 * (line_height_multiplier - 1.0) * emSize(); + ascent += half_leading; + descent += half_leading; } void Layout::_getGlyphTransformMatrix(int glyph_index, Geom::Affine *matrix) const { Span const &span = _glyphs[glyph_index].span(this); - double sin_rotation = sin(_glyphs[glyph_index].rotation); - double cos_rotation = cos(_glyphs[glyph_index].rotation); + double rotation = _glyphs[glyph_index].rotation; + if ( (span.block_progression == LEFT_TO_RIGHT || span.block_progression == RIGHT_TO_LEFT) && + _glyphs[glyph_index].orientation == ORIENTATION_SIDEWAYS ) { + // Vertical sideways text + rotation += M_PI/2.0; + } + double sin_rotation = sin(rotation); + double cos_rotation = cos(rotation); (*matrix)[0] = span.font_size * cos_rotation; (*matrix)[1] = span.font_size * sin_rotation; (*matrix)[2] = span.font_size * sin_rotation; (*matrix)[3] = -span.font_size * cos_rotation * (_glyphs[glyph_index].vertical_scale); // unscale vertically so the specified text height is preserved if lengthAdjust=spacingAndGlyphs if (span.block_progression == LEFT_TO_RIGHT || span.block_progression == RIGHT_TO_LEFT) { + // Vertical text + // This effectively swaps x for y which changes handedness of coordinate system. This is a bit strange + // and not what one would expect but the compute code already reverses y so OK. (*matrix)[4] = _lines[_chunks[span.in_chunk].in_line].baseline_y + _glyphs[glyph_index].y; (*matrix)[5] = _chunks[span.in_chunk].left_x + _glyphs[glyph_index].x; } else { + // Horizontal text (*matrix)[4] = _chunks[span.in_chunk].left_x + _glyphs[glyph_index].x; (*matrix)[5] = _lines[_chunks[span.in_chunk].in_line].baseline_y + _glyphs[glyph_index].y; } @@ -129,7 +144,7 @@ void Layout::show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const text_source->style->text_decoration_data.tspan_width = _spans[span_index].width(); text_source->style->text_decoration_data.ascender = _spans[span_index].line_height.getAscent(); text_source->style->text_decoration_data.descender = _spans[span_index].line_height.getDescent(); - text_source->style->text_decoration_data.line_gap = _spans[span_index].line_height.getLeading(); + if(!span_index || (_chunks[_spans[span_index].in_chunk].in_line != _chunks[_spans[span_index-1].in_chunk].in_line)){ text_source->style->text_decoration_data.tspan_line_start = true; @@ -580,7 +595,7 @@ Glib::ustring Layout::dumpAsText() const result += Glib::ustring::compose(" font '%1' %2 %3 %4\n", sp_font_description_get_family(_spans[span_index].font->descr), _spans[span_index].font_size, style_to_text(pango_font_description_get_style(_spans[span_index].font->descr)), weight_to_text(pango_font_description_get_weight(_spans[span_index].font->descr))); } result += Glib::ustring::compose(" x_start = %1, x_end = %2\n", _spans[span_index].x_start, _spans[span_index].x_end) - + Glib::ustring::compose(" line height: ascent %1, descent %2 leading %3\n", _spans[span_index].line_height.ascent, _spans[span_index].line_height.descent, _spans[span_index].line_height.leading) + + Glib::ustring::compose(" line height: ascent %1, descent %2\n", _spans[span_index].line_height.ascent, _spans[span_index].line_height.descent) + Glib::ustring::compose(" direction %1, block-progression %2\n", direction_to_text(_spans[span_index].direction), direction_to_text(_spans[span_index].block_progression)) + " ** characters:\n"; Glib::ustring::const_iterator iter_char = _spans[span_index].input_stream_first_character; diff --git a/src/libnrtype/Layout-TNG-Scanline-Maker.h b/src/libnrtype/Layout-TNG-Scanline-Maker.h index d513d7cc1..da70bff89 100644 --- a/src/libnrtype/Layout-TNG-Scanline-Maker.h +++ b/src/libnrtype/Layout-TNG-Scanline-Maker.h @@ -47,7 +47,7 @@ public: between calls if the new height too big to fit in the space remaining in this shape. Returns an empty vector if there is no space left in the current shape. */ - virtual std::vector makeScanline(Layout::LineHeight const &line_height) =0; + virtual std::vector makeScanline(Layout::FontMetrics const &line_height) =0; /** Indicates that the caller has successfully filled the current line and hence that the next call to makeScanline() should return lines on @@ -71,7 +71,7 @@ public: The metrics given here are considered to be the ones that are being used now, and hence is the line advance height used by completeLine(). */ - virtual bool canExtendCurrentScanline(Layout::LineHeight const &line_height) =0; + virtual bool canExtendCurrentScanline(Layout::FontMetrics const &line_height) =0; }; /** \brief private to Layout. Generates infinite scanlines for when you don't want wrapping @@ -90,7 +90,7 @@ public: virtual ~InfiniteScanlineMaker(); /** Returns a single infinite run at the current location */ - virtual std::vector makeScanline(Layout::LineHeight const &line_height); + virtual std::vector makeScanline(Layout::FontMetrics const &line_height); /** Increments the current y by the current line height */ virtual void completeLine(); @@ -102,11 +102,11 @@ public: virtual void setNewYCoordinate(double new_y); /** Always true, but has to save the new height */ - virtual bool canExtendCurrentScanline(Layout::LineHeight const &line_height); + virtual bool canExtendCurrentScanline(Layout::FontMetrics const &line_height); private: double _x, _y; - Layout::LineHeight _current_line_height; + Layout::FontMetrics _current_line_height; bool _negative_block_progression; /// if true, indicates that completeLine() should decrement rather than increment, ie block-progression is either rl or bt }; @@ -122,7 +122,7 @@ public: ShapeScanlineMaker(Shape const *shape, Layout::Direction block_progression); virtual ~ShapeScanlineMaker(); - virtual std::vector makeScanline(Layout::LineHeight const &line_height); + virtual std::vector makeScanline(Layout::FontMetrics const &line_height); virtual void completeLine(); @@ -131,7 +131,7 @@ public: virtual void setNewYCoordinate(double new_y); /** never true */ - virtual bool canExtendCurrentScanline(Layout::LineHeight const &line_height); + virtual bool canExtendCurrentScanline(Layout::FontMetrics const &line_height); private: /** To generate scanlines for top-to-bottom text it is easiest if we simply rotate the given shape by a multiple of 90 degrees. This stores diff --git a/src/libnrtype/Layout-TNG-Scanline-Makers.cpp b/src/libnrtype/Layout-TNG-Scanline-Makers.cpp index 7144f3876..67fffd620 100644 --- a/src/libnrtype/Layout-TNG-Scanline-Makers.cpp +++ b/src/libnrtype/Layout-TNG-Scanline-Makers.cpp @@ -19,9 +19,7 @@ namespace Text { Layout::InfiniteScanlineMaker::InfiniteScanlineMaker(double initial_x, double initial_y, Layout::Direction block_progression) { - _current_line_height.ascent = 0.0; - _current_line_height.descent = 0.0; - _current_line_height.leading = 0.0; + _current_line_height.setZero(); switch (block_progression) { case LEFT_TO_RIGHT: case RIGHT_TO_LEFT: @@ -41,7 +39,7 @@ Layout::InfiniteScanlineMaker::~InfiniteScanlineMaker() { } -std::vector Layout::InfiniteScanlineMaker::makeScanline(Layout::LineHeight const &line_height) +std::vector Layout::InfiniteScanlineMaker::makeScanline(Layout::FontMetrics const &line_height) { std::vector runs(1); runs[0].x_start = _x; @@ -54,12 +52,10 @@ std::vector Layout::InfiniteScanlineMaker::makeS void Layout::InfiniteScanlineMaker::completeLine() { if (_negative_block_progression) - _y -= _current_line_height.total(); + _y -= _current_line_height.emSize(); else - _y += _current_line_height.total(); - _current_line_height.ascent = 0.0; - _current_line_height.descent = 0.0; - _current_line_height.leading = 0.0; + _y += _current_line_height.emSize(); + _current_line_height.setZero(); } void Layout::InfiniteScanlineMaker::setNewYCoordinate(double new_y) @@ -67,7 +63,7 @@ void Layout::InfiniteScanlineMaker::setNewYCoordinate(double new_y) _y = new_y; } -bool Layout::InfiniteScanlineMaker::canExtendCurrentScanline(Layout::LineHeight const &line_height) +bool Layout::InfiniteScanlineMaker::canExtendCurrentScanline(Layout::FontMetrics const &line_height) { _current_line_height = line_height; return true; @@ -111,29 +107,29 @@ Layout::ShapeScanlineMaker::~ShapeScanlineMaker() delete _rotated_shape; } -std::vector Layout::ShapeScanlineMaker::makeScanline(Layout::LineHeight const &line_height) +std::vector Layout::ShapeScanlineMaker::makeScanline(Layout::FontMetrics const &line_height) { - FloatLigne line_rasterization; - FloatLigne line_decent_length_runs; - float line_text_height = (float)(line_height.ascent + line_height.descent); - if (_y > _bounding_box_bottom) return std::vector(); if (_y < _bounding_box_top) _y = _bounding_box_top; + FloatLigne line_rasterization; + FloatLigne line_decent_length_runs; + float line_text_height = (float)(line_height.emSize()); if (line_text_height == 0.0) line_text_height = 0.001; // Scan() doesn't work for zero height so this will have to do - _current_line_height = (float)line_height.total(); + _current_line_height = (float)line_height.emSize(); // I think what's going on here is that we're moving the top of the scanline to the given position... _rotated_shape->Scan(_rasterizer_y, _current_rasterization_point, _y, line_text_height); // ...then actually retreiving the scanline (which alters the first two parameters) _rotated_shape->Scan(_rasterizer_y, _current_rasterization_point, _y + line_text_height , &line_rasterization, true, line_text_height); - // sanitise the raw rasterisation, which could have weird overlaps + // sanitise the raw rasterisation, which could have weird overlaps line_rasterization.Flatten(); + // line_rasterization.Affiche(); // cut out runs that cover less than 90% of the line line_decent_length_runs.Over(&line_rasterization, 0.9 * line_text_height); @@ -179,7 +175,7 @@ void Layout::ShapeScanlineMaker::setNewYCoordinate(double new_y) // it's not an important question because doesn't have a y attribute } -bool Layout::ShapeScanlineMaker::canExtendCurrentScanline(Layout::LineHeight const &/*line_height*/) +bool Layout::ShapeScanlineMaker::canExtendCurrentScanline(Layout::FontMetrics const &/*line_height*/) { //we actually could return true if only the leading changed, but that's too much effort for something that rarely happens return false; diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 26db1fad9..66cc96d3f 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -22,6 +22,7 @@ #include #include #include +#include "style-enums.h" #ifdef HAVE_CAIRO_PDF namespace Inkscape { @@ -157,6 +158,9 @@ public: both the 'direction' and 'block-progression' CSS attributes. */ enum Direction {LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM, BOTTOM_TO_TOP}; + /** Used to specify orientation of glyphs in vertical text. */ + enum Orientation {ORIENTATION_UPRIGHT, ORIENTATION_SIDEWAYS}; + /** Display alignment for shapes. See appendWrapShape(). */ enum DisplayAlign {DISPLAY_ALIGN_BEFORE, DISPLAY_ALIGN_CENTER, DISPLAY_ALIGN_AFTER}; @@ -603,18 +607,45 @@ public: //@} - /// it's useful for this to be public so that ScanlineMaker can use it - struct LineHeight { + + /** + * Keep track of font metrics. Two use cases: + * 1. Keep track of ascent and descent of an individual font. + * 2. Keep track of effective ascent and descent that includes half-leading. + * + * Note: Leading refers to the "external" leading which is added (subtracted) due to + * a computed value of 'line-height' that differs from 'font-size'. "Internal" leading + * which is specified inside a font is not used in CSS. The 'font-size' is based on + * the font's em size which is 'ascent' + 'descent'. + * + * This structure was renamed (and modified) from "LineHeight". + * + * It's useful for this to be public so that ScanlineMaker can use it. + */ + struct FontMetrics { + double ascent; double descent; - double leading; - inline double total() const {return ascent + descent + leading;} - inline void setZero() {ascent = descent = leading = 0.0;} - inline LineHeight& operator*=(double x) {ascent *= x; descent *= x; leading *= x; return *this;} - void max(LineHeight const &other); /// makes this object contain the largest of all three members between this object and other + double leading; // Not used... to be removed (requires change to font->FontMetrics() + + // CSS 2.1 dictates that font-size is based on em-size which is defined as ascent + descent + inline double emSize() const {return ascent + descent;} + // Alternatively name function for use 2. + inline double lineSize() const { return ascent + descent; } + inline void setZero() {ascent = descent = 0.0;} + + // For scaling for 'font-size'. + inline FontMetrics& operator*=(double x) {ascent *= x; descent *= x; return *this;} + + /// Save the larger values of ascent and descent between this and other. Needed for laying + /// out a line with mixed font-sizes, fonts, or line spacings. + void max(FontMetrics const &other); + + /// Calculate the effective ascent and descent including half "leading". + void computeEffective( const double &line_height ); + inline double getAscent() const {return ascent; } inline double getDescent() const {return descent; } - inline double getLeading() const {return leading; } }; /// see _enum_converter() @@ -748,6 +779,7 @@ private: float x; /// relative to the start of the chunk float y; /// relative to the current line's baseline float rotation; /// absolute, modulo any object transforms, which we don't know about + Orientation orientation; /// Orientation of glyph in vertical text float width; float vertical_scale; /// to implement lengthAdjust="spacingAndGlyphs" that must scale glyphs only horizontally; instead we change font size and then undo that change vertically only inline Span const & span(Layout const *l) const {return l->_spans[l->_characters[in_character].in_span];} @@ -772,8 +804,9 @@ private: float x_start; /// relative to the start of the chunk float x_end; /// relative to the start of the chunk inline float width() const {return std::abs(x_start - x_end);} - LineHeight line_height; + FontMetrics line_height; double baseline_shift; /// relative to the line's baseline + SPCSSTextOrientation text_orientation; Direction direction; /// See CSS3 section 3.2. Either rtl or ltr Direction block_progression; /// See CSS3 section 3.2. The direction in which lines go. unsigned in_input_stream_item; diff --git a/src/style-enums.h b/src/style-enums.h index 03255b3b1..c9a558e0f 100644 --- a/src/style-enums.h +++ b/src/style-enums.h @@ -174,10 +174,7 @@ enum SPCSSWritingMode { enum SPCSSTextOrientation { SP_CSS_TEXT_ORIENTATION_MIXED, SP_CSS_TEXT_ORIENTATION_UPRIGHT, - SP_CSS_TEXT_ORIENTATION_SIDEWAYS_RIGHT, - SP_CSS_TEXT_ORIENTATION_SIDEWAYS_LEFT, - SP_CSS_TEXT_ORIENTATION_SIDEWAYS, - SP_CSS_TEXT_ORIENTATION_USE_GLYPH_ORIENTATION + SP_CSS_TEXT_ORIENTATION_SIDEWAYS }; enum SPTextAnchor { @@ -519,10 +516,7 @@ static SPStyleEnum const enum_writing_mode[] = { static SPStyleEnum const enum_text_orientation[] = { {"mixed", SP_CSS_TEXT_ORIENTATION_MIXED}, // Default {"upright", SP_CSS_TEXT_ORIENTATION_UPRIGHT}, - {"sideways-right", SP_CSS_TEXT_ORIENTATION_SIDEWAYS_RIGHT}, - {"sideways-left", SP_CSS_TEXT_ORIENTATION_SIDEWAYS_LEFT}, {"sideways", SP_CSS_TEXT_ORIENTATION_SIDEWAYS}, - {"use-glyph-orientation", SP_CSS_TEXT_ORIENTATION_USE_GLYPH_ORIENTATION}, {NULL, -1} }; diff --git a/src/style-internal.h b/src/style-internal.h index 1ddab30f1..889292454 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -1260,7 +1260,6 @@ struct SPITextDecorationData { float tspan_width; // from libnrtype, when it calculates spans float ascender; // the rest from tspan's font float descender; - float line_gap; float underline_thickness; float underline_position; float line_through_thickness; diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 7b22e4af7..75c4a6736 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -737,7 +737,7 @@ static void sp_text_rotation_value_changed( GtkAdjustment *adj, GObject *tbl ) g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } -static void sp_text_orientation_mode_changed( EgeSelectOneAction *act, GObject *tbl ) +static void sp_writing_mode_changed( EgeSelectOneAction *act, GObject *tbl ) { // quit if run by the _changed callbacks if (g_object_get_data(G_OBJECT(tbl), "freeze")) { @@ -752,13 +752,73 @@ static void sp_text_orientation_mode_changed( EgeSelectOneAction *act, GObject * { case 0: { - sp_repr_css_set_property (css, "writing-mode", "lr"); + sp_repr_css_set_property (css, "writing-mode", "lr-tb"); break; } case 1: { - sp_repr_css_set_property (css, "writing-mode", "tb"); + sp_repr_css_set_property (css, "writing-mode", "tb-rl"); + break; + } + + case 2: + { + sp_repr_css_set_property (css, "writing-mode", "vertical-lr"); + break; + } +} + + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + + // If querying returned nothing, update default style. + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } + + sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); + if(result_numbers != QUERY_STYLE_NOTHING) + { + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Change writing mode")); + } + sp_repr_css_attr_unref (css); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_text_orientation_changed( EgeSelectOneAction *act, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + int mode = ege_select_one_action_get_active( act ); + + SPCSSAttr *css = sp_repr_css_attr_new (); + switch (mode) + { + case 0: + { + sp_repr_css_set_property (css, "text-orientation", "auto"); + break; + } + + case 1: + { + sp_repr_css_set_property (css, "text-orientation", "upright"); + break; + } + + case 2: + { + sp_repr_css_set_property (css, "text-orientation", "sideways"); break; } } @@ -893,13 +953,17 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_BASELINES); + int result_wmode = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES); /* * If no text in selection (querying returned nothing), read the style from * the /tools/text preferencess (default style for new texts). Return if * tool bar already set to these preferences. */ - if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING) { + if (result_family == QUERY_STYLE_NOTHING || + result_style == QUERY_STYLE_NOTHING || + result_numbers == QUERY_STYLE_NOTHING || + result_wmode == QUERY_STYLE_NOTHING ) { // There are no texts in selection, read from preferences. query.readFromPrefs("/tools/text"); #ifdef DEBUG_TEXT @@ -1047,13 +1111,42 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ gtk_adjustment_set_value( letterSpacingAdjustment, letterSpacing ); + // Writing mode + int activeButton2 = 0; + if (query.writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB) activeButton2 = 0; + if (query.writing_mode.computed == SP_CSS_WRITING_MODE_TB_RL) activeButton2 = 1; + if (query.writing_mode.computed == SP_CSS_WRITING_MODE_TB_LR) activeButton2 = 2; + + EgeSelectOneAction* writingModeAction = + EGE_SELECT_ONE_ACTION( g_object_get_data( tbl, "TextWritingModeAction" ) ); + ege_select_one_action_set_active( writingModeAction, activeButton2 ); + // Orientation - int activeButton2 = (query.writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB ? 0 : 1); + int activeButton3 = 0; + if (query.text_orientation.computed == SP_CSS_TEXT_ORIENTATION_MIXED ) activeButton3 = 0; + if (query.text_orientation.computed == SP_CSS_TEXT_ORIENTATION_UPRIGHT ) activeButton3 = 1; + if (query.text_orientation.computed == SP_CSS_TEXT_ORIENTATION_SIDEWAYS) activeButton3 = 2; EgeSelectOneAction* textOrientationAction = EGE_SELECT_ONE_ACTION( g_object_get_data( tbl, "TextOrientationAction" ) ); - ege_select_one_action_set_active( textOrientationAction, activeButton2 ); + ege_select_one_action_set_active( textOrientationAction, activeButton3 ); + + // Disable text orientation for horizontal text.. See above for why this nonsense + model = GTK_LIST_STORE( ege_select_one_action_get_model( textOrientationAction ) ); + path = gtk_tree_path_new_from_string("0"); + gtk_tree_model_get_iter( GTK_TREE_MODEL (model), &iter, path ); + gtk_list_store_set( model, &iter, /* column */ 3, activeButton2 != 0, -1 ); + + path = gtk_tree_path_new_from_string("1"); + gtk_tree_model_get_iter( GTK_TREE_MODEL (model), &iter, path ); + gtk_list_store_set( model, &iter, /* column */ 3, activeButton2 != 0, -1 ); + + path = gtk_tree_path_new_from_string("2"); + gtk_tree_model_get_iter( GTK_TREE_MODEL (model), &iter, path ); + gtk_list_store_set( model, &iter, /* column */ 3, activeButton2 != 0, -1 ); + + ege_select_one_action_update_sensitive( textOrientationAction ); } @@ -1387,7 +1480,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_text_align_mode_changed), holder ); } - /* Orientation (Left to Right, Top to Bottom */ + /* Writing mode (Horizontal, Vertical-LR, Vertical-RL) */ { GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); @@ -1402,14 +1495,73 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, - 0, _("Vertical"), - 1, _("Vertical text"), + 0, _("Vertical — RL"), + 1, _("Vertical text — lines: right to left"), 2, INKSCAPE_ICON("format-text-direction-vertical"), -1 ); + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("Vertical — LR"), + 1, _("Vertical text — lines: left to right"), // Mongolian! + 2, INKSCAPE_ICON("format-text-direction-vertical-lr"), + -1 ); + + EgeSelectOneAction* act = ege_select_one_action_new( "TextWritingModeAction", // Name + _("Writing mode"), // Label + _("Block progression"), // Tooltip + NULL, // Icon name + GTK_TREE_MODEL(model) ); // Model + + g_object_set( act, "short_label", "NotUsed", NULL ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + g_object_set_data( holder, "TextWritingModeAction", act ); + + ege_select_one_action_set_appearance( act, "full" ); + ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); + g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); + ege_select_one_action_set_icon_column( act, 2 ); + ege_select_one_action_set_icon_size( act, secondarySize ); + ege_select_one_action_set_tooltip_column( act, 1 ); + + gint mode = prefs->getInt("/tools/text/writing_mode", 0); + ege_select_one_action_set_active( act, mode ); + g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_writing_mode_changed), holder ); + } + + /* Text (glyph) orientation (Auto (mixed), Upright, Sideways) */ + { + GtkListStore* model = gtk_list_store_new( 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN ); + + GtkTreeIter iter; + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("Auto"), + 1, _("Auto glyph orientation"), + 2, INKSCAPE_ICON("text-orientation-auto"), + 3, true, + -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("Upright"), + 1, _("Upright glyph orientation"), + 2, INKSCAPE_ICON("text-orientation-upright"), + 3, true, + -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("Sideways"), + 1, _("Sideways glyph orientation"), + 2, INKSCAPE_ICON("text-orientation-sideways"), + 3, true, + -1 ); + EgeSelectOneAction* act = ege_select_one_action_new( "TextOrientationAction", // Name - _("Orientation"), // Label - _("Text orientation"), // Tooltip + _("Text orientation"), // Label + _("Text (glyph) orientation in vertical text."), // Tooltip NULL, // Icon name GTK_TREE_MODEL(model) ); // Model @@ -1423,10 +1575,11 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje ege_select_one_action_set_icon_column( act, 2 ); ege_select_one_action_set_icon_size( act, secondarySize ); ege_select_one_action_set_tooltip_column( act, 1 ); + ege_select_one_action_set_sensitive_column( act, 3 ); - gint mode = prefs->getInt("/tools/text/orientation", 0); + gint mode = prefs->getInt("/tools/text/text_orientation", 0); ege_select_one_action_set_active( act, mode ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_text_orientation_mode_changed), holder ); + g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_text_orientation_changed), holder ); } /* Line height */ diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index a1c32352c..00c09e50e 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -478,6 +478,8 @@ static gchar const * ui_descr = " " " " " " + " " + " " " " " " -- cgit v1.2.3 From db7f8af5407653016d6b2847f779ce59f568cdaa Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 28 Oct 2015 18:43:39 +0100 Subject: Fix the problems on transformed layers (bzr r14422.1.20) --- src/ui/tools/spray-tool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 269afbbbf..fd7c99d91 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -355,7 +355,7 @@ 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){ SPDocument *doc = item->document; - path *= doc->getRoot()->c2p.inverse(); + path *= i2anc_affine(static_cast(item->parent), NULL).inverse(); path *= item->transform.inverse(); Geom::Affine dt2p; if (item->parent) { @@ -366,7 +366,7 @@ static void sp_spray_transform_path(SPItem * item, Geom::Path &path, Geom::Affin } Geom::Affine i2dt = item->i2dt_affine() * Geom::Translate(center).inverse() * affine * Geom::Translate(center); path *= i2dt * dt2p; - path *= doc->getRoot()->c2p; + path *= i2anc_affine(static_cast(item->parent), NULL); } static bool fit_item(SPDesktop *desktop, -- cgit v1.2.3 From 598dbc9628a3f31e877a4848896b9d0421683106 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 28 Oct 2015 19:09:21 +0100 Subject: add a ignore transparent areas option (bzr r14422.1.21) --- src/ui/tools/spray-tool.cpp | 49 +++++++++++++++++++++++++------------------ src/ui/tools/spray-tool.h | 1 + src/widgets/spray-toolbar.cpp | 37 +++++++++++++++++++++++++++++--- src/widgets/toolbox.cpp | 1 + 4 files changed, 65 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index fd7c99d91..e1c5b36b2 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -162,6 +162,7 @@ SprayTool::SprayTool() , dilate_area(NULL) , overlap(false) , picker(false) + , visible(false) , offset(0) { } @@ -237,6 +238,7 @@ void SprayTool::setup() { sp_event_context_read(this, "Scale"); sp_event_context_read(this, "offset"); sp_event_context_read(this, "picker"); + sp_event_context_read(this, "visible"); sp_event_context_read(this, "overlap"); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -279,6 +281,8 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) { this->offset = CLAMP(val.getDouble(), -1000.0, 1000.0); } else if (path == "picker") { this->picker = val.getBool(); + } else if (path == "visible") { + this->visible = val.getBool(); } else if (path == "overlap") { this->overlap = val.getBool(); } @@ -354,7 +358,6 @@ 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){ - SPDocument *doc = item->document; path *= i2anc_affine(static_cast(item->parent), NULL).inverse(); path *= item->transform.inverse(); Geom::Affine dt2p; @@ -378,6 +381,7 @@ static bool fit_item(SPDesktop *desktop, double _scale, double scale, bool picker, + bool visible, bool overlap, double offset, SPCSSAttr *css) @@ -444,14 +448,14 @@ static bool fit_item(SPDesktop *desktop, std::abs(bbox_top - bbox_top_main) > std::abs(offset_min))){ return false; } - } else if(picker){ + } else if(picker || visible){ item_down->setHidden(true); item_down->updateRepr(); } } } } - if(picker){ + if(picker || visible){ if(!overlap){ doc->ensureUpToDate(); } @@ -465,19 +469,21 @@ static bool fit_item(SPDesktop *desktop, if (fabs(A) < 1e-4) { A = 0; // suppress exponentials, CSS does not allow that } - if (A > 0) { - R /= A; - G /= A; - B /= A; + if(picker){ + if (A > 0) { + R /= A; + G /= A; + B /= A; + } + guint32 c32 = SP_RGBA32_F_COMPOSE(R, G, B, A); + gchar c[64]; + sp_svg_write_color(c, sizeof(c), c32); + sp_repr_css_set_property(css, "fill", c); + std::stringstream fill_opacity; + fill_opacity.imbue(std::locale::classic()); + fill_opacity << float(A); + sp_repr_css_set_property(css, "fill-opacity", fill_opacity.str().c_str()); } - guint32 c32 = SP_RGBA32_F_COMPOSE(R, G, B, A); - gchar c[64]; - sp_svg_write_color(c, sizeof(c), c32); - sp_repr_css_set_property(css, "fill", c); - std::stringstream fill_opacity; - fill_opacity.imbue(std::locale::classic()); - fill_opacity << float(A); - sp_repr_css_set_property(css, "fill-opacity", fill_opacity.str().c_str()); if(!overlap){ for (std::vector::const_iterator k=items_down.begin(); k!=items_down.end(); k++) { SPItem *item_hidden = *k; @@ -511,6 +517,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, gint _distrib, bool overlap, bool picker, + bool visible, double offset, size_t &limit) { @@ -547,8 +554,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(overlap || picker){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, overlap, offset, css)){ + if(overlap || picker || visible){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, visible, overlap, offset, css)){ limit += 1; //Limit recursion to 10 levels //Seems enough to chech if there is place to put new copie @@ -572,6 +579,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, _distrib, overlap, picker, + visible, offset, limit); } else { @@ -681,8 +689,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(overlap || picker){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, overlap, offset, css)){ + if(overlap || picker || visible){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, visible, overlap, offset, css)){ limit += 1; if(limit < 11){ return sp_spray_recursive(desktop, @@ -704,6 +712,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, _distrib, overlap, picker, + visible, offset, limit); } else { @@ -786,7 +795,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point SPItem *item = *i; g_assert(item != NULL); size_t limit = 0; - 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->overlap,tc->picker, tc->offset, limit)) { + 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->overlap, tc->picker, tc->visible, tc->offset, limit)) { did = true; } } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index f65e0a223..8f000e095 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -89,6 +89,7 @@ public: SPCanvasItem *dilate_area; bool overlap; bool picker; + bool visible; double offset; sigc::connection style_set_connection; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 9f7a7cb1d..7831c0fe7 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -123,19 +123,37 @@ static void sp_spray_offset_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ static void sp_toggle_not_overlap( GtkToggleAction* act, gpointer data) { - - GObject *tbl = G_OBJECT(data); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); prefs->setBool("/tools/spray/overlap", active); + GObject *tbl = G_OBJECT(data); sp_stb_sensitivize(tbl); } +static void sp_toggle_visible( GtkToggleAction* act, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/visible", active); + if(active == true){ + prefs->setBool("/tools/spray/picker", false); + GObject *tbl = G_OBJECT(data); + GtkToggleAction *picker = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "picker") ); + gtk_toggle_action_set_active(picker, false); + } +} + static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); prefs->setBool("/tools/spray/picker", active); + if(active == true){ + prefs->setBool("/tools/spray/visible", false); + GObject *tbl = G_OBJECT(data); + GtkToggleAction *visible = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "visible") ); + gtk_toggle_action_set_active(visible, false); + } } void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) @@ -310,7 +328,20 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picker", false) ); g_object_set_data( holder, "picker", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_picker), desktop) ; + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_picker), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Visible */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayOverVisibleAction", + _("Apply on non transparent areas"), + _("Apply on non transparent areas"), + INKSCAPE_ICON("object-visible"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/visible", false) ); + g_object_set_data( holder, "visible", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_visible), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index f4bc367d0..ef2d89103 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -320,6 +320,7 @@ static gchar const * ui_descr = " " " " " " + " " " " " " -- cgit v1.2.3 From b0541736ec1d94e0c3db41c5dae5a11fefa65989 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 28 Oct 2015 20:12:17 +0100 Subject: Improvement to the css stored on change colors (bzr r14422.1.22) --- src/ui/tools/spray-tool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index e1c5b36b2..41e209cc1 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -553,7 +553,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, } 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(); + SPCSSAttr *css = sp_repr_css_attr(item->getRepr(), "style"); if(overlap || picker || visible){ if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, visible, overlap, offset, css)){ limit += 1; @@ -688,7 +688,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, } 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(); + SPCSSAttr *css = sp_repr_css_attr(item->getRepr(), "style"); if(overlap || picker || visible){ if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, visible, overlap, offset, css)){ limit += 1; -- cgit v1.2.3 From eb0dca3297aed737b3c0fdae7473413da9204346 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 28 Oct 2015 21:23:02 +0100 Subject: Increase recursion levels (bzr r14422.1.23) --- src/ui/tools/spray-tool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 41e209cc1..6376f1e19 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -559,7 +559,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, limit += 1; //Limit recursion to 10 levels //Seems enough to chech if there is place to put new copie - if(limit < 11){ + if(limit < 21){ return sp_spray_recursive(desktop, selection, item, @@ -692,7 +692,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, if(overlap || picker || visible){ if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, visible, overlap, offset, css)){ limit += 1; - if(limit < 11){ + if(limit < 21){ return sp_spray_recursive(desktop, selection, item, -- cgit v1.2.3 From a853619b54d05d6cc785a12fa747a3e702122b69 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Wed, 28 Oct 2015 21:28:43 +0100 Subject: typo (bzr r14431) --- src/live_effects/lpe-simplify.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index f6842a030..2d79d5b34 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -29,7 +29,7 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) : Effect(lpeobject), steps(_("Steps:"),_("Change number of simplify steps "), "steps", &wr, this,1), threshold(_("Roughly threshold:"), _("Roughly threshold:"), "threshold", &wr, this, 0.003), - smooth_angles(_("Smooth angles:"), _("Max degree difference on handles to preform a smooth"), "smooth_angles", &wr, this, 20.), + smooth_angles(_("Smooth angles:"), _("Max degree difference on handles to perform a smooth"), "smooth_angles", &wr, this, 20.), helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 5), simplify_individual_paths(_("Paths separately"), _("Simplifying paths (separately)"), "simplify_individual_paths", &wr, this, false, "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), -- cgit v1.2.3 From 2e1f86061452fc6cad648a3370236bf2cb1f1a7d Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Wed, 28 Oct 2015 21:43:30 +0100 Subject: static code analysis (bzr r14432) --- src/conn-avoid-ref.cpp | 2 +- src/desktop-style.cpp | 36 ++++++++++++++++++------------------ src/display/canvas-text.cpp | 6 +++++- src/display/curve.cpp | 2 +- src/live_effects/lpe-taperstroke.cpp | 3 +-- src/sp-filter.cpp | 2 +- src/uri.cpp | 2 +- src/uri.h | 2 +- src/widgets/sp-xmlview-attr-list.cpp | 2 ++ 9 files changed, 31 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/conn-avoid-ref.cpp b/src/conn-avoid-ref.cpp index ec9aba793..4c9665fa0 100644 --- a/src/conn-avoid-ref.cpp +++ b/src/conn-avoid-ref.cpp @@ -253,7 +253,7 @@ static std::vector approxItemWithPoints(SPItem const *item, const G SPGroup* group = SP_GROUP(item); // consider all first-order children std::vector itemlist = sp_item_group_item_list(group); - for (std::vector::const_iterator i = itemlist.begin(); i != itemlist.end(); i++) { + for (std::vector::const_iterator i = itemlist.begin(); i != itemlist.end(); ++i) { SPItem* child_item = *i; std::vector child_points = approxItemWithPoints(child_item, item_transform * child_item->transform); poly_points.insert(poly_points.end(), child_points.begin(), child_points.end()); diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 02c18339b..e66da90fb 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -195,7 +195,7 @@ sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write sp_css_attr_unset_uris(css_write); prefs->mergeStyle("/desktop/style", css_write); std::vector const itemlist = desktop->selection->itemList(); - for (std::vector::const_iterator i = itemlist.begin(); i!= itemlist.end(); i++) { + for (std::vector::const_iterator i = itemlist.begin(); i!= itemlist.end(); ++i) { /* last used styles for 3D box faces are stored separately */ SPObject *obj = *i; Box3DSide *side = dynamic_cast(obj); @@ -235,7 +235,7 @@ sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write css_no_text = sp_css_attr_unset_text(css_no_text); std::vector const itemlist = desktop->selection->itemList(); - for (std::vector::const_iterator i = itemlist.begin(); i!= itemlist.end(); i++) { + for (std::vector::const_iterator i = itemlist.begin(); i!= itemlist.end(); ++i) { SPItem *item = *i; // If not text, don't apply text attributes (can a group have text attributes? Yes! FIXME) @@ -447,7 +447,7 @@ stroke_average_width (const std::vector &objects) gdouble avgwidth = 0.0; bool notstroked = true; int n_notstroked = 0; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPItem *item = *i; if (!item) { continue; @@ -513,7 +513,7 @@ objects_query_fillstroke (const std::vector &objects, SPStyle *style_re prev[0] = prev[1] = prev[2] = 0.0; bool same_color = true; - for (std::vector::const_iterator i = objects.begin(); i!= objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i!= objects.end(); ++i) { SPObject *obj = *i; if (!obj) { continue; @@ -697,7 +697,7 @@ objects_query_opacity (const std::vector &objects, SPStyle *style_res) guint opacity_items = 0; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; if (!obj) { continue; @@ -753,7 +753,7 @@ objects_query_strokewidth (const std::vector &objects, SPStyle *style_r int n_stroked = 0; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; if (!obj) { continue; @@ -827,7 +827,7 @@ objects_query_miterlimit (const std::vector &objects, SPStyle *style_re gdouble prev_ml = -1; bool same_ml = true; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; if (!dynamic_cast(obj)) { continue; @@ -886,7 +886,7 @@ objects_query_strokecap (const std::vector &objects, SPStyle *style_res bool same_cap = true; int n_stroked = 0; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; if (!dynamic_cast(obj)) { continue; @@ -940,7 +940,7 @@ objects_query_strokejoin (const std::vector &objects, SPStyle *style_re bool same_join = true; int n_stroked = 0; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; if (!dynamic_cast(obj)) { continue; @@ -1003,7 +1003,7 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r int texts = 0; int no_size = 0; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; if (!isTextualItem(obj)) { @@ -1122,7 +1122,7 @@ objects_query_fontstyle (const std::vector &objects, SPStyle *style_res int texts = 0; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; if (!isTextualItem(obj)) { @@ -1192,7 +1192,7 @@ objects_query_fontvariants (const std::vector &objects, SPStyle *style_ caps_res->value = 0; numeric_res->value = 0; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; if (!isTextualItem(obj)) { @@ -1268,7 +1268,7 @@ objects_query_fontfeaturesettings (const std::vector &objects, SPStyle } style_res->font_feature_settings.set = FALSE; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; // std::cout << " " << reinterpret_cast(i->data)->getId() << std::endl; @@ -1336,7 +1336,7 @@ objects_query_baselines (const std::vector &objects, SPStyle *style_res int texts = 0; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; if (!isTextualItem(obj)) { @@ -1424,7 +1424,7 @@ objects_query_fontfamily (const std::vector &objects, SPStyle *style_re } style_res->font_family.set = FALSE; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; // std::cout << " " << reinterpret_cast(i->data)->getId() << std::endl; @@ -1480,7 +1480,7 @@ objects_query_fontspecification (const std::vector &objects, SPStyle *s } style_res->font_specification.set = FALSE; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; // std::cout << " " << reinterpret_cast(i->data)->getId() << std::endl; @@ -1538,7 +1538,7 @@ objects_query_blend (const std::vector &objects, SPStyle *style_res) bool same_blend = true; guint items = 0; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; if (!obj) { continue; @@ -1628,7 +1628,7 @@ objects_query_blur (const std::vector &objects, SPStyle *style_res) guint blur_items = 0; guint items = 0; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; if (!obj) { continue; diff --git a/src/display/canvas-text.cpp b/src/display/canvas-text.cpp index 5ad87b4ef..2c29fc207 100644 --- a/src/display/canvas-text.cpp +++ b/src/display/canvas-text.cpp @@ -266,10 +266,14 @@ sp_canvastext_set_coords (SPCanvasText *ct, gdouble x0, gdouble y0) void sp_canvastext_set_coords (SPCanvasText *ct, const Geom::Point start) { - Geom::Point pos = ct->desktop->doc2dt(start); + Geom::Point pos; g_return_if_fail (ct != NULL); g_return_if_fail (SP_IS_CANVASTEXT (ct)); + + if (ct && ct->desktop) { + pos = ct->desktop->doc2dt(start); + } if (DIFFER (pos[0], ct->s[Geom::X]) || DIFFER (pos[1], ct->s[Geom::Y])) { ct->s[Geom::X] = pos[0]; diff --git a/src/display/curve.cpp b/src/display/curve.cpp index 3024d1276..b6c387034 100644 --- a/src/display/curve.cpp +++ b/src/display/curve.cpp @@ -496,7 +496,7 @@ SPCurve::append(SPCurve const *curve2, _pathv.push_back( (*it) ); } - for (it++; it != curve2->_pathv.end(); ++it) { + for (++it; it != curve2->_pathv.end(); ++it) { _pathv.push_back( (*it) ); } } else { diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index ef616f802..f2ddd4929 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -408,9 +408,8 @@ Piecewise > stretch_along(Piecewise > pwd2_in, Geom::Path n = force_continuity(remove_short_cuts(n,.1)); int nbCopies = 0; - double scaling = 1; + double scaling = (uskeleton.domain().extent() - toffset)/pattBndsX->extent(); nbCopies = 1; - scaling = (uskeleton.domain().extent() - toffset)/pattBndsX->extent(); double pattWidth = pattBndsX->extent() * scaling; diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp index 1bde69dd1..c17c67fc5 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -246,7 +246,7 @@ void SPFilter::update(SPCtx *ctx, guint flags) { } childflags &= SP_OBJECT_MODIFIED_CASCADE; std::vector l(this->childList(true, SPObject::ActionUpdate)); - for(std::vector::const_iterator i=l.begin();i!=l.end();i++){ + for(std::vector::const_iterator i=l.begin();i!=l.end();++i){ SPObject *child = *i; if( SP_IS_FILTER_PRIMITIVE( child ) ) { child->updateDisplay(ctx, childflags); diff --git a/src/uri.cpp b/src/uri.cpp index 2eaf4ecc1..49bdab63c 100644 --- a/src/uri.cpp +++ b/src/uri.cpp @@ -148,7 +148,7 @@ gchar *URI::to_native_filename(gchar const* uri) throw(BadURIException) * Does not check if the returned path is the local document's path (local) * and thus redundent. Caller is expected to check against the document's path. */ -const std::string URI::getFullPath(std::string const base) const { +const std::string URI::getFullPath(std::string const &base) const { if (!_impl->getPath()) { return ""; } diff --git a/src/uri.h b/src/uri.h index cee1baa09..bdf5f1baa 100644 --- a/src/uri.h +++ b/src/uri.h @@ -104,7 +104,7 @@ public: static char *to_native_filename(char const* uri) throw(BadURIException); - const std::string getFullPath(std::string const base) const; + const std::string getFullPath(std::string const &base) const; char *toNativeFilename() const throw(BadURIException); diff --git a/src/widgets/sp-xmlview-attr-list.cpp b/src/widgets/sp-xmlview-attr-list.cpp index dd763aea5..a4c00db7c 100644 --- a/src/widgets/sp-xmlview-attr-list.cpp +++ b/src/widgets/sp-xmlview-attr-list.cpp @@ -145,6 +145,7 @@ void sp_xmlview_attr_list_select_row_by_key(SPXMLViewAttrList * list, const gcha break; } valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(list->store), &iter); + // cppcheck-suppress nullPointer // a string was copied in n by gtk_tree_model_get if (n) { g_free(n); } @@ -181,6 +182,7 @@ event_attr_changed (Inkscape::XML::Node * /*repr*/, } row++; valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(list->store), &iter); + // cppcheck-suppress nullPointer // a string was copied in n by gtk_tree_model_get if (n) { g_free(n); } -- cgit v1.2.3 From f0c7823bd854087fcd2989d205a178d9deea1a9a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 28 Oct 2015 23:14:01 +0100 Subject: Fix a regression updating CSS data (bzr r14422.1.24) --- src/ui/tools/spray-tool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 6376f1e19..f64e56a5b 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -553,7 +553,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, } 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(item->getRepr(), "style"); + SPCSSAttr *css = sp_repr_css_attr_new(); if(overlap || picker || visible){ if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, visible, overlap, offset, css)){ limit += 1; @@ -688,7 +688,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, } 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(item->getRepr(), "style"); + SPCSSAttr *css = sp_repr_css_attr_new(); if(overlap || picker || visible){ if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, visible, overlap, offset, css)){ limit += 1; -- cgit v1.2.3 From 6a0b7c70e7e07839551be32aba63ae4a6badee81 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 29 Oct 2015 02:37:02 +0100 Subject: Removed recursion from code because no speed improvements Added swith to 100 on toogle no overlap button pointed by Mc. Fixed crash pointed by Mc selecting all+no overlap+click (bzr r14422.1.25) --- src/ui/tools/spray-tool.cpp | 66 ++++--------------------------------------- src/widgets/spray-toolbar.cpp | 2 ++ 2 files changed, 7 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index f64e56a5b..29bfe1641 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -434,7 +434,7 @@ static bool fit_item(SPDesktop *desktop, for (std::vector::const_iterator j=items_selected.begin(); j!=items_selected.end(); j++) { SPItem *item_selected = *j; gchar const * spray_origin; - if(!item->getAttribute("inkscape: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"); @@ -518,8 +518,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, bool overlap, bool picker, bool visible, - double offset, - size_t &limit) + double offset) { bool did = false; @@ -556,35 +555,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, SPCSSAttr *css = sp_repr_css_attr_new(); if(overlap || picker || visible){ if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, visible, overlap, offset, css)){ - limit += 1; - //Limit recursion to 10 levels - //Seems enough to chech if there is place to put new copie - if(limit < 21){ - return sp_spray_recursive(desktop, - selection, - item, - p, - Geom::Point(), - mode, - radius, - population, - scale, - scale_variation, - false, - mean, - standard_deviation, - ratio, - tilt, - rotation_variation, - _distrib, - overlap, - picker, - visible, - offset, - limit); - } else { - return false; - } + return false; } } SPItem *item_copied; @@ -691,33 +662,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, SPCSSAttr *css = sp_repr_css_attr_new(); if(overlap || picker || visible){ if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, visible, overlap, offset, css)){ - limit += 1; - if(limit < 21){ - return sp_spray_recursive(desktop, - selection, - item, - p, - Geom::Point(), - mode, - radius, - population, - scale, - scale_variation, - false, - mean, - standard_deviation, - ratio, - tilt, - rotation_variation, - _distrib, - overlap, - picker, - visible, - offset, - limit); - } else { - return false; - } + return false; } } SPItem *item_copied; @@ -794,8 +739,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ SPItem *item = *i; g_assert(item != NULL); - size_t limit = 0; - 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->overlap, tc->picker, tc->visible, tc->offset, limit)) { + 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->overlap, tc->picker, tc->visible, tc->offset)) { did = true; } } diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 7831c0fe7..a335a6c4f 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -57,7 +57,9 @@ using Inkscape::UI::PrefPusher; static void sp_stb_sensitivize( GObject *tbl ) { GtkAction* offset = GTK_ACTION( g_object_get_data(tbl, "offset") ); + GtkAdjustment *adj_offset = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(offset) ); GtkToggleAction *overlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "overlap") ); + gtk_adjustment_set_value( adj_offset, 100.0 ); if (gtk_toggle_action_get_active(overlap)) { gtk_action_set_sensitive( offset, TRUE ); } else { -- cgit v1.2.3 From cb75f9913807063d2c15d68b4b1fcbb7ac9df408 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Thu, 29 Oct 2015 12:47:45 -0700 Subject: patch for bug 1511508 (bzr r14435) --- src/extension/internal/emf-inout.cpp | 5 +---- src/extension/internal/emf-print.cpp | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp index e88cf3d42..68b38f5ee 100644 --- a/src/extension/internal/emf-inout.cpp +++ b/src/extension/internal/emf-inout.cpp @@ -1174,10 +1174,7 @@ Emf::select_extpen(PEMF_CALLBACK_DATA d, int index) if (!d->dc[d->level].style.stroke_dasharray.values.empty() && (d->level==0 || (d->level>0 && d->dc[d->level].style.stroke_dasharray.values!=d->dc[d->level-1].style.stroke_dasharray.values))) d->dc[d->level].style.stroke_dasharray.values.clear(); for (unsigned int i=0; ielp.elpNumEntries; i++) { -// Doing it this way typically results in a pattern that is tiny, better to assume the array -// is the same scale as for dot/dash below, that is, no scaling should be applied -// double dash_length = pix_to_abs_size( d, pEmr->elp.elpStyleEntry[i] ); - double dash_length = pEmr->elp.elpStyleEntry[i]; + double dash_length = pix_to_abs_size( d, pEmr->elp.elpStyleEntry[i] ); d->dc[d->level].style.stroke_dasharray.values.push_back(dash_length); } d->dc[d->level].style.stroke_dasharray.set = 1; diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index 5b8aae655..cc798cc5f 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -708,7 +708,7 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform) n_dash = style->stroke_dasharray.values.size(); dash = new uint32_t[n_dash]; for (i = 0; i < n_dash; i++) { - dash[i] = style->stroke_dasharray.values[i]; + dash[i] = MAX(1, (uint32_t) round(scale * style->stroke_dasharray.values[i] * PX2WORLD)); } } } -- cgit v1.2.3 From fd5fce801e86b3e9ab0d56a702e89b11dbf7484e Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Thu, 29 Oct 2015 23:24:26 +0100 Subject: static code analysis (bzr r14436) --- src/display/canvas-text.cpp | 8 +--- src/extension/execution-env.cpp | 2 +- src/extension/internal/cairo-renderer.cpp | 2 +- src/extension/internal/latex-text-renderer.cpp | 2 +- src/live_effects/lpe-fill-between-many.cpp | 2 +- .../parameter/filletchamferpointarray.cpp | 10 ++-- src/pure-transform.h | 56 +++++++++++----------- src/selection-describer.cpp | 6 +-- src/snap.cpp | 2 +- src/sp-hatch.cpp | 2 +- src/unclump.cpp | 10 ++-- 11 files changed, 47 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/display/canvas-text.cpp b/src/display/canvas-text.cpp index 2c29fc207..7c019caf5 100644 --- a/src/display/canvas-text.cpp +++ b/src/display/canvas-text.cpp @@ -266,14 +266,10 @@ sp_canvastext_set_coords (SPCanvasText *ct, gdouble x0, gdouble y0) void sp_canvastext_set_coords (SPCanvasText *ct, const Geom::Point start) { - Geom::Point pos; - - g_return_if_fail (ct != NULL); + g_return_if_fail (ct && ct->desktop); g_return_if_fail (SP_IS_CANVASTEXT (ct)); - if (ct && ct->desktop) { - pos = ct->desktop->doc2dt(start); - } + Geom::Point pos = ct->desktop->doc2dt(start); if (DIFFER (pos[0], ct->s[Geom::X]) || DIFFER (pos[1], ct->s[Geom::Y])) { ct->s[Geom::X] = pos[0]; diff --git a/src/extension/execution-env.cpp b/src/extension/execution-env.cpp index 29c2b5537..27d19fdff 100644 --- a/src/extension/execution-env.cpp +++ b/src/extension/execution-env.cpp @@ -61,7 +61,7 @@ ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Imp if (desktop != NULL) { std::vector selected = desktop->getSelection()->itemList(); - for(std::vector::const_iterator x = selected.begin(); x != selected.end(); x++){ + for(std::vector::const_iterator x = selected.begin(); x != selected.end(); ++x){ Glib::ustring selected_id; selected_id = (*x)->getId(); _selected.insert(_selected.end(), selected_id); diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 5a5553e97..a4561fd11 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -295,7 +295,7 @@ static void sp_group_render(SPGroup *group, CairoRenderContext *ctx) TRACE(("sp_group_render opacity: %f\n", SP_SCALE24_TO_FLOAT(item->style->opacity.value))); std::vector l(group->childList(false)); - for(std::vector::const_iterator x = l.begin(); x!= l.end(); x++){ + for(std::vector::const_iterator x = l.begin(); x!= l.end(); ++x){ SPItem *item = dynamic_cast(*x); if (item) { renderer->renderItem(ctx, item); diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 5933dd526..dec75aeb6 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -229,7 +229,7 @@ LaTeXTextRenderer::writePostamble() void LaTeXTextRenderer::sp_group_render(SPGroup *group) { std::vector l = (group->childList(false)); - for(std::vector::const_iterator x = l.begin(); x != l.end(); x++){ + for(std::vector::const_iterator x = l.begin(); x != l.end(); ++x){ SPItem *item = dynamic_cast(*x); if (item) { renderItem(item); diff --git a/src/live_effects/lpe-fill-between-many.cpp b/src/live_effects/lpe-fill-between-many.cpp index 3e0810cfc..574ec3580 100644 --- a/src/live_effects/lpe-fill-between-many.cpp +++ b/src/live_effects/lpe-fill-between-many.cpp @@ -37,7 +37,7 @@ void LPEFillBetweenMany::doEffect (SPCurve * curve) { Geom::PathVector res_pathv; SPItem * firstObj = NULL; - for (std::vector::iterator iter = linked_paths._vector.begin(); iter != linked_paths._vector.end(); iter++) { + for (std::vector::iterator iter = linked_paths._vector.begin(); iter != linked_paths._vector.end(); ++iter) { SPObject *obj; if ((*iter)->ref.isAttached() && (obj = (*iter)->ref.getObject()) && SP_IS_ITEM(obj) && !(*iter)->_pathvector.empty()) { Geom::Path linked_path; diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp index b089213fd..399307502 100644 --- a/src/live_effects/parameter/filletchamferpointarray.cpp +++ b/src/live_effects/parameter/filletchamferpointarray.cpp @@ -159,9 +159,8 @@ void FilletChamferPointArrayParam::recalculate_controlpoints_for_new_pwd2( //todo: if the path remove some nodes whith the result of a straight //line but with handles, the node inserted into dont fire the knot // because is not handle as cusp node by get_nodetype function - bool this_is_line = true; bool next_is_line = is_straight_curve(*curve_it1); - this_is_line = is_straight_curve((*path_it)[counterCurves - 1]); + bool this_is_line = is_straight_curve((*path_it)[counterCurves - 1]); nodetype = get_nodetype((*path_it)[counterCurves - 1], *curve_it1); if (this_is_line || next_is_line) { nodetype = NODE_CUSP; @@ -307,9 +306,8 @@ void FilletChamferPointArrayParam::recalculate_knots( nodetype = NODE_NONE; } } else { - bool this_is_line = true; bool next_is_line = is_straight_curve(*curve_it1); - this_is_line = is_straight_curve((*path_it)[counterCurves - 1]); + bool this_is_line = is_straight_curve((*path_it)[counterCurves - 1]); nodetype = get_nodetype((*path_it)[counterCurves - 1], *curve_it1); if (this_is_line || next_is_line) { nodetype = NODE_CUSP; @@ -467,12 +465,12 @@ double FilletChamferPointArrayParam::len_to_rad(int index, double len) Geom::Point endArcPoint = B->toSBasis().valueAt(times[2]); Curve *knotCurve1 = A->portion(times[0], times[1]); Curve *knotCurve2 = B->portion(times[2], 1); - Geom::CubicBezier const *cubic1 = dynamic_cast(&*knotCurve1); + Geom::CubicBezier const *cubic1 = dynamic_cast(knotCurve1); Ray ray1(startArcPoint, A->finalPoint()); if (cubic1) { ray1.setPoints((*cubic1)[2], startArcPoint); } - Geom::CubicBezier const *cubic2 = dynamic_cast(&*knotCurve2); + Geom::CubicBezier const *cubic2 = dynamic_cast(knotCurve2); Ray ray2(B->initialPoint(), endArcPoint); if (cubic2) { ray2.setPoints(endArcPoint, (*cubic2)[1]); diff --git a/src/pure-transform.h b/src/pure-transform.h index 8ea74ce76..f973a95b1 100644 --- a/src/pure-transform.h +++ b/src/pure-transform.h @@ -54,10 +54,7 @@ public: // PureTranslate(); // Default constructor // PureTranslate(PureTranslate const &); // Copy constructor virtual ~PureTranslate() {}; - PureTranslate(Geom::Point vector = Geom::Point()) { - _vector = vector; - _vector_snapped = vector; - } + PureTranslate(Geom::Point vector = Geom::Point()) : _vector(vector), _vector_snapped(vector) {} Geom::Point getTranslationSnapped() {return _vector_snapped;} // PureTranslate * clone () const {return new PureTranslate(*this);} @@ -100,12 +97,12 @@ public: // PureScale(PureScale const &); // Copy constructor virtual ~PureScale() {}; - PureScale(Geom::Scale scale, Geom::Point origin, bool uniform) { - _scale = scale; - _scale_snapped = scale; - _origin = origin; - _uniform = uniform; - } + PureScale(Geom::Scale scale, Geom::Point origin, bool uniform) : + _scale (scale), + _scale_snapped (scale), + _origin (origin), + _uniform (uniform) + {} Geom::Scale getScaleSnapped() {return _scale_snapped;} // PureScale * clone () const {return new PureScale (*this);} @@ -142,12 +139,13 @@ protected: public: virtual ~PureStretchConstrained() {}; - PureStretchConstrained(Geom::Coord magnitude, Geom::Point origin, Geom::Dim2 direction, bool uniform) { - _magnitude = magnitude; - _origin = origin; - _direction = direction; - _uniform = uniform; - _stretch_snapped = Geom::Scale(magnitude, magnitude); + PureStretchConstrained(Geom::Coord magnitude, Geom::Point origin, Geom::Dim2 direction, bool uniform) : + _magnitude (magnitude), + _stretch_snapped (Geom::Scale(magnitude, magnitude)), + _origin (origin), + _direction (direction), + _uniform (uniform) + { if (not uniform) { _stretch_snapped[1-direction] = 1.0; } @@ -178,13 +176,13 @@ protected: public: virtual ~PureSkewConstrained() {}; - PureSkewConstrained(Geom::Coord skew, Geom::Coord scale, Geom::Point origin, Geom::Dim2 direction) { - _skew = skew; - _skew_snapped = skew; - _scale = scale; - _origin = origin; - _direction = direction; - }; + PureSkewConstrained(Geom::Coord skew, Geom::Coord scale, Geom::Point origin, Geom::Dim2 direction) : + _skew (skew), + _skew_snapped (skew), + _scale (scale), + _origin (origin), + _direction (direction) + {}; Geom::Coord getSkewSnapped() {return _skew_snapped;} @@ -212,12 +210,12 @@ public: // PureRotate(PureRotate const &); // Copy constructor virtual ~PureRotateConstrained() {}; - PureRotateConstrained(double angle, Geom::Point origin) { - _origin = origin; - _angle = angle; // in radians! - _angle_snapped = angle; - _uniform = true; // We do not yet allow for simultaneous rotation and scaling - } + PureRotateConstrained(double angle, Geom::Point origin) : + _angle (angle), // in radians! + _angle_snapped (angle), + _origin (origin), + _uniform (true) // We do not yet allow for simultaneous rotation and scaling + {} double getAngleSnapped() {return _angle_snapped;} diff --git a/src/selection-describer.cpp b/src/selection-describer.cpp index 8304db684..ddc7a0d10 100644 --- a/src/selection-describer.cpp +++ b/src/selection-describer.cpp @@ -46,7 +46,7 @@ char* collect_terms (const std::vector &items) std::stringstream ss; bool first = true; - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { + for ( std::vector::const_iterator iter=items.begin();iter!=items.end();++iter ) { SPItem *item = *iter; if (item) { const char *term = item->displayName(); @@ -65,7 +65,7 @@ static int count_terms (const std::vector &items) { GSList *check = NULL; int count=0; - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { + for ( std::vector::const_iterator iter=items.begin();iter!=items.end();++iter ) { SPItem *item = *iter; if (item) { const char *term = item->displayName(); @@ -82,7 +82,7 @@ static int count_terms (const std::vector &items) static int count_filtered (const std::vector &items) { int count=0; - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { + for ( std::vector::const_iterator iter=items.begin();iter!=items.end();++iter ) { SPItem *item = *iter; if (item) { count += item->isFiltered(); diff --git a/src/snap.cpp b/src/snap.cpp index 5a4a047b2..4721283c3 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -710,7 +710,7 @@ void SnapManager::setupIgnoreSelection(SPDesktop const *desktop, Inkscape::Selection *sel = _desktop->selection; std::vector const items = sel->itemList(); - for (std::vector::const_iterator i=items.begin();i!=items.end();i++) { + for (std::vector::const_iterator i=items.begin();i!=items.end();++i) { _items_to_ignore.push_back(*i); } } diff --git a/src/sp-hatch.cpp b/src/sp-hatch.cpp index ea4c5865a..2d938618c 100644 --- a/src/sp-hatch.cpp +++ b/src/sp-hatch.cpp @@ -113,7 +113,7 @@ void SPHatch::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) SPHatchPath *path_child = dynamic_cast(document->getObjectByRepr(child)); if (path_child) { - for (ViewIterator iter = _display.begin(); iter != _display.end(); iter++) { + for (ViewIterator iter = _display.begin(); iter != _display.end(); ++iter) { Geom::OptInterval extents = _calculateStripExtents(iter->bbox); Inkscape::DrawingItem *ac = path_child->show(iter->arenaitem->drawing(), iter->key, extents); diff --git a/src/unclump.cpp b/src/unclump.cpp index 81c958937..2c6840425 100644 --- a/src/unclump.cpp +++ b/src/unclump.cpp @@ -172,7 +172,7 @@ static double unclump_average (SPItem *item, std::list &others) { int n = 0; double sum = 0; - for (std::list::const_iterator i = others.begin(); i != others.end();i++) { + for (std::list::const_iterator i = others.begin(); i != others.end();++i) { SPItem *other = *i; if (other == item) @@ -196,7 +196,7 @@ static SPItem *unclump_closest (SPItem *item, std::list &others) double min = HUGE_VAL; SPItem *closest = NULL; - for (std::list::const_iterator i = others.begin(); i != others.end();i++) { + for (std::list::const_iterator i = others.begin(); i != others.end();++i) { SPItem *other = *i; if (other == item) @@ -219,7 +219,7 @@ static SPItem *unclump_farest (SPItem *item, std::list &others) { double max = -HUGE_VAL; SPItem *farest = NULL; - for (std::list::const_iterator i = others.begin(); i != others.end();i++) { + for (std::list::const_iterator i = others.begin(); i != others.end();++i) { SPItem *other = *i; if (other == item) @@ -259,7 +259,7 @@ unclump_remove_behind (SPItem *item, SPItem *closest, std::list &rest) double val_item = A * it[Geom::X] + B * it[Geom::Y] + C; std::vector out; - for (std::list::const_reverse_iterator i = rest.rbegin(); i != rest.rend();i++) { + for (std::list::const_reverse_iterator i = rest.rbegin(); i != rest.rend();++i) { SPItem *other = *i; if (other == item) @@ -336,7 +336,7 @@ unclump (std::vector &items) c_cache.clear(); wh_cache.clear(); - for (std::vector::const_iterator i = items.begin(); i != items.end();i++) { // for each original/clone x: + for (std::vector::const_iterator i = items.begin(); i != items.end();++i) { // for each original/clone x: SPItem *item = *i; std::list nei; -- cgit v1.2.3 From 109427b9ee5b74661b6bb2d5eb9efcc83d1a1082 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 30 Oct 2015 01:38:22 +0100 Subject: Add optional presure to width and to size Start showing trace dialog (bzr r14422.1.27) --- src/ui/dialog/clonetiler.cpp | 11 +++++--- src/ui/tools/spray-tool.cpp | 43 ++++++++++++++++++++++------ src/ui/tools/spray-tool.h | 4 ++- src/widgets/spray-toolbar.cpp | 66 ++++++++++++++++++++++++++++++++++++++++--- src/widgets/toolbox.cpp | 4 ++- 5 files changed, 110 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index da1c6d9fb..0b1d0ecf2 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(); @@ -777,7 +777,6 @@ CloneTiler::CloneTiler () : { 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,7 +786,12 @@ 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")); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if(prefs->getBool("/dialogs/clonetiler/opentrace", false)){ + gtk_notebook_set_current_page (GTK_NOTEBOOK(nb),5); + } + + GtkWidget *b = gtk_check_button_new_with_label (_("Trace the drawing under the tiles/spray tool")); 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); @@ -1289,7 +1293,6 @@ CloneTiler::CloneTiler () : } gtk_widget_show_all (mainbox); - } show_all(); diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 29bfe1641..e78f5787e 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -142,7 +142,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) @@ -234,7 +236,9 @@ 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"); @@ -258,8 +262,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") { @@ -297,9 +305,16 @@ 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); + //g_warning("Pressure, population: %f, %f", pressure, pressure * tc->population); + 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) @@ -314,11 +329,18 @@ static double get_path_standard_deviation(SprayTool *tc) static double get_population(SprayTool *tc) { - double pressure = (tc->usepressure? tc->pressure / TC_DEFAULT_PRESSURE : 1); + double pressure = (tc->usepressurepopulation? tc->pressure / TC_DEFAULT_PRESSURE : 1); //g_warning("Pressure, population: %f, %f", pressure, pressure * tc->population); return pressure * tc->population; } +static double get_pressure(SprayTool *tc) +{ + double pressure = (tc->usepressurepopulation? tc->pressure / TC_DEFAULT_PRESSURE : 1); + //g_warning("Pressure, population: %f, %f", pressure, pressure * tc->population); + return pressure; +} + static double get_move_mean(SprayTool *tc) { return tc->mean; @@ -518,7 +540,9 @@ static bool sp_spray_recursive(SPDesktop *desktop, bool overlap, bool picker, bool visible, - double offset) + double offset, + bool usepressurescale, + double pressure) { bool did = false; @@ -534,6 +558,9 @@ 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 * 2.0; + } double dr; double dp; random_position( dr, dp, mean, standard_deviation, _distrib ); dr=dr*radius; @@ -739,7 +766,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for(std::vector::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, tc->overlap, tc->picker, tc->visible, tc->offset)) { + 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->overlap, tc->picker, tc->visible, tc->offset, tc->usepressurescale, get_pressure(tc))) { did = true; } } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index 8f000e095..112ab77e9 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -63,7 +63,9 @@ public: /* attributes */ bool dragging; /* mouse state: mouse is dragging */ - bool usepressure; + bool usepressurewidth; + bool usepressurepopulation; + bool usepressurescale; bool usetilt; bool usetext; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index a335a6c4f..3b175b715 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -29,18 +29,23 @@ # include "config.h" #endif -#include +#include #include "spray-toolbar.h" #include "desktop.h" +#include "inkscape.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" #include "widgets/ege-select-one-action.h" #include "widgets/ink-action.h" #include "preferences.h" #include "toolbox.h" +#include "ui/dialog/clonetiler.h" +#include "ui/dialog/dialog-manager.h" #include "ui/icon-names.h" +#include + using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; using Inkscape::UI::PrefPusher; @@ -57,14 +62,23 @@ using Inkscape::UI::PrefPusher; static void sp_stb_sensitivize( GObject *tbl ) { GtkAction* offset = GTK_ACTION( g_object_get_data(tbl, "offset") ); + GtkAction* spray_scale = GTK_ACTION( g_object_get_data(tbl, "spray_scale") ); GtkAdjustment *adj_offset = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(offset) ); + GtkAdjustment *adj_scale = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(spray_scale) ); GtkToggleAction *overlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "overlap") ); + GtkToggleAction *usepressurescale = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "usepressurescale") ); gtk_adjustment_set_value( adj_offset, 100.0 ); if (gtk_toggle_action_get_active(overlap)) { gtk_action_set_sensitive( offset, TRUE ); } else { gtk_action_set_sensitive( offset, FALSE ); } + if (gtk_toggle_action_get_active(usepressurescale)) { + gtk_adjustment_set_value( adj_scale, 0.0 ); + gtk_action_set_sensitive( spray_scale, FALSE ); + } else { + gtk_action_set_sensitive( spray_scale, TRUE ); + } } static void sp_spray_width_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) @@ -132,6 +146,18 @@ static void sp_toggle_not_overlap( GtkToggleAction* act, gpointer data) sp_stb_sensitivize(tbl); } +static void sp_toggle_pressure_scale( GtkToggleAction* act, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/usepressurescale", active); + if(active == true){ + prefs->setDouble("/tools/spray/scale_variation", 0); + } + GObject *tbl = G_OBJECT(data); + sp_stb_sensitivize( tbl ); +} + static void sp_toggle_visible( GtkToggleAction* act, gpointer data) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -155,6 +181,11 @@ static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) GObject *tbl = G_OBJECT(data); GtkToggleAction *visible = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "visible") ); gtk_toggle_action_set_active(visible, false); + prefs->setBool("/dialogs/clonetiler/dotrace", true); + prefs->setBool("/dialogs/clonetiler/opentrace", true); + SPDesktop *dt = SP_ACTIVE_DESKTOP; + dt->_dlg_mgr->showDialog("CloneTiler"); + prefs->setBool("/dialogs/clonetiler/opentrace", false); } } @@ -177,7 +208,20 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); } + + /* Use Pressure Width button */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPressureWidthAction", + _("Pressure"), + _("Use the pressure of the input device to alter the width of spray area"), + INKSCAPE_ICON("draw-use-pressure"), + Inkscape::ICON_SIZE_DECORATION ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressurewidth"); + g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + } + { /* Mean */ gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(maximum mean)")}; @@ -272,15 +316,15 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_object_set_data( holder, "spray_population", eact ); } - /* Use Pressure button */ + /* Use Pressure Population button */ { - InkToggleAction* act = ink_toggle_action_new( "SprayPressureAction", + InkToggleAction* act = ink_toggle_action_new( "SprayPressurePopulationAction", _("Pressure"), _("Use the pressure of the input device to alter the amount of sprayed objects"), INKSCAPE_ICON("draw-use-pressure"), Inkscape::ICON_SIZE_DECORATION ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressure"); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressurepopulation"); g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); } @@ -321,6 +365,20 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_object_set_data( holder, "spray_scale", eact ); } + /* Use Pressure Scale button */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPressureScaleAction", + _("Pressure"), + _("Use the pressure of the input device to alter the scale of new items"), + INKSCAPE_ICON("draw-use-pressure"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/usepressurescale", false) ); + g_object_set_data( holder, "usepressurescale", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pressure_scale), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Picker */ { InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction", diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index ef2d89103..892d90cc1 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -310,11 +310,13 @@ static gchar const * ui_descr = " " " " " " + " " " " - " " + " " " " " " " " + " " " " " " " " -- cgit v1.2.3 From 670abe866479007812bdd5c5b29eff5116e06c8a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 30 Oct 2015 11:58:17 +0100 Subject: Some fixes to new pressure options (bzr r14422.1.29) --- src/ui/tools/spray-tool.cpp | 4 ++-- src/widgets/spray-toolbar.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index e78f5787e..a763e50a7 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -336,7 +336,7 @@ static double get_population(SprayTool *tc) static double get_pressure(SprayTool *tc) { - double pressure = (tc->usepressurepopulation? tc->pressure / TC_DEFAULT_PRESSURE : 1); + double pressure = tc->pressure / TC_DEFAULT_PRESSURE; //g_warning("Pressure, population: %f, %f", pressure, pressure * tc->population); return pressure; } @@ -559,7 +559,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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 * 2.0; + _scale = pressure; } double dr; double dp; random_position( dr, dp, mean, standard_deviation, _distrib ); diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 3b175b715..bc994d1b7 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -371,7 +371,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj _("Pressure"), _("Use the pressure of the input device to alter the scale of new items"), INKSCAPE_ICON("draw-use-pressure"), - secondarySize ); + Inkscape::ICON_SIZE_DECORATION); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/usepressurescale", false) ); g_object_set_data( holder, "usepressurescale", act ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pressure_scale), holder) ; -- cgit v1.2.3 From 0798ff4618d8e961cab364fdf827993c18aa69ac Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 30 Oct 2015 17:45:39 +0100 Subject: Open trace dialog on click on pick toogle (bzr r14422.1.30) --- src/ui/dialog/clonetiler.cpp | 14 ++++++++++---- src/ui/dialog/clonetiler.h | 4 +++- src/widgets/spray-toolbar.cpp | 22 +++++++++++++++++++--- 3 files changed, 32 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index 0b1d0ecf2..266d61ed5 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -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); @@ -776,7 +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); @@ -791,11 +790,11 @@ CloneTiler::CloneTiler () : gtk_notebook_set_current_page (GTK_NOTEBOOK(nb),5); } - GtkWidget *b = gtk_check_button_new_with_label (_("Trace the drawing under the tiles/spray tool")); + b = gtk_check_button_new_with_label (_("Trace the drawing under the tiles/spray tool")); 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 that clone's or item spayed location and apply it")); gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(b), "toggled", @@ -3008,6 +3007,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, true); +} + + } } } 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/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index bc994d1b7..1e7d42378 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -42,6 +42,7 @@ #include "toolbox.h" #include "ui/dialog/clonetiler.h" #include "ui/dialog/dialog-manager.h" +#include "ui/dialog/panel-dialog.h" #include "ui/icon-names.h" #include @@ -81,6 +82,20 @@ static void sp_stb_sensitivize( GObject *tbl ) } } +Inkscape::UI::Dialog::CloneTiler *get_clone_tiler_panel(SPDesktop *desktop) +{ + if (Inkscape::UI::Dialog::PanelDialogBase *panel_dialog = + dynamic_cast(desktop->_dlg_mgr->getDialog("CloneTiler"))) { + try { + Inkscape::UI::Dialog::CloneTiler &clone_tiler = + dynamic_cast(panel_dialog->getPanel()); + return &clone_tiler; + } catch (std::exception &e) { } + } + + return 0; +} + static void sp_spray_width_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -182,10 +197,11 @@ static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) GtkToggleAction *visible = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "visible") ); gtk_toggle_action_set_active(visible, false); prefs->setBool("/dialogs/clonetiler/dotrace", true); - prefs->setBool("/dialogs/clonetiler/opentrace", true); SPDesktop *dt = SP_ACTIVE_DESKTOP; - dt->_dlg_mgr->showDialog("CloneTiler"); - prefs->setBool("/dialogs/clonetiler/opentrace", false); + if (Inkscape::UI::Dialog::CloneTiler *ct = get_clone_tiler_panel(dt)){ + dt->_dlg_mgr->showDialog("CloneTiler"); + ct->show_page_trace(); + } } } -- cgit v1.2.3 From 2b4566e6d203b6b3cf90bca23b7de48f576cc361 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 30 Oct 2015 19:45:10 +0100 Subject: Now picker use all features of trace clones (bzr r14422.1.31) --- src/ui/tools/spray-tool.cpp | 218 ++++++++++++++++++++++++++++++++++-------- src/widgets/spray-toolbar.cpp | 26 ----- src/widgets/toolbox.cpp | 1 - 3 files changed, 176 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index a763e50a7..d0ea62caa 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -97,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; } @@ -164,7 +175,6 @@ SprayTool::SprayTool() , dilate_area(NULL) , overlap(false) , picker(false) - , visible(false) , offset(0) { } @@ -242,7 +252,6 @@ void SprayTool::setup() { sp_event_context_read(this, "Scale"); sp_event_context_read(this, "offset"); sp_event_context_read(this, "picker"); - sp_event_context_read(this, "visible"); sp_event_context_read(this, "overlap"); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -289,8 +298,6 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) { this->offset = CLAMP(val.getDouble(), -1000.0, 1000.0); } else if (path == "picker") { this->picker = val.getBool(); - } else if (path == "visible") { - this->visible = val.getBool(); } else if (path == "overlap") { this->overlap = val.getBool(); } @@ -394,19 +401,33 @@ static void sp_spray_transform_path(SPItem * item, Geom::Path &path, Geom::Affin path *= i2anc_affine(static_cast(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... +} + static bool fit_item(SPDesktop *desktop, SPItem *item, Geom::OptRect bbox, Geom::Point move, Geom::Point center, double angle, - double _scale, + double &_scale, double scale, bool picker, - bool visible, bool overlap, double offset, - SPCSSAttr *css) + SPCSSAttr *css, + bool trace_scale) { SPDocument *doc = item->document; double width = bbox->width(); @@ -416,30 +437,30 @@ static bool fit_item(SPDesktop *desktop, if(offset_min < 0 ){ offset_min = 0; } - bbox = Geom::Rect(Geom::Point(bbox->left() - offset_min, bbox->top() - offset_min),Geom::Point(bbox->right() + offset_min, bbox->bottom() + offset_min)); + Geom::OptRect bbox_procesed = Geom::Rect(Geom::Point(bbox->left() - offset_min, bbox->top() - offset_min),Geom::Point(bbox->right() + offset_min, bbox->bottom() + offset_min)); Geom::Path path; - path.start(Geom::Point(bbox->left(), bbox->top())); - path.appendNew(Geom::Point(bbox->right(), bbox->top())); - path.appendNew(Geom::Point(bbox->right(), bbox->bottom())); - path.appendNew(Geom::Point(bbox->left(), bbox->bottom())); + path.start(Geom::Point(bbox_procesed->left(), bbox_procesed->top())); + path.appendNew(Geom::Point(bbox_procesed->right(), bbox_procesed->top())); + path.appendNew(Geom::Point(bbox_procesed->right(), bbox_procesed->bottom())); + path.appendNew(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[Geom::X], move[Geom::Y]); path *= desktop->doc2dt(); - bbox = path.boundsFast(); - double bbox_left_main = bbox->left(); - double bbox_top_main = bbox->top(); - double width_transformed = bbox->width(); - double height_transformed = bbox->height(); + bbox_procesed = path.boundsFast(); + double bbox_left_main = bbox_procesed->left(); + double bbox_top_main = bbox_procesed->top(); + double width_transformed = bbox_procesed->width(); + double height_transformed = bbox_procesed->height(); size = std::min(width_transformed,height_transformed); if(offset < 100 ){ offset_min = ((99.0 - offset) * size)/100.0 - size; } else { offset_min = 0; } - std::vector items_down = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox); + std::vector items_down = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox_procesed); Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { return false; @@ -470,18 +491,29 @@ static bool fit_item(SPDesktop *desktop, std::abs(bbox_top - bbox_top_main) > std::abs(offset_min))){ return false; } - } else if(picker || visible){ + } else if(picker){ item_down->setHidden(true); item_down->updateRepr(); } } } } - if(picker || visible){ + if(picker){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if(!overlap){ doc->ensureUpToDate(); } - Geom::Point mid_point = desktop->d2w(bbox->midpoint()); + int pick = prefs->getInt("/dialogs/clonetiler/pick"); + bool pick_to_presence = prefs->getBool("/dialogs/clonetiler/pick_to_presence"); + bool pick_to_size = prefs->getBool("/dialogs/clonetiler/pick_to_size"); + bool pick_to_color = prefs->getBool("/dialogs/clonetiler/pick_to_color"); + bool pick_to_opacity = prefs->getBool("/dialogs/clonetiler/pick_to_opacity"); + double rand_picked = 0.01 * prefs->getDoubleLimited("/dialogs/clonetiler/rand_picked", 0, 0, 100); + bool invert_picked = prefs->getBool("/dialogs/clonetiler/invert_picked"); + double gamma_picked = prefs->getDoubleLimited("/dialogs/clonetiler/gamma_picked", 0, -10, 10); + double opacity = 1.0; + gchar color_string[32]; *color_string = 0; + 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); double R = 0, G = 0, B = 0, A = 0; cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); @@ -491,20 +523,126 @@ static bool fit_item(SPDesktop *desktop, if (fabs(A) < 1e-4) { A = 0; // suppress exponentials, CSS does not allow that } + if(A == 0 && R == 0 && G == 0 && B == 0){ + R = 1; + G = 1; + B = 1; + } if(picker){ - if (A > 0) { - R /= A; - G /= A; - B /= A; +// if (A > 0) { +// R /= A; +// G /= A; +// B /= A; +// } + guint32 rgba = SP_RGBA32_F_COMPOSE(R, G, B, A); + 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); + + 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 (r, power); + g = pow (g, power); + b = pow (b, 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_presence) { + //this line I think is wrong in original code clonetiler + //if (g_random_double_range (0, 1) > val) { + if(a == 0){ + return false; + } + } + if (pick_to_size) { + if(!trace_scale){ + _scale = 2 - (val * 1.7); + return fit_item(desktop, + item, + bbox, + move, + center, + angle, + _scale, + scale, + picker, + overlap, + offset, + css, + true); + } + } + if (pick_to_opacity) { + opacity *= a; + std::stringstream fill_opacity; + fill_opacity.imbue(std::locale::classic()); + fill_opacity << float(opacity); + sp_repr_css_set_property(css, "fill-opacity", fill_opacity.str().c_str()); + } + if (pick_to_color) { + sp_svg_write_color(color_string, sizeof(color_string), rgba); + sp_repr_css_set_property(css, "fill", color_string); } - guint32 c32 = SP_RGBA32_F_COMPOSE(R, G, B, A); - gchar c[64]; - sp_svg_write_color(c, sizeof(c), c32); - sp_repr_css_set_property(css, "fill", c); - std::stringstream fill_opacity; - fill_opacity.imbue(std::locale::classic()); - fill_opacity << float(A); - sp_repr_css_set_property(css, "fill-opacity", fill_opacity.str().c_str()); } if(!overlap){ for (std::vector::const_iterator k=items_down.begin(); k!=items_down.end(); k++) { @@ -513,9 +651,6 @@ static bool fit_item(SPDesktop *desktop, item_hidden->updateRepr(); } } - if(A == 0){ - return false; - } } return true; } @@ -539,7 +674,6 @@ static bool sp_spray_recursive(SPDesktop *desktop, gint _distrib, bool overlap, bool picker, - bool visible, double offset, bool usepressurescale, double pressure) @@ -580,8 +714,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(overlap || picker || visible){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, visible, overlap, offset, css)){ + if(overlap || picker){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, overlap, offset, css, false)){ return false; } } @@ -687,8 +821,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(overlap || picker || visible){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, visible, overlap, offset, css)){ + if(overlap || picker){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, overlap, offset, css, false)){ return false; } } @@ -766,7 +900,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for(std::vector::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, tc->overlap, tc->picker, tc->visible, tc->offset, tc->usepressurescale, get_pressure(tc))) { + 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->overlap, tc->picker, tc->offset, tc->usepressurescale, get_pressure(tc))) { did = true; } } diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 1e7d42378..842b8e0aa 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -173,19 +173,6 @@ static void sp_toggle_pressure_scale( GtkToggleAction* act, gpointer data) sp_stb_sensitivize( tbl ); } -static void sp_toggle_visible( GtkToggleAction* act, gpointer data) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/visible", active); - if(active == true){ - prefs->setBool("/tools/spray/picker", false); - GObject *tbl = G_OBJECT(data); - GtkToggleAction *picker = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "picker") ); - gtk_toggle_action_set_active(picker, false); - } -} - static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -408,19 +395,6 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } - /* Visible */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayOverVisibleAction", - _("Apply on non transparent areas"), - _("Apply on non transparent areas"), - INKSCAPE_ICON("object-visible"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/visible", false) ); - g_object_set_data( holder, "visible", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_visible), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - /* Overlap */ { InkToggleAction* act = ink_toggle_action_new( "SprayNotOverlapAction", diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 892d90cc1..0c72242e0 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -322,7 +322,6 @@ static gchar const * ui_descr = " " " " " " - " " " " " " -- cgit v1.2.3 From 0f6203288f49de2a3958b4adf3318b5777817169 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 30 Oct 2015 20:58:42 +0100 Subject: Fix a bug compiling on pow (bzr r14422.1.32) --- src/ui/tools/spray-tool.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index d0ea62caa..f81a274d1 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -588,9 +588,9 @@ static bool fit_item(SPDesktop *desktop, power = 1 + fabs(gamma_picked); val = pow (val, power); - r = pow (r, power); - g = pow (g, power); - b = pow (b, power); + r = pow ((double)r, (double)power); + g = pow ((double)g, (double)power); + b = pow ((double)b, (double)power); } if (invert_picked) { -- cgit v1.2.3 From ee0d08e599aae484a6e8354499b126596dc4aa73 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 31 Oct 2015 21:51:10 +0100 Subject: Working on picker (bzr r14422.1.33) --- src/ui/dialog/clonetiler.cpp | 16 +++++- src/ui/tools/spray-tool.cpp | 128 ++++++++++++++++++++++++++++-------------- src/ui/tools/spray-tool.h | 3 + src/widgets/spray-toolbar.cpp | 103 +++++++++++++++++++++++++++++++-- src/widgets/toolbox.cpp | 4 ++ 5 files changed, 203 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index 266d61ed5..da6cc5192 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -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(color_picker->gobj()), FALSE, FALSE, 0); @@ -1003,7 +1003,19 @@ CloneTiler::CloneTiler () : gtk_widget_set_sensitive (vvb, prefs->getBool(prefs_path + "dotrace")); } } - + // Info + { +#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) diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index f81a274d1..0b54d3779 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -175,6 +175,10 @@ SprayTool::SprayTool() , dilate_area(NULL) , overlap(false) , picker(false) + , pickinversescale(false) + , pickfill(false) + , pickstroke(false) + , visible(false) , offset(0) { } @@ -252,6 +256,10 @@ void SprayTool::setup() { sp_event_context_read(this, "Scale"); sp_event_context_read(this, "offset"); sp_event_context_read(this, "picker"); + sp_event_context_read(this, "pickinversescale"); + sp_event_context_read(this, "pickfill"); + sp_event_context_read(this, "pickstroke"); + sp_event_context_read(this, "visible"); sp_event_context_read(this, "overlap"); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -298,6 +306,14 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) { this->offset = CLAMP(val.getDouble(), -1000.0, 1000.0); } else if (path == "picker") { this->picker = val.getBool(); + } else if (path == "pickinversescale") { + this->pickinversescale = val.getBool(); + } else if (path == "pickfill") { + this->pickfill = val.getBool(); + } else if (path == "pickstroke") { + this->pickstroke = val.getBool(); + } else if (path == "visible") { + this->visible = val.getBool(); } else if (path == "overlap") { this->overlap = val.getBool(); } @@ -424,6 +440,10 @@ static bool fit_item(SPDesktop *desktop, double &_scale, double scale, bool picker, + bool pickinversescale, + bool pickfill, + bool pickstroke, + bool visible, bool overlap, double offset, SPCSSAttr *css, @@ -491,21 +511,21 @@ static bool fit_item(SPDesktop *desktop, std::abs(bbox_top - bbox_top_main) > std::abs(offset_min))){ return false; } - } else if(picker){ + } else if(picker || visible){ item_down->setHidden(true); item_down->updateRepr(); } } } } - if(picker){ + if(picker || visible){ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if(!overlap){ doc->ensureUpToDate(); } int pick = prefs->getInt("/dialogs/clonetiler/pick"); - bool pick_to_presence = prefs->getBool("/dialogs/clonetiler/pick_to_presence"); bool pick_to_size = prefs->getBool("/dialogs/clonetiler/pick_to_size"); + bool pick_to_presence = prefs->getBool("/dialogs/clonetiler/pick_to_presence", false); bool pick_to_color = prefs->getBool("/dialogs/clonetiler/pick_to_color"); bool pick_to_opacity = prefs->getBool("/dialogs/clonetiler/pick_to_opacity"); double rand_picked = 0.01 * prefs->getDoubleLimited("/dialogs/clonetiler/rand_picked", 0, 0, 100); @@ -518,28 +538,24 @@ static bool fit_item(SPDesktop *desktop, double R = 0, G = 0, B = 0, A = 0; cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); sp_canvas_arena_render_surface(SP_CANVAS_ARENA(desktop->getDrawing()), s, area); - ink_cairo_surface_average_color_premul(s, R, G, B, A); + ink_cairo_surface_average_color(s, R, G, B, A); cairo_surface_destroy(s); - if (fabs(A) < 1e-4) { - A = 0; // suppress exponentials, CSS does not allow that + guint32 rgba = SP_RGBA32_F_COMPOSE(R, G, B, A); + 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); + //this can fix the bug #1511998 if confirmed + if( a == 0 && r == 0 && g == 0 && b == 0){ + r = 1; + g = 1; + b = 1; } - if(A == 0 && R == 0 && G == 0 && B == 0){ - R = 1; - G = 1; - B = 1; + if(visible && (a == 0 || a < 1e-6)){ + return false; } - if(picker){ -// if (A > 0) { -// R /= A; -// G /= A; -// B /= A; -// } - guint32 rgba = SP_RGBA32_F_COMPOSE(R, G, B, A); - 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(picker){ float hsl[3]; sp_color_rgb_to_hsl_floatv (hsl, r, g, b); @@ -607,17 +623,17 @@ static bool fit_item(SPDesktop *desktop, // recompose tweaked color rgba = SP_RGBA32_F_COMPOSE(r, g, b, a); - if (pick_to_presence) { - //this line I think is wrong in original code clonetiler - //if (g_random_double_range (0, 1) > val) { - if(a == 0){ - return false; - } - } if (pick_to_size) { if(!trace_scale){ - _scale = 2 - (val * 1.7); - return fit_item(desktop, + if(pickinversescale){ + _scale = 1.0 - val; + } else { + _scale = val; + } + if _scale == 0.0){ + return false; + } + if(!fit_item(desktop, item, bbox, move, @@ -626,25 +642,47 @@ static bool fit_item(SPDesktop *desktop, _scale, scale, picker, + pickinversescale, + pickfill, + pickstroke, + visible, overlap, offset, css, - true); + true)){ + return false; + } } } + if (pick_to_opacity) { - opacity *= a; - std::stringstream fill_opacity; - fill_opacity.imbue(std::locale::classic()); - fill_opacity << float(opacity); - sp_repr_css_set_property(css, "fill-opacity", fill_opacity.str().c_str()); + 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 + //beabiohur 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); - sp_repr_css_set_property(css, "fill", color_string); + if(pickfill){ + sp_repr_css_set_property(css, "fill", color_string); + } + if(pickstroke){ + sp_repr_css_set_property(css, "stroke", color_string); + } + } + if (opacity < 1e-6) { // invisibly transparent, skip + return false; } } - if(!overlap){ + if(!overlap && (picker || visible)){ for (std::vector::const_iterator k=items_down.begin(); k!=items_down.end(); k++) { SPItem *item_hidden = *k; item_hidden->setHidden(false); @@ -674,6 +712,10 @@ static bool sp_spray_recursive(SPDesktop *desktop, gint _distrib, bool overlap, bool picker, + bool pickinversescale, + bool pickfill, + bool pickstroke, + bool visible, double offset, bool usepressurescale, double pressure) @@ -714,8 +756,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(overlap || picker){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, overlap, offset, css, false)){ + if(overlap || picker || visible){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversescale, pickfill, pickstroke, visible, overlap, offset, css, false)){ return false; } } @@ -821,8 +863,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(overlap || picker){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, overlap, offset, css, false)){ + if(overlap || picker || visible){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversescale, pickfill, pickstroke, visible, overlap, offset, css, false)){ return false; } } @@ -900,7 +942,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for(std::vector::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, tc->overlap, tc->picker, tc->offset, tc->usepressurescale, get_pressure(tc))) { + 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->overlap, tc->picker, tc->pickinversescale, tc->pickfill, tc->pickstroke, tc->visible, tc->offset, tc->usepressurescale, get_pressure(tc))) { did = true; } } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index 112ab77e9..89a06dee9 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -91,6 +91,9 @@ public: SPCanvasItem *dilate_area; bool overlap; bool picker; + bool pickinversescale; + bool pickfill; + bool pickstroke; bool visible; double offset; sigc::connection style_set_connection; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 842b8e0aa..ce37ac9f7 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -67,7 +67,11 @@ static void sp_stb_sensitivize( GObject *tbl ) GtkAdjustment *adj_offset = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(offset) ); GtkAdjustment *adj_scale = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(spray_scale) ); GtkToggleAction *overlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "overlap") ); + GtkToggleAction *picker = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "picker") ); GtkToggleAction *usepressurescale = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "usepressurescale") ); + GtkAction *pickfill = GTK_ACTION( g_object_get_data(tbl, "pickfill") ); + GtkAction *pickstroke = GTK_ACTION( g_object_get_data(tbl, "pickstroke") ); + GtkAction *pickinversescale = GTK_ACTION( g_object_get_data(tbl, "pickinversescale") ); gtk_adjustment_set_value( adj_offset, 100.0 ); if (gtk_toggle_action_get_active(overlap)) { gtk_action_set_sensitive( offset, TRUE ); @@ -80,6 +84,15 @@ static void sp_stb_sensitivize( GObject *tbl ) } else { gtk_action_set_sensitive( spray_scale, TRUE ); } + if(gtk_toggle_action_get_active(picker)){ + gtk_action_set_sensitive( pickfill, TRUE ); + gtk_action_set_sensitive( pickstroke, TRUE ); + gtk_action_set_sensitive( pickinversescale, TRUE ); + } else { + gtk_action_set_sensitive( pickfill, FALSE ); + gtk_action_set_sensitive( pickstroke, FALSE ); + gtk_action_set_sensitive( pickinversescale, FALSE ); + } } Inkscape::UI::Dialog::CloneTiler *get_clone_tiler_panel(SPDesktop *desktop) @@ -173,16 +186,19 @@ static void sp_toggle_pressure_scale( GtkToggleAction* act, gpointer data) sp_stb_sensitivize( tbl ); } +static void sp_toggle_visible( GtkToggleAction* act, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/visible", active); +} + static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); prefs->setBool("/tools/spray/picker", active); if(active == true){ - prefs->setBool("/tools/spray/visible", false); - GObject *tbl = G_OBJECT(data); - GtkToggleAction *visible = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "visible") ); - gtk_toggle_action_set_active(visible, false); prefs->setBool("/dialogs/clonetiler/dotrace", true); SPDesktop *dt = SP_ACTIVE_DESKTOP; if (Inkscape::UI::Dialog::CloneTiler *ct = get_clone_tiler_panel(dt)){ @@ -190,6 +206,29 @@ static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) ct->show_page_trace(); } } + GObject *tbl = G_OBJECT(data); + sp_stb_sensitivize(tbl); +} + +static void sp_toggle_pickfill( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/pickfill", active); +} + +static void sp_toggle_pickinversescale( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/pickinversescale", active); +} + +static void sp_toggle_pickstroke( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/pickstroke", active); } void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) @@ -385,8 +424,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Picker */ { InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction", - _("Pick down color. Fill must be unset on original when spraying clones"), - _("Pick down color. Fill must be unset on original when spraying clones"), + _("Pick down. Fill or Stroke must be unset on original when spraying color to clones"), + _("Pick down. Fill or Stroke must be unset on original when spraying color to clones"), INKSCAPE_ICON("color-picker"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picker", false) ); @@ -395,6 +434,58 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } + /* Inverse Scale */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayOverPickInverseScaleAction", + _("Apply inversed scale to pick"), + _("Apply inversed scale to pick"), + INKSCAPE_ICON("object-tweak-shrink"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickinversescale", false) ); + g_object_set_data( holder, "pickinversescale", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pickinversescale), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Pick Fill */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayOverPickFillAction", + _("Apply picked color to fill"), + _("Apply picked color to fill"), + INKSCAPE_ICON("paint-solid"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickfill", false) ); + g_object_set_data( holder, "pickfill", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pickfill), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Pick Stroke */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayOverPickStrokeAction", + _("Apply picked color to stroke"), + _("Apply picked color to stroke"), + INKSCAPE_ICON("no-marker"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickstroke", false) ); + g_object_set_data( holder, "pickstroke", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pickstroke), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Visible */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayOverVisibleAction", + _("Apply only over non transparent areas"), + _("Apply only over non transparent areas"), + INKSCAPE_ICON("object-visible"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/visible", false) ); + g_object_set_data( holder, "visible", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_visible), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + /* Overlap */ { InkToggleAction* act = ink_toggle_action_new( "SprayNotOverlapAction", diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 0c72242e0..0188beef0 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -322,6 +322,10 @@ static gchar const * ui_descr = " " " " " " + " " + " " + " " + " " " " " " -- cgit v1.2.3 From be64ba3e07ac16e14712929756739de6b4465fef Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 31 Oct 2015 23:50:21 +0100 Subject: 'End' of picker work (bzr r14422.1.35) --- src/ui/dialog/clonetiler.cpp | 5 ----- src/ui/tools/spray-tool.cpp | 48 +++++++++++++++++++++---------------------- src/ui/tools/spray-tool.h | 4 ++-- src/widgets/spray-toolbar.cpp | 48 +++++++++++++++++++++---------------------- src/widgets/toolbox.cpp | 5 +++-- 5 files changed, 53 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index da6cc5192..e842cf78f 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -785,11 +785,6 @@ CloneTiler::CloneTiler () : #endif gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if(prefs->getBool("/dialogs/clonetiler/opentrace", false)){ - gtk_notebook_set_current_page (GTK_NOTEBOOK(nb),5); - } - b = gtk_check_button_new_with_label (_("Trace the drawing under the tiles/spray tool")); g_object_set_data (G_OBJECT(b), "uncheckable", GINT_TO_POINTER(TRUE)); bool old = prefs->getBool(prefs_path + "dotrace"); diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 0b54d3779..d9a5de377 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -173,9 +173,9 @@ SprayTool::SprayTool() , is_dilating(false) , has_dilated(false) , dilate_area(NULL) - , overlap(false) + , nooverlap(false) , picker(false) - , pickinversescale(false) + , pickinversesize(false) , pickfill(false) , pickstroke(false) , visible(false) @@ -256,11 +256,11 @@ void SprayTool::setup() { sp_event_context_read(this, "Scale"); sp_event_context_read(this, "offset"); sp_event_context_read(this, "picker"); - sp_event_context_read(this, "pickinversescale"); + sp_event_context_read(this, "pickinversesize"); sp_event_context_read(this, "pickfill"); sp_event_context_read(this, "pickstroke"); sp_event_context_read(this, "visible"); - sp_event_context_read(this, "overlap"); + sp_event_context_read(this, "nooverlap"); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/tools/spray/selcue")) { @@ -306,16 +306,16 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) { this->offset = CLAMP(val.getDouble(), -1000.0, 1000.0); } else if (path == "picker") { this->picker = val.getBool(); - } else if (path == "pickinversescale") { - this->pickinversescale = val.getBool(); + } else if (path == "pickinversesize") { + this->pickinversesize = val.getBool(); } else if (path == "pickfill") { this->pickfill = val.getBool(); } else if (path == "pickstroke") { this->pickstroke = val.getBool(); } else if (path == "visible") { this->visible = val.getBool(); - } else if (path == "overlap") { - this->overlap = val.getBool(); + } else if (path == "nooverlap") { + this->nooverlap = val.getBool(); } } @@ -440,11 +440,11 @@ static bool fit_item(SPDesktop *desktop, double &_scale, double scale, bool picker, - bool pickinversescale, + bool pickinversesize, bool pickfill, bool pickstroke, bool visible, - bool overlap, + bool nooverlap, double offset, SPCSSAttr *css, bool trace_scale) @@ -506,7 +506,7 @@ static bool fit_item(SPDesktop *desktop, (item_down->getAttribute("inkscape:spray-origin") && strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 )) { - if(overlap){ + if(nooverlap){ if(!(offset_min < 0 && std::abs(bbox_left - bbox_left_main) > std::abs(offset_min) && std::abs(bbox_top - bbox_top_main) > std::abs(offset_min))){ return false; @@ -520,7 +520,7 @@ static bool fit_item(SPDesktop *desktop, } if(picker || visible){ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if(!overlap){ + if(!nooverlap){ doc->ensureUpToDate(); } int pick = prefs->getInt("/dialogs/clonetiler/pick"); @@ -625,12 +625,12 @@ static bool fit_item(SPDesktop *desktop, rgba = SP_RGBA32_F_COMPOSE(r, g, b, a); if (pick_to_size) { if(!trace_scale){ - if(pickinversescale){ + if(pickinversesize) { _scale = 1.0 - val; } else { _scale = val; } - if _scale == 0.0){ + if(_scale == 0.0) { return false; } if(!fit_item(desktop, @@ -642,11 +642,11 @@ static bool fit_item(SPDesktop *desktop, _scale, scale, picker, - pickinversescale, + pickinversesize, pickfill, pickstroke, visible, - overlap, + nooverlap, offset, css, true)){ @@ -682,7 +682,7 @@ static bool fit_item(SPDesktop *desktop, return false; } } - if(!overlap && (picker || visible)){ + if(!nooverlap && (picker || visible)){ for (std::vector::const_iterator k=items_down.begin(); k!=items_down.end(); k++) { SPItem *item_hidden = *k; item_hidden->setHidden(false); @@ -710,9 +710,9 @@ static bool sp_spray_recursive(SPDesktop *desktop, double tilt, double rotation_variation, gint _distrib, - bool overlap, + bool nooverlap, bool picker, - bool pickinversescale, + bool pickinversesize, bool pickfill, bool pickstroke, bool visible, @@ -756,8 +756,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(overlap || picker || visible){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversescale, pickfill, pickstroke, visible, overlap, offset, css, false)){ + if(nooverlap || picker || visible){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversesize, pickfill, pickstroke, visible, nooverlap, offset, css, false)){ return false; } } @@ -863,8 +863,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(overlap || picker || visible){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversescale, pickfill, pickstroke, visible, overlap, offset, css, false)){ + if(nooverlap || picker || visible){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversesize, pickfill, pickstroke, visible, nooverlap, offset, css, false)){ return false; } } @@ -942,7 +942,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for(std::vector::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, tc->overlap, tc->picker, tc->pickinversescale, tc->pickfill, tc->pickstroke, tc->visible, tc->offset, tc->usepressurescale, get_pressure(tc))) { + 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->nooverlap, tc->picker, tc->pickinversesize, tc->pickfill, tc->pickstroke, tc->visible, tc->offset, tc->usepressurescale, get_pressure(tc))) { did = true; } } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index 89a06dee9..212948c77 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -89,9 +89,9 @@ public: bool has_dilated; Geom::Point last_push; SPCanvasItem *dilate_area; - bool overlap; + bool nooverlap; bool picker; - bool pickinversescale; + bool pickinversesize; bool pickfill; bool pickstroke; bool visible; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index ce37ac9f7..c7013b6a1 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -66,14 +66,14 @@ static void sp_stb_sensitivize( GObject *tbl ) GtkAction* spray_scale = GTK_ACTION( g_object_get_data(tbl, "spray_scale") ); GtkAdjustment *adj_offset = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(offset) ); GtkAdjustment *adj_scale = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(spray_scale) ); - GtkToggleAction *overlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "overlap") ); + GtkToggleAction *nooverlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "nooverlap") ); GtkToggleAction *picker = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "picker") ); GtkToggleAction *usepressurescale = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "usepressurescale") ); GtkAction *pickfill = GTK_ACTION( g_object_get_data(tbl, "pickfill") ); GtkAction *pickstroke = GTK_ACTION( g_object_get_data(tbl, "pickstroke") ); - GtkAction *pickinversescale = GTK_ACTION( g_object_get_data(tbl, "pickinversescale") ); + GtkAction *pickinversesize = GTK_ACTION( g_object_get_data(tbl, "pickinversesize") ); gtk_adjustment_set_value( adj_offset, 100.0 ); - if (gtk_toggle_action_get_active(overlap)) { + if (gtk_toggle_action_get_active(nooverlap)) { gtk_action_set_sensitive( offset, TRUE ); } else { gtk_action_set_sensitive( offset, FALSE ); @@ -87,11 +87,11 @@ static void sp_stb_sensitivize( GObject *tbl ) if(gtk_toggle_action_get_active(picker)){ gtk_action_set_sensitive( pickfill, TRUE ); gtk_action_set_sensitive( pickstroke, TRUE ); - gtk_action_set_sensitive( pickinversescale, TRUE ); + gtk_action_set_sensitive( pickinversesize, TRUE ); } else { gtk_action_set_sensitive( pickfill, FALSE ); gtk_action_set_sensitive( pickstroke, FALSE ); - gtk_action_set_sensitive( pickinversescale, FALSE ); + gtk_action_set_sensitive( pickinversesize, FALSE ); } } @@ -165,11 +165,11 @@ static void sp_spray_offset_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ gtk_adjustment_get_value(adj)); } -static void sp_toggle_not_overlap( GtkToggleAction* act, gpointer data) +static void sp_toggle_nooverlap( GtkToggleAction* act, gpointer data) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/overlap", active); + prefs->setBool("/tools/spray/nooverlap", active); GObject *tbl = G_OBJECT(data); sp_stb_sensitivize(tbl); } @@ -210,21 +210,21 @@ static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) sp_stb_sensitivize(tbl); } -static void sp_toggle_pickfill( GtkToggleAction* act, gpointer data ) +static void sp_toggle_pick_fill( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); prefs->setBool("/tools/spray/pickfill", active); } -static void sp_toggle_pickinversescale( GtkToggleAction* act, gpointer data ) +static void sp_toggle_pick_inverse_size( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/pickinversescale", active); + prefs->setBool("/tools/spray/pickinversesize", active); } -static void sp_toggle_pickstroke( GtkToggleAction* act, gpointer data ) +static void sp_toggle_pick_stroke( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); @@ -434,16 +434,16 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } - /* Inverse Scale */ + /* Inverse Value Size */ { - InkToggleAction* act = ink_toggle_action_new( "SprayOverPickInverseScaleAction", - _("Apply inversed scale to pick"), - _("Apply inversed scale to pick"), + InkToggleAction* act = ink_toggle_action_new( "SprayOverPickInverseSizeAction", + _("Apply inversed to pick value size"), + _("Apply inversed to pick value size"), INKSCAPE_ICON("object-tweak-shrink"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickinversescale", false) ); - g_object_set_data( holder, "pickinversescale", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pickinversescale), holder) ; + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickinversesize", false) ); + g_object_set_data( holder, "pickinversesize", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_inverse_size), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } @@ -456,7 +456,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickfill", false) ); g_object_set_data( holder, "pickfill", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pickfill), holder) ; + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_fill), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } @@ -469,7 +469,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickstroke", false) ); g_object_set_data( holder, "pickstroke", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pickstroke), holder) ; + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_stroke), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } @@ -488,16 +488,16 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Overlap */ { - InkToggleAction* act = ink_toggle_action_new( "SprayNotOverlapAction", + InkToggleAction* act = ink_toggle_action_new( "SprayNoOverlapAction", _("Prevent overlapping objects"), _("Prevent overlapping objects"), INKSCAPE_ICON("distribute-randomize"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overlap", false) ); - g_object_set_data( holder, "overlap", act ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/nooverlap", false) ); + g_object_set_data( holder, "nooverlap", act ); //g_object_set_data (context_object, "holder", holder); //g_object_set_data (context_object, "desktop", desktop); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_not_overlap), holder) ; + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_nooverlap), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 0188beef0..6457b7c7e 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -322,11 +322,12 @@ static gchar const * ui_descr = " " " " " " - " " + " " " " " " + " " " " - " " + " " " " " " -- cgit v1.2.3 From e5ef21e284cd3bd7da7f15fcee7f4d1999457b2e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 1 Nov 2015 00:51:14 +0100 Subject: Order disposition of icons Add inverse also to opacity (bzr r14422.1.37) --- src/ui/tools/spray-tool.cpp | 28 ++++++++++++++++------------ src/ui/tools/spray-tool.h | 2 +- src/widgets/spray-toolbar.cpp | 22 +++++++++++----------- src/widgets/toolbox.cpp | 10 +++++----- 4 files changed, 33 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index d9a5de377..f7762ad8a 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -175,7 +175,7 @@ SprayTool::SprayTool() , dilate_area(NULL) , nooverlap(false) , picker(false) - , pickinversesize(false) + , pickinversevalue(false) , pickfill(false) , pickstroke(false) , visible(false) @@ -256,7 +256,7 @@ void SprayTool::setup() { sp_event_context_read(this, "Scale"); sp_event_context_read(this, "offset"); sp_event_context_read(this, "picker"); - sp_event_context_read(this, "pickinversesize"); + sp_event_context_read(this, "pickinversevalue"); sp_event_context_read(this, "pickfill"); sp_event_context_read(this, "pickstroke"); sp_event_context_read(this, "visible"); @@ -306,8 +306,8 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) { this->offset = CLAMP(val.getDouble(), -1000.0, 1000.0); } else if (path == "picker") { this->picker = val.getBool(); - } else if (path == "pickinversesize") { - this->pickinversesize = val.getBool(); + } else if (path == "pickinversevalue") { + this->pickinversevalue = val.getBool(); } else if (path == "pickfill") { this->pickfill = val.getBool(); } else if (path == "pickstroke") { @@ -440,7 +440,7 @@ static bool fit_item(SPDesktop *desktop, double &_scale, double scale, bool picker, - bool pickinversesize, + bool pickinversevalue, bool pickfill, bool pickstroke, bool visible, @@ -625,7 +625,7 @@ static bool fit_item(SPDesktop *desktop, rgba = SP_RGBA32_F_COMPOSE(r, g, b, a); if (pick_to_size) { if(!trace_scale){ - if(pickinversesize) { + if(pickinversevalue) { _scale = 1.0 - val; } else { _scale = val; @@ -642,7 +642,7 @@ static bool fit_item(SPDesktop *desktop, _scale, scale, picker, - pickinversesize, + pickinversevalue, pickfill, pickstroke, visible, @@ -656,7 +656,11 @@ static bool fit_item(SPDesktop *desktop, } if (pick_to_opacity) { - opacity *= val; + if(pickinversevalue) { + opacity *= 1.0 - val; + } else { + opacity *= val; + } std::stringstream opacity_str; opacity_str.imbue(std::locale::classic()); opacity_str << opacity; @@ -712,7 +716,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, gint _distrib, bool nooverlap, bool picker, - bool pickinversesize, + bool pickinversevalue, bool pickfill, bool pickstroke, bool visible, @@ -757,7 +761,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(nooverlap || picker || visible){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversesize, pickfill, pickstroke, visible, nooverlap, offset, css, false)){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversevalue, pickfill, pickstroke, visible, nooverlap, offset, css, false)){ return false; } } @@ -864,7 +868,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(nooverlap || picker || visible){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversesize, pickfill, pickstroke, visible, nooverlap, offset, css, false)){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversevalue, pickfill, pickstroke, visible, nooverlap, offset, css, false)){ return false; } } @@ -942,7 +946,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for(std::vector::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, tc->nooverlap, tc->picker, tc->pickinversesize, tc->pickfill, tc->pickstroke, tc->visible, tc->offset, tc->usepressurescale, get_pressure(tc))) { + 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->nooverlap, tc->picker, tc->pickinversevalue, tc->pickfill, tc->pickstroke, tc->visible, tc->offset, tc->usepressurescale, get_pressure(tc))) { did = true; } } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index 212948c77..ca0c20375 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -91,7 +91,7 @@ public: SPCanvasItem *dilate_area; bool nooverlap; bool picker; - bool pickinversesize; + bool pickinversevalue; bool pickfill; bool pickstroke; bool visible; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index c7013b6a1..fa9722bdb 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -71,7 +71,7 @@ static void sp_stb_sensitivize( GObject *tbl ) GtkToggleAction *usepressurescale = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "usepressurescale") ); GtkAction *pickfill = GTK_ACTION( g_object_get_data(tbl, "pickfill") ); GtkAction *pickstroke = GTK_ACTION( g_object_get_data(tbl, "pickstroke") ); - GtkAction *pickinversesize = GTK_ACTION( g_object_get_data(tbl, "pickinversesize") ); + GtkAction *pickinversevalue = GTK_ACTION( g_object_get_data(tbl, "pickinversevalue") ); gtk_adjustment_set_value( adj_offset, 100.0 ); if (gtk_toggle_action_get_active(nooverlap)) { gtk_action_set_sensitive( offset, TRUE ); @@ -87,11 +87,11 @@ static void sp_stb_sensitivize( GObject *tbl ) if(gtk_toggle_action_get_active(picker)){ gtk_action_set_sensitive( pickfill, TRUE ); gtk_action_set_sensitive( pickstroke, TRUE ); - gtk_action_set_sensitive( pickinversesize, TRUE ); + gtk_action_set_sensitive( pickinversevalue, TRUE ); } else { gtk_action_set_sensitive( pickfill, FALSE ); gtk_action_set_sensitive( pickstroke, FALSE ); - gtk_action_set_sensitive( pickinversesize, FALSE ); + gtk_action_set_sensitive( pickinversevalue, FALSE ); } } @@ -217,11 +217,11 @@ static void sp_toggle_pick_fill( GtkToggleAction* act, gpointer data ) prefs->setBool("/tools/spray/pickfill", active); } -static void sp_toggle_pick_inverse_size( GtkToggleAction* act, gpointer data ) +static void sp_toggle_pick_inverse_value( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/pickinversesize", active); + prefs->setBool("/tools/spray/pickinversevalue", active); } static void sp_toggle_pick_stroke( GtkToggleAction* act, gpointer data ) @@ -436,14 +436,14 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Inverse Value Size */ { - InkToggleAction* act = ink_toggle_action_new( "SprayOverPickInverseSizeAction", - _("Apply inversed to pick value size"), - _("Apply inversed to pick value size"), + InkToggleAction* act = ink_toggle_action_new( "SprayOverPickInverseValueAction", + _("Inversed pick value retaining color"), + _("Inversed pick value retaining color"), INKSCAPE_ICON("object-tweak-shrink"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickinversesize", false) ); - g_object_set_data( holder, "pickinversesize", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_inverse_size), holder) ; + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickinversevalue", false) ); + g_object_set_data( holder, "pickinversevalue", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_inverse_value), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 6457b7c7e..bab317f16 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -321,14 +321,14 @@ static gchar const * ui_descr = " " " " " " - " " - " " - " " - " " - " " " " " " " " + " " + " " + " " + " " + " " " " -- cgit v1.2.3 From e40c7e81cc683c8c937486c4a53f9758752bbbe6 Mon Sep 17 00:00:00 2001 From: Yuri Chornoivan <> Date: Sun, 1 Nov 2015 13:49:27 +0100 Subject: Typo fix (bzr r14439) --- src/live_effects/lpe-roughen.cpp | 2 +- src/live_effects/lpe-transform_2pts.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index cea91509e..29cfc9839 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -63,7 +63,7 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) "max_smooth_angle", &wr, this, 20), shift_nodes(_("Shift nodes"), _("Shift nodes"), "shift_nodes", &wr, this, true), - fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment lenght"), + fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment length"), "fixed_displacement", &wr, this, false), spray_tool_friendly(_("Spray Tool friendly"), _("For use with spray tool"), "spray_tool_friendly", &wr, this, false) diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 8326bd6f1..f2b756567 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -30,13 +30,13 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : Effect(lpeobject), elastic(_("Elastic"), _("Elastic transform mode"), "elastic", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), from_original_width(_("From original width"), _("From original width"), "from_original_width", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), - lock_lenght(_("Lock lenght"), _("Lock lenght to current distance"), "lock_lenght", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + lock_lenght(_("Lock length"), _("Lock length to current distance"), "lock_lenght", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), lock_angle(_("Lock angle"), _("Lock angle"), "lock_angle", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), flip_horizontal(_("Flip horizontal"), _("Flip horizontal"), "flip_horizontal", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), flip_vertical(_("Flip vertical"), _("Flip vertical"), "flip_vertical", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), start(_("Start"), _("Start point"), "start", &wr, this, "Start point"), end(_("End"), _("End point"), "end", &wr, this, "End point"), - strech(_("Strech"), _("Strech the result"), "strech", &wr, this, 1), + strech(_("Stretch"), _("Stretch the result"), "strech", &wr, this, 1), offset(_("Offset"), _("Offset from knots"), "offset", &wr, this, 0), first_knot(_("First Knot"), _("First Knot"), "first_knot", &wr, this, 1), last_knot(_("Last Knot"), _("Last Knot"), "last_knot", &wr, this, 1), -- cgit v1.2.3 From 326bf4284ba296b71c9584962e2ec232a7a89fb3 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 1 Nov 2015 13:50:42 +0100 Subject: i18n. Strings disambiguation (thanks, Maren!). Translation. Translation template update. Translation. French translation update. (bzr r14440) --- src/ui/dialog/inkscape-preferences.cpp | 4 +- src/ui/dialog/objects.cpp | 10 ++--- src/ui/widget/font-variants.cpp | 70 +++++++++++++++++----------------- src/widgets/tweak-toolbar.cpp | 8 ++-- 4 files changed, 46 insertions(+), 46 deletions(-) (limited to 'src') 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..d72dda028 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -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/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 ), diff --git a/src/widgets/tweak-toolbar.cpp b/src/widgets/tweak-toolbar.cpp index a5d90fc3d..e2c0daf6e 100644 --- a/src/widgets/tweak-toolbar.cpp +++ b/src/widgets/tweak-toolbar.cpp @@ -288,7 +288,7 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj NULL, Inkscape::ICON_SIZE_DECORATION ); //TRANSLATORS: "H" here stands for hue - g_object_set( act, "short_label", _("H"), NULL ); + g_object_set( act, "short_label", C_("Hue", "H"), NULL ); gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doh), desktop ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/doh", true) ); @@ -304,7 +304,7 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj NULL, Inkscape::ICON_SIZE_DECORATION ); //TRANSLATORS: "S" here stands for Saturation - g_object_set( act, "short_label", _("S"), NULL ); + g_object_set( act, "short_label", C_("Saturation", "S"), NULL ); gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dos), desktop ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/dos", true) ); @@ -320,7 +320,7 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj NULL, Inkscape::ICON_SIZE_DECORATION ); //TRANSLATORS: "L" here stands for Lightness - g_object_set( act, "short_label", _("L"), NULL ); + g_object_set( act, "short_label", C_("Lightness", "L"), NULL ); gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dol), desktop ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/dol", true) ); @@ -336,7 +336,7 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj NULL, Inkscape::ICON_SIZE_DECORATION ); //TRANSLATORS: "O" here stands for Opacity - g_object_set( act, "short_label", _("O"), NULL ); + g_object_set( act, "short_label", C_("Opacity", "O"), NULL ); gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doo), desktop ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/doo", true) ); -- cgit v1.2.3 From a555ac58d0b5827d577d61f810e9df668fa55470 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 1 Nov 2015 17:13:04 +0100 Subject: improve apply value to clones in scale mode (bzr r14422.1.38) --- src/ui/tools/spray-tool.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index f7762ad8a..03a225b6e 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -434,7 +434,7 @@ double randomize01(double val, double rand) static bool fit_item(SPDesktop *desktop, SPItem *item, Geom::OptRect bbox, - Geom::Point move, + Geom::Point &move, Geom::Point center, double angle, double &_scale, @@ -457,6 +457,11 @@ static bool fit_item(SPDesktop *desktop, if(offset_min < 0 ){ offset_min = 0; } + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool pick_to_size = prefs->getBool("/dialogs/clonetiler/pick_to_size"); + if(picker && pick_to_size && !trace_scale){ + _scale = 0.1; + } Geom::OptRect bbox_procesed = Geom::Rect(Geom::Point(bbox->left() - offset_min, bbox->top() - offset_min),Geom::Point(bbox->right() + offset_min, bbox->bottom() + offset_min)); Geom::Path path; path.start(Geom::Point(bbox_procesed->left(), bbox_procesed->top())); @@ -467,13 +472,24 @@ static bool fit_item(SPDesktop *desktop, 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[Geom::X], move[Geom::Y]); + path *= Geom::Translate(move); path *= desktop->doc2dt(); bbox_procesed = path.boundsFast(); double bbox_left_main = bbox_procesed->left(); double bbox_top_main = bbox_procesed->top(); 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); + double R = 0, G = 0, B = 0, A = 0; + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); + 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); + guint32 rgba = SP_RGBA32_F_COMPOSE(R, G, B, A); + if(nooverlap && visible && (A==0 || A < 1e-6)){ + return false; + } size = std::min(width_transformed,height_transformed); if(offset < 100 ){ offset_min = ((99.0 - offset) * size)/100.0 - size; @@ -519,12 +535,10 @@ static bool fit_item(SPDesktop *desktop, } } if(picker || visible){ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if(!nooverlap){ doc->ensureUpToDate(); } int pick = prefs->getInt("/dialogs/clonetiler/pick"); - bool pick_to_size = prefs->getBool("/dialogs/clonetiler/pick_to_size"); bool pick_to_presence = prefs->getBool("/dialogs/clonetiler/pick_to_presence", false); bool pick_to_color = prefs->getBool("/dialogs/clonetiler/pick_to_color"); bool pick_to_opacity = prefs->getBool("/dialogs/clonetiler/pick_to_opacity"); @@ -533,20 +547,12 @@ static bool fit_item(SPDesktop *desktop, double gamma_picked = prefs->getDoubleLimited("/dialogs/clonetiler/gamma_picked", 0, -10, 10); double opacity = 1.0; gchar color_string[32]; *color_string = 0; - 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); - double R = 0, G = 0, B = 0, A = 0; - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); - 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); - guint32 rgba = SP_RGBA32_F_COMPOSE(R, G, B, A); 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); //this can fix the bug #1511998 if confirmed - if( a == 0 && r == 0 && g == 0 && b == 0){ + if( a == 0 || a < 1e-6){ r = 1; g = 1; b = 1; -- cgit v1.2.3 From ead60e7c6226f24be5d11b550cea287fe2ddee11 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 3 Nov 2015 11:46:37 +0100 Subject: Vertical baseline depends on block 'text-orientation' value. (bzr r14430.1.2) --- src/libnrtype/Layout-TNG-Compute.cpp | 37 ++++++++++++++++++++++++++++-------- src/libnrtype/Layout-TNG-Input.cpp | 5 +++++ src/libnrtype/Layout-TNG.h | 9 +++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 4201d052c..1fb0e2d8d 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -700,10 +700,20 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ new_glyph.x = current_x + unbroken_span_glyph_info->geometry.x_offset * font_size_multiplier; - new_glyph.y =_y_offset + - unbroken_span.baseline_shift + - (unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier) - + 0.5 * (new_span.line_height.descent - new_span.line_height.ascent); + // Baseline is determined by overall block (i.e. ) 'text-orientation' value. + // (It's actually a bit more complicated but this should handle most cases.) + if( _flow._blockTextOrientation() == SP_CSS_TEXT_ORIENTATION_SIDEWAYS ) { + // Baseline is alphabetic + new_glyph.y =_y_offset + + unbroken_span.baseline_shift + + (unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier); + } else { + // Baseline is center + new_glyph.y =_y_offset + + unbroken_span.baseline_shift + + (unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier) + + 0.5 * (new_span.line_height.descent - new_span.line_height.ascent); + } new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, false); @@ -713,10 +723,21 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ new_glyph.x = current_x + unbroken_span_glyph_info->geometry.x_offset * font_size_multiplier + new_span.line_height.ascent; - new_glyph.y = _y_offset + // Does baseline shift have any meaning here? - unbroken_span.baseline_shift + - (unbroken_span_glyph_info->geometry.y_offset - - unbroken_span_glyph_info->geometry.width * 0.5) * font_size_multiplier; + // Baseline is determined by overall block (i.e. ) 'text-orientation' value. + // (It's actually a bit more complicated but this should handle most cases.) + if( _flow._blockTextOrientation() == SP_CSS_TEXT_ORIENTATION_SIDEWAYS ) { + // Baseline is alphabetic .. sideways + new_glyph.y =_y_offset + + unbroken_span.baseline_shift + + (unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier) - + new_span.line_height.descent; + } else { + // Baseline is center + new_glyph.y = _y_offset + // Does baseline shift have any meaning here? + unbroken_span.baseline_shift + + (unbroken_span_glyph_info->geometry.y_offset - + unbroken_span_glyph_info->geometry.width * 0.5) * font_size_multiplier; + } new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, true); if( new_glyph.width == 0 ) { diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index 77480cebe..d99433adf 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -192,6 +192,11 @@ Layout::Direction Layout::InputStreamTextSource::styleGetBlockProgression() cons return TOP_TO_BOTTOM; } +SPCSSTextOrientation Layout::InputStreamTextSource::styleGetTextOrientation() const +{ + return ((SPCSSTextOrientation)style->text_orientation.computed); +} + static Layout::Alignment text_anchor_to_alignment(unsigned anchor, Layout::Direction para_direction) { switch (anchor) { diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 66cc96d3f..6875fa14a 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -700,6 +700,7 @@ private: PangoFontDescription *styleGetFontDescription() const; font_instance *styleGetFontInstance() const; Direction styleGetBlockProgression() const; + SPCSSTextOrientation styleGetTextOrientation() const; Alignment styleGetAlignment(Direction para_direction, bool try_text_align) const; }; @@ -738,6 +739,14 @@ private: return TOP_TO_BOTTOM; } + /** The overall text-orientation of the whole flow. */ + inline SPCSSTextOrientation _blockTextOrientation() const + { + if(!_input_stream.empty()) + return static_cast(_input_stream.front())->styleGetTextOrientation(); + return SP_CSS_TEXT_ORIENTATION_MIXED; + } + /** so that LEFT_TO_RIGHT == RIGHT_TO_LEFT but != TOP_TO_BOTTOM */ static bool _directions_are_orthogonal(Direction d1, Direction d2); -- cgit v1.2.3 From 83dac189ff21c59be9b4f912e0d0e9690e710a4d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 3 Nov 2015 13:19:36 +0100 Subject: Rearrange code to make handling of baseline clearer. (bzr r14430.1.3) --- src/libnrtype/Layout-TNG-Compute.cpp | 56 +++++++++++++++--------------------- 1 file changed, 23 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 1fb0e2d8d..7cae1eb8a 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -687,9 +687,18 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ else new_glyph.vertical_scale = 1.0; + // Position glyph -------------------- + new_glyph.x = current_x + unbroken_span_glyph_info->geometry.x_offset * font_size_multiplier; + new_glyph.y =_y_offset; + + // y-coordinate is flipped between vertical and horizontal text... delta_y is common offset but applied with opposite sign + double delta_y = unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier + unbroken_span.baseline_shift; + if (_block_progression == LEFT_TO_RIGHT || _block_progression == RIGHT_TO_LEFT) { // Vertical text + new_glyph.y += delta_y; + // TODO: Should also check 'glyph_orientation_vertical' if 'text-orientation' is unset... if( new_span.text_orientation == SP_CSS_TEXT_ORIENTATION_SIDEWAYS || (new_span.text_orientation == SP_CSS_TEXT_ORIENTATION_MIXED && @@ -698,45 +707,26 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ // Sideways orientation (Latin characters, CJK punctuation), 90deg rotation done at output stage. new_glyph.orientation = ORIENTATION_SIDEWAYS; - new_glyph.x = current_x + unbroken_span_glyph_info->geometry.x_offset * font_size_multiplier; - // Baseline is determined by overall block (i.e. ) 'text-orientation' value. - // (It's actually a bit more complicated but this should handle most cases.) - if( _flow._blockTextOrientation() == SP_CSS_TEXT_ORIENTATION_SIDEWAYS ) { - // Baseline is alphabetic - new_glyph.y =_y_offset + - unbroken_span.baseline_shift + - (unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier); - } else { - // Baseline is center - new_glyph.y =_y_offset + - unbroken_span.baseline_shift + - (unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier) + - 0.5 * (new_span.line_height.descent - new_span.line_height.ascent); + if( _flow._blockTextOrientation() != SP_CSS_TEXT_ORIENTATION_SIDEWAYS ) { + // Baseline is center (shift: alphabetic to center) + new_glyph.y += 0.5 * (new_span.line_height.descent - new_span.line_height.ascent); } new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, false); } else { - // Upright orientation - new_glyph.x = current_x + unbroken_span_glyph_info->geometry.x_offset * font_size_multiplier + - new_span.line_height.ascent; + + new_glyph.x += new_span.line_height.ascent; // Baseline is determined by overall block (i.e. ) 'text-orientation' value. - // (It's actually a bit more complicated but this should handle most cases.) if( _flow._blockTextOrientation() == SP_CSS_TEXT_ORIENTATION_SIDEWAYS ) { - // Baseline is alphabetic .. sideways - new_glyph.y =_y_offset + - unbroken_span.baseline_shift + - (unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier) - - new_span.line_height.descent; + // Baseline is alphabetic .. sideways (shift: left edge to alphabetic) + new_glyph.y -= new_span.line_height.descent; } else { - // Baseline is center - new_glyph.y = _y_offset + // Does baseline shift have any meaning here? - unbroken_span.baseline_shift + - (unbroken_span_glyph_info->geometry.y_offset - - unbroken_span_glyph_info->geometry.width * 0.5) * font_size_multiplier; + // Baseline is center (shift: left edge to center) + new_glyph.y -= unbroken_span_glyph_info->geometry.width * 0.5 * font_size_multiplier; } new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, true); @@ -747,15 +737,15 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ } } else { // Horizontal text - new_glyph.x = current_x + unbroken_span_glyph_info->geometry.x_offset * font_size_multiplier; - new_glyph.y = _y_offset - - unbroken_span.baseline_shift + - unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier; + new_glyph.y -= delta_y; + new_glyph.width = unbroken_span_glyph_info->geometry.width * font_size_multiplier; if ((new_glyph.width == 0) && (para.pango_items[unbroken_span.pango_item_index].font)) new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, false); // for some reason pango returns zero width for invalid glyph characters (those empty boxes), so go to freetype for the info } + + if (new_span.direction == RIGHT_TO_LEFT) { // pango wanted to give us glyphs in visual order but we refused, so we need to work // out where the cluster start is ourselves @@ -772,7 +762,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ } new_glyph.x -= cluster_width; } - _flow._glyphs.push_back(new_glyph); + _flow._glyphs.push_back(new_glyph); // create the Layout::Character(s) double advance_width = new_glyph.width; -- cgit v1.2.3 From e90bd3cd9a9bcc57551c4f37c035cf28cd01e30a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 3 Nov 2015 22:46:41 +0100 Subject: Fix a localization problem storing attribute (bzr r14393.1.32) --- src/ui/tools/measure-tool.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index e6f56674a..31977b8b1 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -415,9 +415,11 @@ void MeasureTool::writeMeasurePoint(Geom::Point point, bool is_start) { if(!namedview) { return; } - gchar *str = g_strdup_printf("%f,%f", point[Geom::X], point[Geom::Y]); + 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, str); + namedview->setAttribute (measure_point, meassure_point_str.str().c_str()); g_free(str); } -- cgit v1.2.3 From 01f40289c4b069d0b3d8ad80b4c59c69950dd937 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 3 Nov 2015 23:57:43 +0100 Subject: Fix a bug compiling (bzr r14393.1.34) --- src/ui/tools/measure-tool.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 31977b8b1..06f32ba5c 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -420,7 +420,6 @@ void MeasureTool::writeMeasurePoint(Geom::Point point, bool is_start) { 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()); - g_free(str); } //This function is used to reverse the Measure, I do it in two steps because when move the knot the -- cgit v1.2.3 From 23935ad410a79d6f82e0ce90e5efba32a55cda4c Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Thu, 5 Nov 2015 22:27:44 +0100 Subject: static code analysis (bzr r14446) --- src/live_effects/parameter/originalpatharray.cpp | 10 +++++----- src/ui/clipboard.cpp | 10 +++++----- src/ui/dialog/export.cpp | 6 +++--- src/ui/dialog/font-substitution.cpp | 2 +- src/ui/dialog/glyphs.cpp | 4 ++-- src/ui/dialog/icon-preview.cpp | 2 +- src/ui/dialog/pixelartdialog.cpp | 2 +- src/ui/dialog/polar-arrange-tab.cpp | 2 +- src/ui/dialog/tags.cpp | 4 ++-- src/ui/dialog/text-edit.cpp | 6 +++--- src/ui/dialog/transformation.cpp | 8 ++++---- src/ui/tools/eraser-tool.cpp | 8 ++++---- src/ui/tools/lpe-tool.cpp | 2 +- src/widgets/arc-toolbar.cpp | 8 ++++---- src/widgets/connector-toolbar.cpp | 4 ++-- src/widgets/gradient-toolbar.cpp | 6 +++--- src/widgets/mesh-toolbar.cpp | 4 ++-- src/widgets/rect-toolbar.cpp | 4 ++-- src/widgets/star-toolbar.cpp | 12 ++++++------ src/widgets/stroke-style.cpp | 6 +++--- 20 files changed, 55 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/originalpatharray.cpp b/src/live_effects/parameter/originalpatharray.cpp index 78e061e66..9e03e2c02 100644 --- a/src/live_effects/parameter/originalpatharray.cpp +++ b/src/live_effects/parameter/originalpatharray.cpp @@ -215,7 +215,7 @@ void OriginalPathArrayParam::on_up_button_click() int i = -1; std::vector::iterator piter = _vector.begin(); - for (std::vector::iterator iter = _vector.begin(); iter != _vector.end(); piter = iter, i++, iter++) { + for (std::vector::iterator iter = _vector.begin(); iter != _vector.end(); piter = iter, i++, ++iter) { if (*iter == row[_model->_colObject]) { _vector.erase(iter); _vector.insert(piter, row[_model->_colObject]); @@ -241,7 +241,7 @@ void OriginalPathArrayParam::on_down_button_click() Gtk::TreeModel::Row row = *iter; int i = 0; - for (std::vector::iterator iter = _vector.begin(); iter != _vector.end(); i++, iter++) { + for (std::vector::iterator iter = _vector.begin(); iter != _vector.end(); i++, ++iter) { if (*iter == row[_model->_colObject]) { std::vector::iterator niter = _vector.erase(iter); if (niter != _vector.end()) { @@ -295,7 +295,7 @@ OriginalPathArrayParam::on_link_button_click() Inkscape::SVGOStringStream os; bool foundOne = false; - for (std::vector::const_iterator iter = _vector.begin(); iter != _vector.end(); iter++) { + for (std::vector::const_iterator iter = _vector.begin(); iter != _vector.end(); ++iter) { if (foundOne) { os << "|"; } else { @@ -330,7 +330,7 @@ void OriginalPathArrayParam::unlink(PathAndDirection* to) void OriginalPathArrayParam::remove_link(PathAndDirection* to) { unlink(to); - for (std::vector::iterator iter = _vector.begin(); iter != _vector.end(); iter++) { + for (std::vector::iterator iter = _vector.begin(); iter != _vector.end(); ++iter) { if (*iter == to) { PathAndDirection *w = *iter; _vector.erase(iter); @@ -455,7 +455,7 @@ gchar * OriginalPathArrayParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; bool foundOne = false; - for (std::vector::const_iterator iter = _vector.begin(); iter != _vector.end(); iter++) { + for (std::vector::const_iterator iter = _vector.begin(); iter != _vector.end(); ++iter) { if (foundOne) { os << "|"; } else { 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 itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::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 itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::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 itemlist=selection->itemList(); cloned_elements.clear(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::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 sorted_items; - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++) + for(std::vector::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::const_iterator i=sorted_items.begin();i!=sorted_items.end();i++){ + for(std::vector::const_iterator i=sorted_items.begin();i!=sorted_items.end();++i){ SPItem *item = dynamic_cast(*i); if (item) { Inkscape::XML::Node *obj = item->getRepr(); 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 reprlst = SP_ACTIVE_DESKTOP->getSelection()->reprList(); - for(std::vector::const_iterator i=reprlst.begin(); reprlst.end() != i; i++) { + for(std::vector::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 itemlist=desktop->getSelection()->itemList(); - for(std::vector::const_iterator i = itemlist.begin();i!=itemlist.end() && !interrupted ;i++){ + for(std::vector::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::const_iterator i=reprlst.begin(); reprlst.end() != i; i++) { + for(std::vector::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/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 FontSubstitution::getFontReplacedItems(SPDocument* doc, Gli std::map mapFontStyles; allList = get_all_items(x, doc->getRoot(), desktop, false, false, true, y); - for(std::vector::const_iterator i = allList.begin();i!=allList.end();i++){ + for(std::vector::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 itemlist=targetDesktop->selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin(); itemlist.end() != i; i++) { + for(std::vector::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 itemlist=targetDesktop->selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin(); itemlist.end() != i; i++) { + for(std::vector::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/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 const items = sel->itemList(); - for(std::vector::const_iterator i=items.begin();!target && i!=items.end();i++){ + for(std::vector::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/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 const items = desktop->selection->itemList(); - for(std::vector::const_iterator i=items.begin(); i!=items.end();i++){ + for(std::vector::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..a93cebee8 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::const_iterator i=tmp.begin();i!=tmp.end();i++) + for(std::vector::const_iterator i=tmp.begin();i!=tmp.end();++i) { if(arrangeOnEllipse) { 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 tmp=sel->list(); - for(std::vector::const_iterator i=tmp.begin();i!=tmp.end();i++) + for(std::vector::const_iterator i=tmp.begin();i!=tmp.end();++i) { SPObject *obj = *i; _store->foreach(sigc::bind( 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 items=_desktop->selection->itemList(); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::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 cf53e1441..05cf3a388 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -444,7 +444,7 @@ SPItem *TextEdit::getSelectedTextItem (void) return NULL; std::vector tmp=SP_ACTIVE_DESKTOP->getSelection()->itemList(); - for(std::vector::const_iterator i=tmp.begin();i!=tmp.end();i++) + for(std::vector::const_iterator i=tmp.begin();i!=tmp.end();++i) { if (SP_IS_TEXT(*i) || SP_IS_FLOWTEXT(*i)) return *i; @@ -462,7 +462,7 @@ unsigned TextEdit::getSelectedTextCount (void) unsigned int items = 0; std::vector tmp=SP_ACTIVE_DESKTOP->getSelection()->itemList(); - for(std::vector::const_iterator i=tmp.begin();i!=tmp.end();i++) + for(std::vector::const_iterator i=tmp.begin();i!=tmp.end();++i) { if (SP_IS_TEXT(*i) || SP_IS_FLOWTEXT(*i)) ++items; @@ -572,7 +572,7 @@ void TextEdit::onApply() SPCSSAttr *css = fillTextStyle (); sp_desktop_set_style(desktop, css, true); - for(std::vector::const_iterator i=item_list.begin();i!=item_list.end();i++){ + for(std::vector::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 tmp=selection->itemList(); - for(std::vector::const_iterator i=tmp.begin();i!=tmp.end();i++){ + for(std::vector::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 tmp=selection->itemList(); - for(std::vector::const_iterator i=tmp.begin();i!=tmp.end();i++){ + for(std::vector::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 items=selection->itemList(); - for(std::vector::const_iterator i = items.begin();i!=items.end();i++){ + for(std::vector::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 tmp=selection->itemList(); - for(std::vector::const_iterator i=tmp.begin();i!=tmp.end();i++){ + for(std::vector::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/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::const_iterator i = toWorkOn.begin(); i != toWorkOn.end(); i++){ + for (std::vector::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 nowSel(selection->itemList()); - for (std::vector::const_iterator i2 = nowSel.begin();i2!=nowSel.end();i2++) { + for (std::vector::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 ::const_iterator i = toWorkOn.begin();i!=toWorkOn.end();i++) { + for (std::vector ::const_iterator i = toWorkOn.begin();i!=toWorkOn.end();++i) { sp_object_ref( *i, 0 ); } - for (std::vector::const_iterator i = toWorkOn.begin();i!=toWorkOn.end();i++) { + for (std::vector::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/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 items=selection->itemList(); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::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/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index 71418e238..7b872e8b1 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -98,7 +98,7 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v bool modmade = false; std::vector itemlist=desktop->getSelection()->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_GENERICELLIPSE(item)) { @@ -164,7 +164,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) if ( ege_select_one_action_get_active(act) != 0 ) { std::vector itemlist=desktop->getSelection()->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_GENERICELLIPSE(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -175,7 +175,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) } } else { std::vector itemlist=desktop->getSelection()->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_GENERICELLIPSE(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -265,7 +265,7 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb purge_repr_listener( tbl, tbl ); std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_GENERICELLIPSE(item)) { n_selected++; diff --git a/src/widgets/connector-toolbar.cpp b/src/widgets/connector-toolbar.cpp index 1c99f283d..8cc254bd2 100644 --- a/src/widgets/connector-toolbar.cpp +++ b/src/widgets/connector-toolbar.cpp @@ -98,7 +98,7 @@ static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl bool modmade = false; std::vector itemlist=desktop->getSelection()->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (Inkscape::UI::Tools::cc_item_is_connector(item)) { @@ -145,7 +145,7 @@ static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) bool modmade = false; std::vector itemlist=desktop->getSelection()->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (Inkscape::UI::Tools::cc_item_is_connector(item)) { diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp index 6743dd23a..b24615126 100644 --- a/src/widgets/gradient-toolbar.cpp +++ b/src/widgets/gradient-toolbar.cpp @@ -117,7 +117,7 @@ void gr_apply_gradient(Inkscape::Selection *selection, GrDrag *drag, SPGradient // If no drag or no dragger selected, act on selection std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ gr_apply_gradient_to_item(*i, gr, initialType, initialMode, initialMode); } } @@ -219,7 +219,7 @@ void gr_get_dt_selected_gradient(Inkscape::Selection *selection, SPGradient *&gr SPGradient *gradient = 0; std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i;// get the items gradient, not the getVector() version SPStyle *style = item->style; SPPaintServer *server = 0; @@ -287,7 +287,7 @@ void gr_read_selection( Inkscape::Selection *selection, // If no selected dragger, read desktop selection std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; SPStyle *style = item->style; diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp index bef9129b9..4e0b6d68b 100644 --- a/src/widgets/mesh-toolbar.cpp +++ b/src/widgets/mesh-toolbar.cpp @@ -90,7 +90,7 @@ void ms_read_selection( Inkscape::Selection *selection, ms_type = SP_MESH_TYPE_COONS; std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; SPStyle *style = item->style; @@ -217,7 +217,7 @@ void ms_get_dt_selected_gradient(Inkscape::Selection *selection, SPMesh *&ms_sel SPMesh *gradient = 0; std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i;// get the items gradient, not the getVector() version SPStyle *style = item->style; SPPaintServer *server = 0; diff --git a/src/widgets/rect-toolbar.cpp b/src/widgets/rect-toolbar.cpp index 96ba699dc..bc27d003c 100644 --- a/src/widgets/rect-toolbar.cpp +++ b/src/widgets/rect-toolbar.cpp @@ -107,7 +107,7 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const * bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ if (SP_IS_RECT(*i)) { if (gtk_adjustment_get_value(adj) != 0) { (SP_RECT(*i)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); @@ -244,7 +244,7 @@ static void sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GO purge_repr_listener( tbl, tbl ); std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ if (SP_IS_RECT(*i)) { n_selected++; item = *i; diff --git a/src/widgets/star-toolbar.cpp b/src/widgets/star-toolbar.cpp index 96005d7df..741fd38ad 100644 --- a/src/widgets/star-toolbar.cpp +++ b/src/widgets/star-toolbar.cpp @@ -84,7 +84,7 @@ static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKlu Inkscape::Selection *selection = desktop->getSelection(); std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -129,7 +129,7 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -186,7 +186,7 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d } std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -225,7 +225,7 @@ static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludg Inkscape::Selection *selection = desktop->getSelection(); std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -265,7 +265,7 @@ static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKl Inkscape::Selection *selection = desktop->getSelection(); std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -368,7 +368,7 @@ sp_star_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) purge_repr_listener( tbl, tbl ); std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { n_selected++; diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index d05b3b994..43dffec56 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -480,7 +480,7 @@ void StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, Inkscape::Selection *selection = spw->desktop->getSelection(); std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (!SP_IS_SHAPE(item) || SP_IS_RECT(item)) { // can't set marker to rect, until it's converted to using continue; @@ -981,7 +981,7 @@ StrokeStyle::scaleLine() int ndash; dashSelector->get_dash(&ndash, &dash, &offset); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end();++i){ /* Set stroke width */ double width; if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { @@ -1156,7 +1156,7 @@ StrokeStyle::updateAllMarkers(std::vector const &objects) }; bool all_texts = true; - for(std::vector::const_iterator i=objects.begin();i!=objects.end();i++){ + for(std::vector::const_iterator i=objects.begin();i!=objects.end();++i){ if (!SP_IS_TEXT (*i)) { all_texts = false; break; -- cgit v1.2.3 From 53badc4158169b711d54d68ce112a9b0480776de Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Sat, 7 Nov 2015 00:03:00 +0100 Subject: static code analysis (bzr r14447) --- src/selection-chemistry.cpp | 139 ++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 85b62957c..cdbc6a937 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -284,7 +284,7 @@ void SelectionHelper::fixSelection(SPDesktop *dt) std::vector const selList = selection->itemList(); - for( std::vector::const_reverse_iterator i = selList.rbegin(); i != selList.rend(); i++ ) { + for( std::vector::const_reverse_iterator i = selList.rbegin(); i != selList.rend(); ++i ) { SPItem *item = *i; if( item && !dt->isLayer(item) && @@ -330,7 +330,7 @@ static void sp_selection_copy_impl(std::vector const &items, std::vecto sort(sorted_items.begin(),sorted_items.end(),sp_object_compare_position_bool); // Copy item reprs: - for (std::vector::const_iterator i = sorted_items.begin(); i != sorted_items.end(); i++) { + for (std::vector::const_iterator i = sorted_items.begin(); i != sorted_items.end(); ++i) { SPItem *item = *i; if (item) { sp_selection_copy_one(item->getRepr(), item->i2doc_affine(), clip, xml_doc); @@ -351,7 +351,7 @@ static std::vector sp_selection_paste_impl(SPDocument *doc std::vector copied; // add objects to document - for (std::vector::const_iterator l = clip.begin(); l != clip.end(); l++) { + for (std::vector::const_iterator l = clip.begin(); l != clip.end(); ++l) { Inkscape::XML::Node *repr = *l; Inkscape::XML::Node *copy = repr->duplicate(xml_doc); @@ -378,10 +378,10 @@ static std::vector sp_selection_paste_impl(SPDocument *doc static void sp_selection_delete_impl(std::vector const &items, bool propagate = true, bool propagate_descendants = true) { - for (std::vector::const_iterator i = items.begin(); i != items.end(); i++) { + for (std::vector::const_iterator i = items.begin(); i != items.end(); ++i) { sp_object_ref(*i, NULL); } - for (std::vector::const_iterator i = items.begin(); i != items.end(); i++) { + for (std::vector::const_iterator i = items.begin(); i != items.end(); ++i) { SPItem *item = *i; item->deleteObject(propagate, propagate_descendants); sp_object_unref(item, NULL); @@ -475,7 +475,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone, bool duplicat bool relink_clones = prefs->getBool("/options/relinkclonesonduplicate/value"); const bool fork_livepatheffects = prefs->getBool("/options/forklpeonduplicate/value", true); - for(std::vector::const_iterator i=reprs.begin();i!=reprs.end();i++){ + for(std::vector::const_iterator i=reprs.begin();i!=reprs.end();++i){ Inkscape::XML::Node *old_repr = *i; Inkscape::XML::Node *parent = old_repr->parent(); Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); @@ -483,7 +483,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone, bool duplicat if(! duplicateLayer) parent->appendChild(copy); else - parent->addChild(copy, old_repr); + parent->addChild(copy, old_repr); if (relink_clones) { SPObject *old_obj = doc->getObjectByRepr(old_repr); @@ -547,7 +547,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone, bool duplicat if(!duplicateLayer) selection->setReprList(newsel); else{ - SPObject* new_layer = doc->getObjectByRepr(newsel[0]); + SPObject* new_layer = doc->getObjectByRepr(newsel[0]); gchar* name = g_strdup_printf(_("%s copy"), new_layer->label()); desktop->layer_manager->renameLayer( new_layer, name, TRUE ); g_free(name); @@ -638,7 +638,7 @@ static void sp_edit_select_all_full(SPDesktop *dt, bool force_all_layers, bool i std::vector all_items = sp_item_group_item_list(dynamic_cast(dt->currentLayer())); - for (std::vector::const_reverse_iterator i=all_items.rbegin();i!=all_items.rend();i++) { + for (std::vector::const_reverse_iterator i=all_items.rbegin();i!=all_items.rend();++i) { SPItem *item = *i; if (item && (!onlysensitive || !item->isLocked())) { @@ -655,7 +655,7 @@ static void sp_edit_select_all_full(SPDesktop *dt, bool force_all_layers, bool i break; } case PREFS_SELECTION_LAYER_RECURSIVE: { - std::vector x; + std::vector x; items = get_all_items(x, dt->currentLayer(), dt, onlyvisible, onlysensitive, FALSE, exclude); break; } @@ -698,7 +698,7 @@ static void sp_selection_group_impl(std::vector p, Inkscap gint topmost = p.back()->position(); Inkscape::XML::Node *topmost_parent = p.back()->parent(); - for(std::vector::const_iterator i = p.begin(); i != p.end(); i++){ + for(std::vector::const_iterator i = p.begin(); i != p.end(); ++i){ Inkscape::XML::Node *current = *i; if (current->parent() == topmost_parent) { @@ -802,7 +802,7 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) std::vector old_select = selection->itemList(); std::vector new_select; GSList *groups = NULL; - for (std::vector::const_iterator item = old_select.begin(); item!=old_select.end(); item++) { + for (std::vector::const_iterator item = old_select.begin(); item!=old_select.end(); ++item) { SPItem *obj = *item; if (dynamic_cast(obj)) { groups = g_slist_prepend(groups, obj); @@ -821,7 +821,7 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) // If any of the clones refer to the groups, unlink them and replace them with successors // in the items list. GSList *clones_to_unlink = NULL; - for (std::vector::const_iterator item = items.begin(); item != items.end(); item++) { + for (std::vector::const_iterator item = items.begin(); item != items.end(); ++item) { SPUse *use = dynamic_cast(*item); SPItem *original = use; @@ -847,12 +847,12 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) g_slist_free(clones_to_unlink); // do the actual work - for (std::vector::iterator item = items.begin(); item != items.end(); item++) { + for (std::vector::iterator item = items.begin(); item != items.end(); ++item) { SPItem *obj = *item; // ungroup only the groups marked earlier if (g_slist_find(groups, *item) != NULL) { - std::vector children; + std::vector children; sp_item_group_ungroup(dynamic_cast(obj), children, false); // add the items resulting from ungrouping to the selection new_select.insert(new_select.end(),children.begin(),children.end()); @@ -873,16 +873,16 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) std::vector sp_degroup_list(std::vector &items) { - std::vector out; + std::vector out; bool has_groups = false; - for (std::vector::const_iterator item=items.begin();item!=items.end();item++) { + for (std::vector::const_iterator item=items.begin();item!=items.end();++item) { SPGroup *group = dynamic_cast(*item); if (!group) { out.push_back(*item); } else { has_groups = true; std::vector members = sp_item_group_item_list(group); - for (std::vector::const_iterator member=members.begin();member!=members.end();member++) { + for (std::vector::const_iterator member=members.begin();member!=members.end();++member) { out.push_back(*member); } members.clear(); @@ -899,7 +899,7 @@ sp_degroup_list(std::vector &items) /** If items in the list have a common parent, return it, otherwise return NULL */ static SPGroup * -sp_item_list_common_parent_group(std::vector const items) +sp_item_list_common_parent_group(std::vector const &items) { if (items.empty()) { return NULL; @@ -909,8 +909,8 @@ sp_item_list_common_parent_group(std::vector const items) if (!dynamic_cast(parent)) { return NULL; } - for (std::vector::const_iterator item=items.begin();item!=items.end();item++) { - if((*item)==items[0])continue; + for (std::vector::const_iterator item=items.begin();item!=items.end();++item) { + if((*item)==items[0])continue; if ((*item)->parent != parent) { return NULL; } @@ -926,7 +926,7 @@ enclose_items(std::vector const &items) g_assert(!items.empty()); Geom::OptRect r; - for (std::vector::const_iterator i = items.begin();i!=items.end();i++) { + for (std::vector::const_iterator i = items.begin();i!=items.end();++i) { r.unionWith((*i)->desktopVisualBounds()); } return r; @@ -945,7 +945,7 @@ static SPObject *prev_sibling(SPObject *child) bool sp_item_repr_compare_position_bool(SPObject const *first, SPObject const *second) { return sp_repr_compare_position(((SPItem*)first)->getRepr(), - ((SPItem*)second)->getRepr())<0; + ((SPItem*)second)->getRepr())<0; } void @@ -974,7 +974,7 @@ sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) // Iterate over all objects in the selection (starting from top). if (selected) { - for (std::vector::const_iterator item=rev.begin();item!=rev.end();item++) { + for (std::vector::const_iterator item=rev.begin();item!=rev.end();++item) { SPObject *child = *item; // for each selected object, find the next sibling for (SPObject *newref = child->next; newref; newref = newref->next) { @@ -1019,7 +1019,7 @@ void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *deskto std::vector rl(selection->reprList()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); - for (std::vector::const_iterator l=rl.begin(); l!=rl.end();l++) { + for (std::vector::const_iterator l=rl.begin(); l!=rl.end();++l) { Inkscape::XML::Node *repr =(*l); repr->setPosition(-1); } @@ -1053,7 +1053,7 @@ void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) // Iterate over all objects in the selection (starting from top). if (selected) { - for (std::vector::const_reverse_iterator item=rev.rbegin();item!=rev.rend();item++) { + for (std::vector::const_reverse_iterator item=rev.rbegin();item!=rev.rend();++item) { SPObject *child = *item; // for each selected object, find the prev sibling for (SPObject *newref = prev_sibling(child); newref; newref = prev_sibling(newref)) { @@ -1103,7 +1103,7 @@ void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *des std::vector rl(selection->reprList()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); - for (std::vector::const_reverse_iterator l=rl.rbegin();l!=rl.rend();l++) { + for (std::vector::const_reverse_iterator l=rl.rbegin();l!=rl.rend();++l) { gint minpos; SPObject *pp, *pc; Inkscape::XML::Node *repr = (*l); @@ -1256,7 +1256,7 @@ void sp_selection_remove_livepatheffect(SPDesktop *desktop) return; } std::vector list=selection->itemList(); - for ( std::vector::const_iterator itemlist=list.begin();itemlist!=list.end();itemlist++) { + for ( std::vector::const_iterator itemlist=list.begin();itemlist!=list.end();++itemlist) { SPItem *item = *itemlist; sp_selection_remove_livepatheffect_impl(item); @@ -1313,7 +1313,7 @@ void sp_selection_paste_size_separately(SPDesktop *desktop, bool apply_x, bool a */ void sp_selection_change_layer_maintain_clones(std::vector const &items,SPObject *where) { - for (std::vector::const_iterator i = items.begin(); i != items.end(); i++) { + for (std::vector::const_iterator i = items.begin(); i != items.end(); ++i) { SPItem *item = *i; if (item) { SPItem *oldparent = dynamic_cast(item->parent); @@ -1472,7 +1472,7 @@ selection_contains_both_clone_and_original(Inkscape::Selection *selection) { bool clone_with_original = false; std::vector items = selection->itemList(); - for (std::vector::const_iterator l=items.begin();l!=items.end() ;l++) { + for (std::vector::const_iterator l=items.begin();l!=items.end() ;++l) { SPItem *item = *l; if (item) { clone_with_original |= selection_contains_original(item, selection); @@ -1517,7 +1517,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons persp3d_apply_affine_transformation(transf_persp, affine); } std::vector items = selection->itemList(); - for (std::vector::const_iterator l=items.begin();l!=items.end() ;l++) { + for (std::vector::const_iterator l=items.begin();l!=items.end() ;++l) { SPItem *item = *l; if( dynamic_cast(item) ) { @@ -1688,7 +1688,7 @@ void sp_selection_remove_transform(SPDesktop *desktop) Inkscape::Selection *selection = desktop->getSelection(); std::vector items = selection->reprList(); - for (std::vector::const_iterator l=items.begin();l!=items.end() ;l++) { + for (std::vector::const_iterator l=items.begin();l!=items.end() ;++l) { (*l)->setAttribute("transform", NULL, false); } @@ -1789,7 +1789,7 @@ void sp_selection_rotate_90(SPDesktop *desktop, bool ccw) std::vector items = selection->itemList(); Geom::Rotate const rot_90(Geom::Point(0, ccw ? 1 : -1)); // pos. or neg. rotation, depending on the value of ccw - for (std::vector::const_iterator l=items.begin();l!=items.end() ;l++) { + for (std::vector::const_iterator l=items.begin();l!=items.end() ;++l) { SPItem *item = *l; if (item) { sp_item_rotate_rel(item, rot_90); @@ -1854,14 +1854,14 @@ void sp_select_same_fill_stroke_style(SPDesktop *desktop, gboolean fill, gboolea std::vector items = selection->itemList(); std::vector tmp; - for (std::vector::const_iterator iter=all_list.begin();iter!=all_list.end();iter++) { + for (std::vector::const_iterator iter=all_list.begin();iter!=all_list.end();++iter) { if(!SP_IS_GROUP(*iter)){ tmp.push_back(*iter); } } all_list=tmp; - for (std::vector::const_iterator sel_iter=items.begin();sel_iter!=items.end();sel_iter++) { + for (std::vector::const_iterator sel_iter=items.begin();sel_iter!=items.end();++sel_iter) { SPItem *sel = *sel_iter; std::vector matches = all_list; if (fill && stroke && style) { @@ -1909,7 +1909,7 @@ void sp_select_same_object_type(SPDesktop *desktop) Inkscape::Selection *selection = desktop->getSelection(); std::vector items=selection->itemList(); - for (std::vector::const_iterator sel_iter=items.begin();sel_iter!=items.end();sel_iter++) { + for (std::vector::const_iterator sel_iter=items.begin();sel_iter!=items.end();++sel_iter) { SPItem *sel = *sel_iter; if (sel) { matches = sp_get_same_object_type(sel, matches); @@ -1936,7 +1936,7 @@ std::vector sp_get_same_fill_or_stroke_color(SPItem *sel, std::vectorstyle->fill) : &(sel->style->stroke); - for (std::vector::const_reverse_iterator i=src.rbegin();i!=src.rend();i++) { + for (std::vector::const_reverse_iterator i=src.rbegin();i!=src.rend();++i) { SPItem *iter = *i; if (iter) { SPIPaint *iter_paint = (type == SP_FILL_COLOR) ? &(iter->style->fill) : &(iter->style->stroke); @@ -2031,7 +2031,7 @@ std::vector sp_get_same_object_type(SPItem *sel, std::vector & { std::vector matches; - for (std::vector::const_reverse_iterator i=src.rbegin();i!=src.rend();i++) { + for (std::vector::const_reverse_iterator i=src.rbegin();i!=src.rend();++i) { SPItem *item = *i; if (item && item_type_match(sel, item) && !item->cloned) { matches.push_back(item); @@ -2072,7 +2072,7 @@ std::vector sp_get_same_style(SPItem *sel, std::vector &src, S objects_query_strokewidth (objects, sel_style_for_width); } bool match_g; - for (std::vector::const_iterator i=src.begin();i!=src.end();i++) { + for (std::vector::const_iterator i=src.begin();i!=src.end();++i) { SPItem *iter = *i; if (iter) { match_g=true; @@ -2112,7 +2112,7 @@ std::vector sp_get_same_style(SPItem *sel, std::vector &src, S } } } - match_g = match_g && match; + match_g = match_g && match; if (match_g) { while (iter->cloned) iter=dynamic_cast(iter->parent); matches.insert(matches.begin(),iter); @@ -2371,11 +2371,11 @@ SPItem *next_item(SPDesktop *desktop, GSList *path, SPObject *root, template -SPItem *next_item_from_list(SPDesktop *desktop, std::vector const items, +SPItem *next_item_from_list(SPDesktop *desktop, std::vector const &items, SPObject *root, bool only_in_viewport, PrefsSelectionContext inlayer, bool onlyvisible, bool onlysensitive) { SPObject *current=root; - for(std::vector::const_iterator i = items.begin();i!=items.end();i++) { + for(std::vector::const_iterator i = items.begin();i!=items.end();++i) { SPItem *item = *i; if ( root->isAncestorOf(item) && ( !only_in_viewport || desktop->isWithinViewport(item) ) ) @@ -2577,8 +2577,8 @@ void sp_selection_clone(SPDesktop *desktop) std::vector newsel; - for(std::vector::const_iterator i=reprs.begin();i!=reprs.end();i++){ - Inkscape::XML::Node *sel_repr = *i; + for(std::vector::const_iterator i=reprs.begin();i!=reprs.end();++i){ + Inkscape::XML::Node *sel_repr = *i; Inkscape::XML::Node *parent = sel_repr->parent(); Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); @@ -2628,7 +2628,7 @@ sp_selection_relink(SPDesktop *desktop) // Get a copy of current selection. bool relinked = false; std::vector items=selection->itemList(); - for (std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ SPItem *item = *i; if (dynamic_cast(item)) { @@ -2666,7 +2666,7 @@ sp_selection_unlink(SPDesktop *desktop) std::vector new_select; bool unlinked = false; std::vector items=selection->itemList(); - for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();i++){ + for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();++i){ SPItem *item = *i; if (dynamic_cast(item)) { @@ -2831,7 +2831,7 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) Inkscape::SVGOStringStream os; SPObject * firstItem = NULL; std::vector items=selection->itemList(); - for (std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ if (SP_IS_SHAPE(*i) || SP_IS_TEXT(*i)) { if (firstItem) { os << "|"; @@ -2934,7 +2934,7 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply) // Create a list of duplicates, to be pasted inside marker element. std::vector repr_copies; - for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();i++){ + for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();++i){ Inkscape::XML::Node *dup = (*i)->getRepr()->duplicate(xml_doc); repr_copies.push_back(dup); } @@ -2944,7 +2944,7 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply) if (apply) { // Delete objects so that their clones don't get alerted; // the objects will be restored inside the marker element. - for (std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ SPObject *item = *i; item->deleteObject(false); } @@ -2973,7 +2973,7 @@ static void sp_selection_to_guides_recursive(SPItem *item, bool wholegroups) { SPGroup *group = dynamic_cast(item); if (group && !dynamic_cast(item) && !wholegroups) { std::vector items=sp_item_group_item_list(group); - for (std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ sp_selection_to_guides_recursive(*i, wholegroups); } } else { @@ -3004,7 +3004,7 @@ void sp_selection_to_guides(SPDesktop *desktop) // and its entry in the selection list is invalid (crash). // Therefore: first convert all, then delete all. - for (std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ sp_selection_to_guides_recursive(*i, wholegroups); } @@ -3122,7 +3122,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) } // Move selected items to new - for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();i++){ + for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();++i){ Inkscape::XML::Node *repr = (*i)->getRepr(); repr->parent()->removeChild(repr); symbol_repr->addChild(repr,NULL); @@ -3206,7 +3206,7 @@ void sp_selection_unsymbol(SPDesktop *desktop) } } - for (std::vector::const_reverse_iterator i=children.rbegin();i!=children.rend();i++){ + for (std::vector::const_reverse_iterator i=children.rbegin();i!=children.rend();++i){ Inkscape::XML::Node *repr = (*i)->getRepr(); repr->parent()->removeChild(repr); group->addChild(repr,NULL); @@ -3290,7 +3290,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply) // create a list of duplicates std::vector repr_copies; - for (std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ Inkscape::XML::Node *dup = (*i)->getRepr()->duplicate(xml_doc); repr_copies.push_back(dup); } @@ -3299,7 +3299,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply) if (apply) { // delete objects so that their clones don't get alerted; this object will be restored shortly - for (std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ SPObject *item = *i; item->deleteObject(false); } @@ -3373,7 +3373,7 @@ void sp_selection_untile(SPDesktop *desktop) bool did = false; std::vector items(selection->itemList()); - for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();i++){ + for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();++i){ SPItem *item = *i; SPStyle *style = item->style; @@ -3442,7 +3442,7 @@ void sp_selection_get_export_hints(Inkscape::Selection *selection, Glib::ustring bool xdpi_search = TRUE; bool ydpi_search = TRUE; - for (std::vector::const_iterator i=reprlst.begin();filename_search&&xdpi_search&&ydpi_search&&i!=reprlst.end();i++){ + for (std::vector::const_iterator i=reprlst.begin();filename_search&&xdpi_search&&ydpi_search&&i!=reprlst.end();++i){ gchar const *dpi_string; Inkscape::XML::Node *repr = *i; @@ -3493,7 +3493,6 @@ void sp_document_get_export_hints(SPDocument *doc, Glib::ustring &filename, floa *xdpi = atof(dpi_string); } - dpi_string = NULL; dpi_string = repr->attribute("inkscape:export-ydpi"); if (dpi_string != NULL) { *ydpi = atof(dpi_string); @@ -3743,8 +3742,8 @@ void sp_selection_set_clipgroup(SPDesktop *desktop) Inkscape::XML::Node *inner = xml_doc->createElement("svg:g"); inner->setAttribute("inkscape:label", "Clip"); - for(std::vector::const_iterator i=p.begin();i!=p.end();i++){ - Inkscape::XML::Node *current = *i; + for(std::vector::const_iterator i=p.begin();i!=p.end();++i){ + Inkscape::XML::Node *current = *i; if (current->parent() == topmost_parent) { Inkscape::XML::Node *spnew = current->duplicate(xml_doc); @@ -3879,12 +3878,12 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ apply_to_items.push_back(SP_ITEM(desktop->currentLayer())); } - for (std::vector::const_iterator i=items.begin();i!=items.end();i++) { + for (std::vector::const_iterator i=items.begin();i!=items.end();++i) { if((!topmost && !apply_to_layer && *i == items.front()) || (topmost && !apply_to_layer && *i == items.back()) - || apply_to_layer){ + || apply_to_layer){ - Geom::Affine oldtr=(*i)->transform; + Geom::Affine oldtr=(*i)->transform; (*i)->doWriteTransform((*i)->getRepr(), (*i)->i2doc_affine()); Inkscape::XML::Node *dup = (*i)->getRepr()->duplicate(xml_doc); (*i)->doWriteTransform((*i)->getRepr(), oldtr); @@ -3896,7 +3895,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ else { items_to_select.push_back(*i); } - continue; + continue; }else{ apply_to_items.push_back(*i); items_to_select.push_back(*i); @@ -3914,7 +3913,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ group->setAttribute("inkscape:groupmode", "maskhelper"); std::vector reprs_to_group; - for (std::vector::const_iterator i = apply_to_items.begin(); i != apply_to_items.end(); i++) { + for (std::vector::const_iterator i = apply_to_items.begin(); i != apply_to_items.end(); ++i) { reprs_to_group.push_back(static_cast(*i)->getRepr()); } items_to_select.clear(); @@ -3935,13 +3934,13 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ gchar const *attributeName = apply_clip_path ? "clip-path" : "mask"; - for (std::vector::const_reverse_iterator i = apply_to_items.rbegin(); i != apply_to_items.rend(); i++) { + for (std::vector::const_reverse_iterator i = apply_to_items.rbegin(); i != apply_to_items.rend(); ++i) { SPItem *item = reinterpret_cast(*i); // inverted object transform should be applied to a mask object, // as mask is calculated in user space (after applying transform) std::vector mask_items_dup; - for(std::vector::const_iterator it=mask_items.begin();it!=mask_items.end();it++) - mask_items_dup.push_back((*it)->duplicate(xml_doc)); + for(std::vector::const_iterator it=mask_items.begin();it!=mask_items.end();++it) + mask_items_dup.push_back((*it)->duplicate(xml_doc)); Inkscape::XML::Node *current = SP_OBJECT(*i)->getRepr(); // Node to apply mask to Inkscape::XML::Node *apply_mask_to = current; @@ -3980,7 +3979,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ } - for (std::vector::const_iterator i = items_to_delete.begin(); i != items_to_delete.end(); i++) { + for (std::vector::const_iterator i = items_to_delete.begin(); i != items_to_delete.end(); ++i) { SPObject *item = reinterpret_cast(*i); item->deleteObject(false); items_to_select.erase(remove(items_to_select.begin(), items_to_select.end(), item), items_to_select.end()); @@ -4027,7 +4026,7 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { // SPObject* refers to a group containing the clipped path or mask itself, // whereas SPItem* refers to the item being clipped or masked - for (std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ if (remove_original) { // remember referenced mask/clippath, so orphaned masks can be moved back to document SPItem *item = *i; -- cgit v1.2.3 From ce318a442bc1c9fb4381e1b9ad11effb1314f9b7 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Sat, 7 Nov 2015 00:03:53 +0100 Subject: static code analysis (bzr r14448) --- src/box3d.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/box3d.cpp b/src/box3d.cpp index dc04a2eb6..c4c2728e4 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -50,6 +50,11 @@ SPBox3D::SPBox3D() : SPGroup() { this->persp_href = NULL; this->persp_ref = new Persp3DReference(this); + + /* we initialize the z-orders to zero so that they are updated during dragging */ + for (int i = 0; i < 6; ++i) { + z_orders[i] = 0; + } } SPBox3D::~SPBox3D() { @@ -902,7 +907,7 @@ box3d_swap_sides(int z_orders[6], Box3D::Axis axis) { } } - if (pos1 != -1){ + if ((pos1 != -1) && (pos2 != -1)){ int tmp = z_orders[pos1]; z_orders[pos1] = z_orders[pos2]; z_orders[pos2] = tmp; -- cgit v1.2.3 From 23f5e12afb04c9e029a69fcd77e9857d056e3a6a Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 7 Nov 2015 16:09:43 +0000 Subject: Rebase on upstream libcroco 0.6.9 and backport minor fixes (bzr r14449) --- src/libcroco/cr-additional-sel.c | 16 ++--- src/libcroco/cr-attr-sel.c | 8 +-- src/libcroco/cr-cascade.c | 2 +- src/libcroco/cr-declaration.c | 26 ++++---- src/libcroco/cr-enc-handler.c | 2 +- src/libcroco/cr-fonts.c | 12 ++-- src/libcroco/cr-input.c | 2 +- src/libcroco/cr-num.c | 4 +- src/libcroco/cr-om-parser.c | 61 +++++++++++------- src/libcroco/cr-parser.c | 40 ++++++------ src/libcroco/cr-pseudo.c | 12 ++-- src/libcroco/cr-rgb.c | 13 ++-- src/libcroco/cr-sel-eng.c | 40 ++++++------ src/libcroco/cr-sel-eng.h | 6 +- src/libcroco/cr-selector.c | 15 +++-- src/libcroco/cr-simple-sel.c | 22 ++++--- src/libcroco/cr-statement.c | 131 +++++++++++++++++++++------------------ src/libcroco/cr-string.c | 15 +++-- src/libcroco/cr-style.c | 60 +++++++++--------- src/libcroco/cr-stylesheet.c | 4 +- src/libcroco/cr-term.c | 71 ++++++++++----------- src/libcroco/cr-tknzr.c | 20 +++--- src/libcroco/cr-token.c | 4 +- src/libcroco/cr-utils.c | 26 ++------ 24 files changed, 326 insertions(+), 286 deletions(-) (limited to 'src') diff --git a/src/libcroco/cr-additional-sel.c b/src/libcroco/cr-additional-sel.c index 5a37eba6c..c34b8d243 100644 --- a/src/libcroco/cr-additional-sel.c +++ b/src/libcroco/cr-additional-sel.c @@ -247,7 +247,7 @@ cr_additional_sel_to_string (CRAdditionalSel const * a_this) guchar *name = NULL; if (cur->content.class_name) { - name = g_strndup + name = (guchar *) g_strndup (cur->content.class_name->stryng->str, cur->content.class_name->stryng->len); @@ -266,8 +266,8 @@ cr_additional_sel_to_string (CRAdditionalSel const * a_this) { guchar *name = NULL; - if (cur->content.class_name) { - name = g_strndup + if (cur->content.id_name) { + name = (guchar *) g_strndup (cur->content.id_name->stryng->str, cur->content.id_name->stryng->len); @@ -323,7 +323,7 @@ cr_additional_sel_to_string (CRAdditionalSel const * a_this) } if (str_buf) { - result = str_buf->str; + result = (guchar *) str_buf->str; g_string_free (str_buf, FALSE); str_buf = NULL; } @@ -347,7 +347,7 @@ cr_additional_sel_one_to_string (CRAdditionalSel const *a_this) guchar *name = NULL; if (a_this->content.class_name) { - name = g_strndup + name = (guchar *) g_strndup (a_this->content.class_name->stryng->str, a_this->content.class_name->stryng->len); @@ -366,8 +366,8 @@ cr_additional_sel_one_to_string (CRAdditionalSel const *a_this) { guchar *name = NULL; - if (a_this->content.class_name) { - name = g_strndup + if (a_this->content.id_name) { + name = (guchar *) g_strndup (a_this->content.id_name->stryng->str, a_this->content.id_name->stryng->len); @@ -422,7 +422,7 @@ cr_additional_sel_one_to_string (CRAdditionalSel const *a_this) } if (str_buf) { - result = str_buf->str; + result = (guchar *) str_buf->str; g_string_free (str_buf, FALSE); str_buf = NULL; } diff --git a/src/libcroco/cr-attr-sel.c b/src/libcroco/cr-attr-sel.c index 7976ff1f8..31d9da579 100644 --- a/src/libcroco/cr-attr-sel.c +++ b/src/libcroco/cr-attr-sel.c @@ -123,10 +123,10 @@ cr_attr_sel_to_string (CRAttrSel const * a_this) if (cur->name) { guchar *name = NULL; - name = g_strndup (cur->name->stryng->str, + name = (guchar *) g_strndup (cur->name->stryng->str, cur->name->stryng->len); if (name) { - g_string_append (str_buf, name); + g_string_append (str_buf, (const gchar *) name); g_free (name); name = NULL; } @@ -135,7 +135,7 @@ cr_attr_sel_to_string (CRAttrSel const * a_this) if (cur->value) { guchar *value = NULL; - value = g_strndup (cur->value->stryng->str, + value = (guchar *) g_strndup (cur->value->stryng->str, cur->value->stryng->len); if (value) { switch (cur->match_way) { @@ -168,7 +168,7 @@ cr_attr_sel_to_string (CRAttrSel const * a_this) } if (str_buf) { - result = str_buf->str; + result = (guchar *) str_buf->str; g_string_free (str_buf, FALSE); } diff --git a/src/libcroco/cr-cascade.c b/src/libcroco/cr-cascade.c index 31e938bb7..9f8dbdf8d 100644 --- a/src/libcroco/cr-cascade.c +++ b/src/libcroco/cr-cascade.c @@ -75,8 +75,8 @@ cr_cascade_new (CRStyleSheet * a_author_sheet, PRIVATE (result) = g_try_malloc (sizeof (CRCascadePriv)); if (!PRIVATE (result)) { - g_free(result); cr_utils_trace_info ("Out of memory"); + g_free (result); return NULL; } memset (PRIVATE (result), 0, sizeof (CRCascadePriv)); diff --git a/src/libcroco/cr-declaration.c b/src/libcroco/cr-declaration.c index ab150a9e4..69c24b376 100644 --- a/src/libcroco/cr-declaration.c +++ b/src/libcroco/cr-declaration.c @@ -48,7 +48,7 @@ dump (CRDeclaration const * a_this, FILE * a_fp, glong a_indent) g_return_if_fail (a_this); - str = cr_declaration_to_string (a_this, a_indent); + str = (guchar *) cr_declaration_to_string (a_this, a_indent); if (str) { fprintf (a_fp, "%s", str); g_free (str); @@ -130,7 +130,7 @@ cr_declaration_parse_from_buf (CRStatement * a_statement, g_return_val_if_fail (a_statement->type == RULESET_STMT, NULL); - parser = cr_parser_new_from_buf ((guchar*)a_str, strlen (a_str), a_enc, FALSE); + parser = cr_parser_new_from_buf ((guchar*)a_str, strlen ((const char *) a_str), a_enc, FALSE); g_return_val_if_fail (parser, NULL); status = cr_parser_try_to_skip_spaces_and_comments (parser); @@ -194,7 +194,7 @@ cr_declaration_parse_list_from_buf (const guchar * a_str, g_return_val_if_fail (a_str, NULL); - parser = cr_parser_new_from_buf ((guchar*)a_str, strlen (a_str), a_enc, FALSE); + parser = cr_parser_new_from_buf ((guchar*)a_str, strlen ((const char *) a_str), a_enc, FALSE); g_return_val_if_fail (parser, NULL); status = cr_parser_get_tknzr (parser, &tokenizer); if (status != CR_OK || !tokenizer) { @@ -243,10 +243,10 @@ cr_declaration_parse_list_from_buf (const guchar * a_str, if (status != CR_OK || !property) { if (status == CR_END_OF_INPUT_ERROR) { status = CR_OK; // simply the end of input, do not delete what we got so far, just finish - break; + break; } else { continue; // even if one declaration is broken, it's no reason to discard others (see http://www.w3.org/TR/CSS21/syndata.html#declaration) - } + } } cur_decl = cr_declaration_new (NULL, property, value); if (cur_decl) { @@ -504,7 +504,7 @@ cr_declaration_to_string (CRDeclaration const * a_this, gulong a_indent) { GString *stringue = NULL; - guchar *str = NULL, + gchar *str = NULL, *result = NULL; g_return_val_if_fail (a_this, NULL); @@ -581,7 +581,7 @@ cr_declaration_list_to_string (CRDeclaration const * a_this, gulong a_indent) stringue = g_string_new (NULL); for (cur = a_this; cur; cur = cur->next) { - str = cr_declaration_to_string (cur, a_indent); + str = (guchar *) cr_declaration_to_string (cur, a_indent); if (str) { g_string_append_printf (stringue, "%s;", str); g_free (str); @@ -589,7 +589,7 @@ cr_declaration_list_to_string (CRDeclaration const * a_this, gulong a_indent) break; } if (stringue && stringue->str) { - result = stringue->str; + result = (guchar *) stringue->str; g_string_free (stringue, FALSE); } @@ -620,7 +620,7 @@ cr_declaration_list_to_string2 (CRDeclaration const * a_this, stringue = g_string_new (NULL); for (cur = a_this; cur; cur = cur->next) { - str = cr_declaration_to_string (cur, a_indent); + str = (guchar *) cr_declaration_to_string (cur, a_indent); if (str) { if (a_one_decl_per_line == TRUE) { if (cur->next) @@ -628,21 +628,21 @@ cr_declaration_list_to_string2 (CRDeclaration const * a_this, "%s;\n", str); else g_string_append (stringue, - str); + (const gchar *) str); } else { if (cur->next) g_string_append_printf (stringue, "%s;", str); else g_string_append (stringue, - str); + (const gchar *) str); } g_free (str); } else break; } if (stringue && stringue->str) { - result = stringue->str; + result = (guchar *) stringue->str; g_string_free (stringue, FALSE); } @@ -714,7 +714,7 @@ cr_declaration_get_by_prop_name (CRDeclaration * a_this, && cur->property->stryng && cur->property->stryng->str) { if (!strcmp (cur->property->stryng->str, - a_prop)) { + (const char *) a_prop)) { return cur; } } diff --git a/src/libcroco/cr-enc-handler.c b/src/libcroco/cr-enc-handler.c index b3e5b7eba..646bf1fe2 100644 --- a/src/libcroco/cr-enc-handler.c +++ b/src/libcroco/cr-enc-handler.c @@ -122,7 +122,7 @@ cr_enc_handler_resolve_enc_alias (const guchar * a_alias_name, g_ascii_strup (alias_name_up, -1); for (i = 0; gv_default_aliases[i].name; i++) { - if (!strcmp (gv_default_aliases[i].name, alias_name_up)) { + if (!strcmp (gv_default_aliases[i].name, (const gchar *) alias_name_up)) { *a_enc = gv_default_aliases[i].encoding; status = CR_OK; break; diff --git a/src/libcroco/cr-fonts.c b/src/libcroco/cr-fonts.c index 10f26c99c..78e261149 100644 --- a/src/libcroco/cr-fonts.c +++ b/src/libcroco/cr-fonts.c @@ -78,7 +78,7 @@ cr_font_family_to_string_real (CRFontFamily const * a_this, if (a_this->prev) { g_string_append_printf (*a_string, ", %s", name); } else { - g_string_append (*a_string, name); + g_string_append (*a_string, (const gchar *) name); } } if (a_walk_list == TRUE && a_this->next) { @@ -187,7 +187,7 @@ cr_font_family_to_string (CRFontFamily const * a_this, GString *stringue = NULL; if (!a_this) { - result = g_strdup ("NULL"); + result = (guchar *) g_strdup ("NULL"); g_return_val_if_fail (result, NULL); return result; } @@ -196,7 +196,7 @@ cr_font_family_to_string (CRFontFamily const * a_this, &stringue); if (status == CR_OK && stringue) { - result = stringue->str; + result = (guchar *) stringue->str; g_string_free (stringue, FALSE); stringue = NULL; @@ -420,7 +420,7 @@ cr_font_size_set_predefined_absolute_font_size (CRFontSize *a_this, enum CRPredefinedAbsoluteFontSize a_predefined) { g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; - g_return_val_if_fail ((unsigned)a_predefined < NB_FONT_SIZE_TYPE, + g_return_val_if_fail ((unsigned)a_predefined < NB_PREDEFINED_ABSOLUTE_FONT_SIZES, CR_BAD_PARAM_ERROR) ; a_this->type = PREDEFINED_ABSOLUTE_FONT_SIZE ; @@ -526,7 +526,7 @@ cr_font_size_to_string (CRFontSize const * a_this) (a_this->value.predefined)); break; case ABSOLUTE_FONT_SIZE: - str = cr_num_to_string (&a_this->value.absolute); + str = (gchar *) cr_num_to_string (&a_this->value.absolute); break; case RELATIVE_FONT_SIZE: str = g_strdup (cr_relative_font_size_to_string @@ -683,7 +683,7 @@ cr_font_size_adjust_to_string (CRFontSizeAdjust const * a_this) break; case FONT_SIZE_ADJUST_NUMBER: if (a_this->num) - str = cr_num_to_string (a_this->num); + str = (gchar *) cr_num_to_string (a_this->num); else str = g_strdup ("unknow font-size-adjust property value"); /* Should raise an error no?*/ break; diff --git a/src/libcroco/cr-input.c b/src/libcroco/cr-input.c index 3cc283e01..5395ae214 100644 --- a/src/libcroco/cr-input.c +++ b/src/libcroco/cr-input.c @@ -746,7 +746,7 @@ enum CRStatus cr_input_peek_char (CRInput const * a_this, guint32 * a_char) { enum CRStatus status = CR_OK; - glong consumed = 0, + gulong consumed = 0, nb_bytes_left = 0; g_return_val_if_fail (a_this && PRIVATE (a_this) diff --git a/src/libcroco/cr-num.c b/src/libcroco/cr-num.c index a5c320bf2..6cc5150a1 100644 --- a/src/libcroco/cr-num.c +++ b/src/libcroco/cr-num.c @@ -105,7 +105,7 @@ cr_num_to_string (CRNum const * a_this) test_val = a_this->val - (glong) a_this->val; if (!test_val) { - tmp_char1 = g_strdup_printf ("%ld", (glong) a_this->val); + tmp_char1 = (guchar *) g_strdup_printf ("%ld", (glong) a_this->val); } else { /* We can't use g_ascii_dtostr, because that sometimes uses e notation (which wouldn't be a valid number in CSS). */ @@ -195,7 +195,7 @@ cr_num_to_string (CRNum const * a_this) } if (tmp_char2) { - result = g_strconcat (tmp_char1, tmp_char2, NULL); + result = (guchar *) g_strconcat ((gchar *) tmp_char1, tmp_char2, NULL); g_free (tmp_char1); } else { result = tmp_char1; diff --git a/src/libcroco/cr-om-parser.c b/src/libcroco/cr-om-parser.c index c1acb855c..596cd6e6b 100644 --- a/src/libcroco/cr-om-parser.c +++ b/src/libcroco/cr-om-parser.c @@ -39,9 +39,6 @@ struct _CROMParserPriv { #define PRIVATE(a_this) ((a_this)->priv) -// Unfortunately, C does not allow unnamed function arguments, so use this macro instead... -#define UNUSED(x) (void)(x) - /* *Forward declaration of a type defined later *in this file. @@ -210,12 +207,12 @@ static void start_font_face (CRDocHandler * a_this, CRParsingLocation *a_location) { - UNUSED(a_location); - enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; + (void) a_location; + g_return_if_fail (a_this); g_return_if_fail (a_this); @@ -307,8 +304,6 @@ static void charset (CRDocHandler * a_this, CRString * a_charset, CRParsingLocation *a_location) { - UNUSED(a_location); - enum CRStatus status = CR_OK; CRStatement *stmt = NULL, *stmt2 = NULL; @@ -317,6 +312,8 @@ charset (CRDocHandler * a_this, CRString * a_charset, ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; + (void) a_location; + g_return_if_fail (a_this); ctxtptr = &ctxt; status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); @@ -347,12 +344,12 @@ start_page (CRDocHandler * a_this, CRString * a_pseudo, CRParsingLocation *a_location) { - UNUSED(a_location); - enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; + (void) a_location; + g_return_if_fail (a_this); ctxtptr = &ctxt; status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); @@ -390,18 +387,21 @@ end_page (CRDocHandler * a_this, CRString * a_page, CRString * a_pseudo_page) { - UNUSED(a_page); - UNUSED(a_pseudo_page); - enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; CRStatement *stmt = NULL; + (void) a_page; + (void) a_pseudo_page; + g_return_if_fail (a_this); + ctxtptr = &ctxt; status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt->cur_stmt && ctxt->cur_stmt->type == AT_PAGE_RULE_STMT && ctxt->stylesheet); @@ -419,6 +419,8 @@ end_page (CRDocHandler * a_this, cr_statement_destroy (ctxt->cur_stmt); ctxt->cur_stmt = NULL; } + a_page = NULL; /*keep compiler happy */ + a_pseudo_page = NULL; /*keep compiler happy */ } static void @@ -426,13 +428,13 @@ start_media (CRDocHandler * a_this, GList * a_media_list, CRParsingLocation *a_location) { - UNUSED(a_location); - enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; GList *media_list = NULL; + (void) a_location; + g_return_if_fail (a_this); ctxtptr = &ctxt; status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); @@ -456,17 +458,20 @@ start_media (CRDocHandler * a_this, static void end_media (CRDocHandler * a_this, GList * a_media_list) { - UNUSED(a_media_list); - enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; CRStatement *stmts = NULL; + (void) a_media_list; + g_return_if_fail (a_this); + ctxtptr = &ctxt; status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt && ctxt->cur_media_stmt && ctxt->cur_media_stmt->type == AT_MEDIA_RULE_STMT @@ -474,6 +479,7 @@ end_media (CRDocHandler * a_this, GList * a_media_list) stmts = cr_statement_append (ctxt->stylesheet->statements, ctxt->cur_media_stmt); + if (!stmts) { cr_statement_destroy (ctxt->cur_media_stmt); ctxt->cur_media_stmt = NULL; @@ -484,6 +490,7 @@ end_media (CRDocHandler * a_this, GList * a_media_list) ctxt->cur_stmt = NULL ; ctxt->cur_media_stmt = NULL ; + a_media_list = NULL; } static void @@ -493,9 +500,6 @@ import_style (CRDocHandler * a_this, CRString * a_uri_default_ns, CRParsingLocation *a_location) { - UNUSED(a_uri_default_ns); - UNUSED(a_location); - enum CRStatus status = CR_OK; CRString *uri = NULL; CRStatement *stmt = NULL, @@ -504,17 +508,26 @@ import_style (CRDocHandler * a_this, ParsingContext **ctxtptr = NULL; GList *media_list = NULL ; + (void) a_uri_default_ns; + (void) a_location; + g_return_if_fail (a_this); + ctxtptr = &ctxt; status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt->stylesheet); uri = cr_string_dup (a_uri) ; + if (a_media_list) media_list = cr_utils_dup_glist_of_cr_string (a_media_list) ; + stmt = cr_statement_new_at_import_rule (ctxt->stylesheet, uri, media_list, NULL); + if (!stmt) goto error; @@ -546,6 +559,7 @@ import_style (CRDocHandler * a_this, cr_statement_destroy (stmt); stmt = NULL; } + a_uri_default_ns = NULL; /*keep compiler happy */ } static void @@ -572,16 +586,19 @@ start_selector (CRDocHandler * a_this, CRSelector * a_selector_list) static void end_selector (CRDocHandler * a_this, CRSelector * a_selector_list) { - UNUSED(a_selector_list); - enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; + (void) a_selector_list; + g_return_if_fail (a_this); + ctxtptr = &ctxt; status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt->cur_stmt && ctxt->stylesheet); if (ctxt->cur_stmt) { @@ -621,6 +638,8 @@ end_selector (CRDocHandler * a_this, CRSelector * a_selector_list) } } + + a_selector_list = NULL; /*keep compiler happy */ } static void diff --git a/src/libcroco/cr-parser.c b/src/libcroco/cr-parser.c index 69b521496..544b35ab0 100644 --- a/src/libcroco/cr-parser.c +++ b/src/libcroco/cr-parser.c @@ -78,7 +78,7 @@ typedef struct _CRParserError CRParserError; *parsing routines. */ struct _CRParserError { - gchar *msg; + guchar *msg; enum CRStatus status; glong line; glong column; @@ -197,9 +197,9 @@ if ((a_status) != CR_OK) \ */ #define PEEK_NEXT_CHAR(a_this, a_to_char) \ {\ -enum CRStatus status ; \ -status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, a_to_char) ; \ -CHECK_PARSING_STATUS (status, TRUE) \ +enum CRStatus pnc_status ; \ +pnc_status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, a_to_char) ; \ +CHECK_PARSING_STATUS (pnc_status, TRUE) \ } /** @@ -374,11 +374,11 @@ static enum CRStatus cr_parser_parse_simple_selector (CRParser * a_this, static enum CRStatus cr_parser_parse_simple_sels (CRParser * a_this, CRSimpleSel ** a_sel); -static CRParserError *cr_parser_error_new (const gchar * a_msg, +static CRParserError *cr_parser_error_new (const guchar * a_msg, enum CRStatus); static void cr_parser_error_set_msg (CRParserError * a_this, - const gchar * a_msg); + const guchar * a_msg); static void cr_parser_error_dump (CRParserError * a_this); @@ -392,7 +392,7 @@ static void cr_parser_error_destroy (CRParserError * a_this); static enum CRStatus cr_parser_push_error (CRParser * a_this, - const gchar * a_msg, + const guchar * a_msg, enum CRStatus a_status); static enum CRStatus cr_parser_dump_err_stack (CRParser * a_this, @@ -411,7 +411,7 @@ static enum CRStatus *@return the newly built instance of #CRParserError. */ static CRParserError * -cr_parser_error_new (const gchar * a_msg, enum CRStatus a_status) +cr_parser_error_new (const guchar * a_msg, enum CRStatus a_status) { CRParserError *result = NULL; @@ -436,7 +436,7 @@ cr_parser_error_new (const gchar * a_msg, enum CRStatus a_status) *@param a_msg the new message. */ static void -cr_parser_error_set_msg (CRParserError * a_this, const gchar * a_msg) +cr_parser_error_set_msg (CRParserError * a_this, const guchar * a_msg) { g_return_if_fail (a_this); @@ -444,7 +444,7 @@ cr_parser_error_set_msg (CRParserError * a_this, const gchar * a_msg) g_free (a_this->msg); } - a_this->msg = g_strdup (a_msg); + a_this->msg = (guchar *) g_strdup ((const gchar *) a_msg); } /** @@ -515,7 +515,7 @@ cr_parser_error_destroy (CRParserError * a_this) */ static enum CRStatus cr_parser_push_error (CRParser * a_this, - const gchar * a_msg, enum CRStatus a_status) + const guchar * a_msg, enum CRStatus a_status) { enum CRStatus status = CR_OK; @@ -733,7 +733,7 @@ cr_parser_parse_stylesheet_core (CRParser * a_this) error: cr_parser_push_error - (a_this, "could not recognize next production", CR_ERROR); + (a_this, (const guchar *) "could not recognize next production", CR_ERROR); cr_parser_dump_err_stack (a_this, TRUE); @@ -1688,14 +1688,12 @@ cr_parser_parse_simple_selector (CRParser * a_this, CRSimpleSel ** a_sel) && token->u.unichar == '*') { int comb = (int)sel->type_mask | (int) UNIVERSAL_SELECTOR; sel->type_mask = (enum SimpleSelectorType)comb; - //sel->type_mask |= UNIVERSAL_SELECTOR; sel->name = cr_string_new_from_string ("*"); found_sel = TRUE; } else if (token && token->type == IDENT_TK) { sel->name = token->u.str; int comb = (int)sel->type_mask | (int) TYPE_SELECTOR; sel->type_mask = (enum SimpleSelectorType)comb; - //sel->type_mask |= TYPE_SELECTOR; token->u.str = NULL; found_sel = TRUE; } else { @@ -2707,7 +2705,7 @@ cr_parser_parse_stylesheet (CRParser * a_this) } cr_parser_push_error - (a_this, "could not recognize next production", CR_ERROR); + (a_this, (const guchar *) "could not recognize next production", CR_ERROR); if (PRIVATE (a_this)->sac_handler && PRIVATE (a_this)->sac_handler->unrecoverable_error) { @@ -3193,7 +3191,7 @@ cr_parser_parse_declaration (CRParser * a_this, CHECK_PARSING_STATUS_ERR (a_this, status, FALSE, - "while parsing declaration: next property is malformed", + (const guchar *) "while parsing declaration: next property is malformed", CR_SYNTAX_ERROR); READ_NEXT_CHAR (a_this, &cur_char); @@ -3202,7 +3200,7 @@ cr_parser_parse_declaration (CRParser * a_this, status = CR_PARSING_ERROR; cr_parser_push_error (a_this, - "while parsing declaration: this char must be ':'", + (const guchar *) "while parsing declaration: this char must be ':'", CR_SYNTAX_ERROR); goto error; } @@ -3213,7 +3211,7 @@ cr_parser_parse_declaration (CRParser * a_this, CHECK_PARSING_STATUS_ERR (a_this, status, FALSE, - "while parsing declaration: next expression is malformed", + (const guchar *) "while parsing declaration: next expression is malformed", CR_SYNTAX_ERROR); cr_parser_try_to_skip_spaces_and_comments (a_this); @@ -3353,7 +3351,7 @@ cr_parser_parse_ruleset (CRParser * a_this) ENSURE_PARSING_COND_ERR (a_this, cur_char == '{', - "while parsing rulset: current char should be '{'", + (const guchar *) "while parsing rulset: current char should be '{'", CR_SYNTAX_ERROR); if (PRIVATE (a_this)->sac_handler @@ -3417,7 +3415,7 @@ cr_parser_parse_ruleset (CRParser * a_this) } CHECK_PARSING_STATUS_ERR (a_this, status, FALSE, - "while parsing ruleset: next construction should be a declaration", + (const guchar *) "while parsing ruleset: next construction should be a declaration", CR_SYNTAX_ERROR); for (;;) { @@ -3459,7 +3457,7 @@ cr_parser_parse_ruleset (CRParser * a_this) READ_NEXT_CHAR (a_this, &cur_char); ENSURE_PARSING_COND_ERR (a_this, cur_char == '}', - "while parsing rulset: current char must be a '}'", + (const guchar *) "while parsing rulset: current char must be a '}'", CR_SYNTAX_ERROR); selector->location = end_parsing_location; diff --git a/src/libcroco/cr-pseudo.c b/src/libcroco/cr-pseudo.c index a46e69ed0..cee3fc869 100644 --- a/src/libcroco/cr-pseudo.c +++ b/src/libcroco/cr-pseudo.c @@ -68,11 +68,11 @@ cr_pseudo_to_string (CRPseudo const * a_this) goto error; } - name = g_strndup (a_this->name->stryng->str, + name = (guchar *) g_strndup (a_this->name->stryng->str, a_this->name->stryng->len); if (name) { - g_string_append (str_buf, name); + g_string_append (str_buf, (const gchar *) name); g_free (name); name = NULL; } @@ -83,11 +83,11 @@ cr_pseudo_to_string (CRPseudo const * a_this) if (a_this->name == NULL) goto error; - name = g_strndup (a_this->name->stryng->str, + name = (guchar *) g_strndup (a_this->name->stryng->str, a_this->name->stryng->len); if (a_this->extra) { - arg = g_strndup (a_this->extra->stryng->str, + arg = (guchar *) g_strndup (a_this->extra->stryng->str, a_this->extra->stryng->len); } @@ -97,7 +97,7 @@ cr_pseudo_to_string (CRPseudo const * a_this) name = NULL; if (arg) { - g_string_append (str_buf, arg); + g_string_append (str_buf, (const gchar *) arg); g_free (arg); arg = NULL; } @@ -107,7 +107,7 @@ cr_pseudo_to_string (CRPseudo const * a_this) } if (str_buf) { - result = str_buf->str; + result = (guchar *) str_buf->str; g_string_free (str_buf, FALSE); str_buf = NULL; } diff --git a/src/libcroco/cr-rgb.c b/src/libcroco/cr-rgb.c index 537343579..889f248b6 100644 --- a/src/libcroco/cr-rgb.c +++ b/src/libcroco/cr-rgb.c @@ -275,7 +275,7 @@ cr_rgb_to_string (CRRgb const * a_this) } if (str_buf) { - result = str_buf->str; + result = (guchar *) str_buf->str; g_string_free (str_buf, FALSE); } @@ -507,7 +507,7 @@ cr_rgb_set_from_hex_str (CRRgb * a_this, const guchar * a_hex) g_return_val_if_fail (a_this && a_hex, CR_BAD_PARAM_ERROR); - if (strlen (a_hex) == 3) { + if (strlen ((const char *) a_hex) == 3) { for (i = 0; i < 3; i++) { if (a_hex[i] >= '0' && a_hex[i] <= '9') { colors[i] = a_hex[i] - '0'; @@ -522,7 +522,7 @@ cr_rgb_set_from_hex_str (CRRgb * a_this, const guchar * a_hex) status = CR_UNKNOWN_TYPE_ERROR; } } - } else if (strlen (a_hex) == 6) { + } else if (strlen ((const char *) a_hex) == 6) { for (i = 0; i < 6; i++) { if (a_hex[i] >= '0' && a_hex[i] <= '9') { colors[i / 2] <<= 4; @@ -587,7 +587,7 @@ cr_rgb_set_from_term (CRRgb *a_this, const struct _CRTerm *a_value) } else { status = cr_rgb_set_from_name (a_this, - a_value->content.str->stryng->str) ; + (const guchar *) a_value->content.str->stryng->str) ; } } else { cr_utils_trace_info @@ -600,7 +600,7 @@ cr_rgb_set_from_term (CRRgb *a_this, const struct _CRTerm *a_value) && a_value->content.str->stryng->str) { status = cr_rgb_set_from_hex_str (a_this, - a_value->content.str->stryng->str) ; + (const guchar *) a_value->content.str->stryng->str) ; } else { cr_utils_trace_info ("a_value has NULL string value") ; @@ -656,8 +656,7 @@ cr_rgb_parse_from_buf (const guchar *a_str, g_return_val_if_fail (a_str, NULL); - parser = cr_parser_new_from_buf ((guchar*)a_str, strlen (a_str), - a_enc, FALSE) ; + parser = cr_parser_new_from_buf ((guchar *) a_str, strlen ((const char *) a_str), a_enc, FALSE); g_return_val_if_fail (parser, NULL); diff --git a/src/libcroco/cr-sel-eng.c b/src/libcroco/cr-sel-eng.c index 4f501ee05..ed40de393 100644 --- a/src/libcroco/cr-sel-eng.c +++ b/src/libcroco/cr-sel-eng.c @@ -37,7 +37,7 @@ #define PRIVATE(a_this) (a_this)->priv struct CRPseudoClassSelHandlerEntry { - char *name; + guchar *name; enum CRPseudoType type; CRPseudoClassSelectorHandler handler; }; @@ -149,8 +149,8 @@ lang_pseudo_class_handler (CRSelEng *const a_this, || a_sel->content.pseudo->extra->stryng->len < 2) return FALSE; for (; node; node = get_next_parent_element_node (node_iface, node)) { - char *val = node_iface->getProp (node, "lang"); - if (!val) val = node_iface->getProp (node, "xml:lang"); + char *val = node_iface->getProp (node, (const xmlChar *) "lang"); + if (!val) val = node_iface->getProp (node, (const xmlChar *) "xml:lang"); if (val) { if (!strcasecmp(val, a_sel->content.pseudo->extra->stryng->str)) { result = TRUE; @@ -209,7 +209,7 @@ pseudo_class_add_sel_matches_node (CRSelEng * a_this, && a_node, FALSE); status = cr_sel_eng_get_pseudo_class_selector_handler - (a_this, a_add_sel->content.pseudo->name->stryng->str, + (a_this, (guchar *) a_add_sel->content.pseudo->name->stryng->str, a_add_sel->content.pseudo->type, &handler); if (status != CR_OK || !handler) return FALSE; @@ -237,7 +237,7 @@ class_add_sel_matches_node (CRAdditionalSel * a_add_sel, && a_add_sel->content.class_name->stryng->str && a_node, FALSE); - klass = a_node_iface->getProp (a_node, "class"); + klass = a_node_iface->getProp (a_node, (const xmlChar *) "class"); if (klass) { char const *cur; for (cur = klass; cur && *cur; cur++) { @@ -246,7 +246,7 @@ class_add_sel_matches_node (CRAdditionalSel * a_add_sel, == TRUE) cur++; - if (!strncmp (cur, + if (!strncmp ((const char *) cur, a_add_sel->content.class_name->stryng->str, a_add_sel->content.class_name->stryng->len)) { cur += a_add_sel->content.class_name->stryng->len; @@ -291,9 +291,9 @@ id_add_sel_matches_node (CRAdditionalSel * a_add_sel, && a_add_sel->type == ID_ADD_SELECTOR && a_node, FALSE); - id = a_node_iface->getProp (a_node, "id"); + id = a_node_iface->getProp (a_node, (const xmlChar *) "id"); if (id) { - if (!strqcmp (id, a_add_sel->content.id_name->stryng->str, + if (!strqcmp ((const char *) id, a_add_sel->content.id_name->stryng->str, a_add_sel->content.id_name->stryng->len)) { result = TRUE; } @@ -324,7 +324,7 @@ attr_add_sel_matches_node (CRAdditionalSel * a_add_sel, for (cur_sel = a_add_sel->content.attr_sel; cur_sel; cur_sel = cur_sel->next) { - if (!cur_sel->name + if (!cur_sel->name || !cur_sel->name->stryng || !cur_sel->name->stryng->str) return FALSE; @@ -384,7 +384,7 @@ attr_add_sel_matches_node (CRAdditionalSel * a_add_sel, ptr2 = cur; if (!strncmp - (ptr1, + ((const char *) ptr1, cur_sel->value->stryng->str, ptr2 - ptr1 + 1)) { found = TRUE; @@ -422,7 +422,7 @@ attr_add_sel_matches_node (CRAdditionalSel * a_add_sel, ptr2 = cur; if (g_strstr_len - (ptr1, ptr2 - ptr1 + 1, + ((const gchar *) ptr1, ptr2 - ptr1 + 1, cur_sel->value->stryng->str) == ptr1) { found = TRUE; @@ -635,7 +635,7 @@ sel_matches_node_real (CRSelEng * a_this, CRSimpleSel * a_sel, && cur_sel->name->stryng && cur_sel->name->stryng->str) && (!strcmp (cur_sel->name->stryng->str, - node_iface->getLocalName(cur_node)))) + (const char *) node_iface->getLocalName(cur_node)))) || (cur_sel->type_mask & UNIVERSAL_SELECTOR)) { /* *this simple selector @@ -1121,11 +1121,11 @@ cr_sel_eng_new (void) } memset (PRIVATE (result), 0, sizeof (CRSelEngPriv)); cr_sel_eng_register_pseudo_class_sel_handler - (result, "first-child", + (result, (guchar *) "first-child", IDENT_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ first_child_pseudo_class_handler); cr_sel_eng_register_pseudo_class_sel_handler - (result, "lang", + (result, (guchar *) "lang", FUNCTION_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ lang_pseudo_class_handler); @@ -1146,7 +1146,7 @@ cr_sel_eng_new (void) */ enum CRStatus cr_sel_eng_register_pseudo_class_sel_handler (CRSelEng * a_this, - char * a_name, + guchar * a_name, enum CRPseudoType a_type, CRPseudoClassSelectorHandler a_handler) @@ -1164,7 +1164,7 @@ cr_sel_eng_register_pseudo_class_sel_handler (CRSelEng * a_this, } memset (handler_entry, 0, sizeof (struct CRPseudoClassSelHandlerEntry)); - handler_entry->name = g_strdup (a_name); + handler_entry->name = (guchar *) g_strdup ((const gchar *) a_name); handler_entry->type = a_type; handler_entry->handler = a_handler; list = g_list_append (PRIVATE (a_this)->pcs_handlers, handler_entry); @@ -1177,7 +1177,7 @@ cr_sel_eng_register_pseudo_class_sel_handler (CRSelEng * a_this, enum CRStatus cr_sel_eng_unregister_pseudo_class_sel_handler (CRSelEng * a_this, - char * a_name, + guchar * a_name, enum CRPseudoType a_type) { GList *elem = NULL, @@ -1190,7 +1190,7 @@ cr_sel_eng_unregister_pseudo_class_sel_handler (CRSelEng * a_this, for (elem = PRIVATE (a_this)->pcs_handlers; elem; elem = g_list_next (elem)) { entry = (struct CRPseudoClassSelHandlerEntry *) elem->data; - if (!strcmp (entry->name, a_name) + if (!strcmp ((const char *) entry->name, (const char *) a_name) && entry->type == a_type) { found = TRUE; break; @@ -1250,7 +1250,7 @@ cr_sel_eng_unregister_all_pseudo_class_sel_handlers (CRSelEng * a_this) enum CRStatus cr_sel_eng_get_pseudo_class_selector_handler (CRSelEng * a_this, - char * a_name, + guchar * a_name, enum CRPseudoType a_type, CRPseudoClassSelectorHandler * a_handler) @@ -1265,7 +1265,7 @@ cr_sel_eng_get_pseudo_class_selector_handler (CRSelEng * a_this, for (elem = PRIVATE (a_this)->pcs_handlers; elem; elem = g_list_next (elem)) { entry = (struct CRPseudoClassSelHandlerEntry *) elem->data; - if (!strcmp (a_name, entry->name) + if (!strcmp ((const char *) a_name, (const char *) entry->name) && entry->type == a_type) { found = TRUE; break; diff --git a/src/libcroco/cr-sel-eng.h b/src/libcroco/cr-sel-eng.h index 4d09f9c95..564debc8d 100644 --- a/src/libcroco/cr-sel-eng.h +++ b/src/libcroco/cr-sel-eng.h @@ -65,18 +65,18 @@ typedef gboolean (*CRPseudoClassSelectorHandler) (CRSelEng* a_this, CRSelEng * cr_sel_eng_new (void) ; enum CRStatus cr_sel_eng_register_pseudo_class_sel_handler (CRSelEng *a_this, - char *a_pseudo_class_sel_name, + guchar *a_pseudo_class_sel_name, enum CRPseudoType a_pseudo_class_type, CRPseudoClassSelectorHandler a_handler) ; enum CRStatus cr_sel_eng_unregister_pseudo_class_sel_handler (CRSelEng *a_this, - char *a_pseudo_class_sel_name, + guchar *a_pseudo_class_sel_name, enum CRPseudoType a_pseudo_class_type) ; enum CRStatus cr_sel_eng_unregister_all_pseudo_class_sel_handlers (CRSelEng *a_this) ; enum CRStatus cr_sel_eng_get_pseudo_class_selector_handler (CRSelEng *a_this, - char *a_pseudo_class_sel_name, + guchar *a_pseudo_class_sel_name, enum CRPseudoType a_pseudo_class_type, CRPseudoClassSelectorHandler *a_handler) ; diff --git a/src/libcroco/cr-selector.c b/src/libcroco/cr-selector.c index 43a3bd914..c56c43fda 100644 --- a/src/libcroco/cr-selector.c +++ b/src/libcroco/cr-selector.c @@ -38,7 +38,10 @@ CRSelector * cr_selector_new (CRSimpleSel * a_simple_sel) { - CRSelector *result = (CRSelector *)g_try_malloc (sizeof (CRSelector)); + CRSelector *result = NULL; + + result = (CRSelector *) g_try_malloc (sizeof (CRSelector)); + if (!result) { cr_utils_trace_info ("Out of memory"); return NULL; @@ -55,8 +58,7 @@ cr_selector_parse_from_buf (const guchar * a_char_buf, enum CREncoding a_enc) g_return_val_if_fail (a_char_buf, NULL); - parser = cr_parser_new_from_buf ((guchar*)a_char_buf, - strlen ((char *)a_char_buf), + parser = cr_parser_new_from_buf ((guchar*)a_char_buf, strlen ((const char *) a_char_buf), a_enc, FALSE); g_return_val_if_fail (parser, NULL); @@ -140,8 +142,9 @@ guchar * cr_selector_to_string (CRSelector const * a_this) { guchar *result = NULL; + GString *str_buf = NULL; - GString *str_buf = (GString *)g_string_new (NULL); + str_buf = (GString *) g_string_new (NULL); g_return_val_if_fail (str_buf, NULL); if (a_this) { @@ -159,7 +162,7 @@ cr_selector_to_string (CRSelector const * a_this) g_string_append (str_buf, ", "); - g_string_append (str_buf, (gchar *)tmp_str); + g_string_append (str_buf, (const gchar *) tmp_str); g_free (tmp_str); tmp_str = NULL; @@ -169,7 +172,7 @@ cr_selector_to_string (CRSelector const * a_this) } if (str_buf) { - result = (guchar *)str_buf->str; + result = (guchar *) str_buf->str; g_string_free (str_buf, FALSE); str_buf = NULL; } diff --git a/src/libcroco/cr-simple-sel.c b/src/libcroco/cr-simple-sel.c index 4f5ac965a..a4670fe88 100644 --- a/src/libcroco/cr-simple-sel.c +++ b/src/libcroco/cr-simple-sel.c @@ -35,7 +35,9 @@ CRSimpleSel * cr_simple_sel_new (void) { - CRSimpleSel *result = (CRSimpleSel *)g_try_malloc (sizeof (CRSimpleSel)); + CRSimpleSel *result = NULL; + + result = (CRSimpleSel *) g_try_malloc (sizeof (CRSimpleSel)); if (!result) { cr_utils_trace_info ("Out of memory"); return NULL; @@ -110,7 +112,7 @@ cr_simple_sel_to_string (CRSimpleSel const * a_this) str_buf = g_string_new (NULL); for (cur = a_this; cur; cur = cur->next) { if (cur->name) { - gchar *str = g_strndup (cur->name->stryng->str, + guchar *str = (guchar *) g_strndup (cur->name->stryng->str, cur->name->stryng->len); if (str) { @@ -131,17 +133,18 @@ cr_simple_sel_to_string (CRSimpleSel const * a_this) break; } - g_string_append (str_buf, str); + g_string_append (str_buf, (const gchar *) str); g_free (str); str = NULL; } } if (cur->add_sel) { + guchar *tmp_str = NULL; - gchar *tmp_str = (gchar *)cr_additional_sel_to_string (cur->add_sel); + tmp_str = cr_additional_sel_to_string (cur->add_sel); if (tmp_str) { - g_string_append (str_buf, tmp_str); + g_string_append (str_buf, (const gchar *) tmp_str); g_free (tmp_str); tmp_str = NULL; } @@ -149,7 +152,7 @@ cr_simple_sel_to_string (CRSimpleSel const * a_this) } if (str_buf) { - result = (guchar *)str_buf->str; + result = (guchar *) str_buf->str; g_string_free (str_buf, FALSE); str_buf = NULL; } @@ -168,7 +171,7 @@ cr_simple_sel_one_to_string (CRSimpleSel const * a_this) str_buf = g_string_new (NULL); if (a_this->name) { - gchar *str = g_strndup (a_this->name->stryng->str, + guchar *str = (guchar *) g_strndup (a_this->name->stryng->str, a_this->name->stryng->len); if (str) { @@ -179,8 +182,9 @@ cr_simple_sel_one_to_string (CRSimpleSel const * a_this) } if (a_this->add_sel) { + guchar *tmp_str = NULL; - gchar *tmp_str = (gchar *)cr_additional_sel_to_string (a_this->add_sel); + tmp_str = cr_additional_sel_to_string (a_this->add_sel); if (tmp_str) { g_string_append_printf (str_buf, "%s", tmp_str); @@ -190,7 +194,7 @@ cr_simple_sel_one_to_string (CRSimpleSel const * a_this) } if (str_buf) { - result = (guchar *)str_buf->str; + result = (guchar *) str_buf->str; g_string_free (str_buf, FALSE); str_buf = NULL; } diff --git a/src/libcroco/cr-statement.c b/src/libcroco/cr-statement.c index 4666f26ec..e31123aec 100644 --- a/src/libcroco/cr-statement.c +++ b/src/libcroco/cr-statement.c @@ -25,8 +25,6 @@ #include "cr-statement.h" #include "cr-parser.h" -#define UNUSED(_param) ((void)(_param)) - /** *@file *Definition of the #CRStatement class. @@ -38,12 +36,12 @@ static void cr_statement_clear (CRStatement * a_this); static void parse_font_face_start_font_face_cb (CRDocHandler * a_this, - CRParsingLocation * a_location) + CRParsingLocation *a_location) { CRStatement *stmt = NULL; enum CRStatus status = CR_OK; - UNUSED(a_location); + (void) a_location; stmt = cr_statement_new_at_font_face_rule (NULL, NULL); g_return_if_fail (stmt); @@ -86,7 +84,7 @@ parse_font_face_property_cb (CRDocHandler * a_this, CRStatement *stmt = NULL; CRStatement **stmtptr = NULL; - UNUSED(a_important); + (void) a_important; g_return_if_fail (a_this && a_name); @@ -144,13 +142,13 @@ static void parse_page_start_page_cb (CRDocHandler * a_this, CRString * a_name, CRString * a_pseudo_page, - CRParsingLocation * a_location) + CRParsingLocation *a_location) { CRStatement *stmt = NULL; enum CRStatus status = CR_OK; CRString *page_name = NULL, *pseudo_name = NULL ; - UNUSED(a_location); + (void) a_location; if (a_name) page_name = cr_string_dup (a_name) ; @@ -225,8 +223,8 @@ parse_page_end_page_cb (CRDocHandler * a_this, CRStatement *stmt = NULL; CRStatement **stmtptr = NULL; - UNUSED(a_name); - UNUSED(a_pseudo_page); + (void) a_name; + (void) a_pseudo_page; stmtptr = &stmt; status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); @@ -240,13 +238,13 @@ parse_page_end_page_cb (CRDocHandler * a_this, static void parse_at_media_start_media_cb (CRDocHandler * a_this, GList * a_media_list, - CRParsingLocation * a_location) + CRParsingLocation *a_location) { enum CRStatus status = CR_OK; CRStatement *at_media = NULL; GList *media_list = NULL; - UNUSED(a_location); + (void) a_location; g_return_if_fail (a_this && a_this->priv); @@ -380,7 +378,7 @@ parse_at_media_end_media_cb (CRDocHandler * a_this, CRStatement *at_media = NULL; CRStatement **at_media_ptr = NULL; - UNUSED(a_media_list); + (void) a_media_list; g_return_if_fail (a_this && a_this->priv); @@ -603,12 +601,13 @@ cr_statement_clear (CRStatement * a_this) static gchar * cr_statement_ruleset_to_string (CRStatement const * a_this, glong a_indent) { + GString *stringue = NULL; gchar *tmp_str = NULL, *result = NULL; g_return_val_if_fail (a_this && a_this->type == RULESET_STMT, NULL); - GString * stringue = (GString *)g_string_new (NULL); + stringue = (GString *) g_string_new (NULL); if (!stringue) { return result; } @@ -617,8 +616,8 @@ cr_statement_ruleset_to_string (CRStatement const * a_this, glong a_indent) if (a_indent) cr_utils_dump_n_chars2 (' ', stringue, a_indent); - tmp_str = (gchar *) - cr_selector_to_string (a_this->kind.ruleset-> + tmp_str = + (gchar *) cr_selector_to_string (a_this->kind.ruleset-> sel_list); if (tmp_str) { g_string_append (stringue, tmp_str); @@ -628,7 +627,7 @@ cr_statement_ruleset_to_string (CRStatement const * a_this, glong a_indent) } g_string_append (stringue, " {\n"); if (a_this->kind.ruleset->decl_list) { - tmp_str = (gchar *)cr_declaration_list_to_string2 + tmp_str = (gchar *) cr_declaration_list_to_string2 (a_this->kind.ruleset->decl_list, a_indent + DECLARATION_INDENT_NB, TRUE); if (tmp_str) { @@ -677,13 +676,13 @@ cr_statement_font_face_rule_to_string (CRStatement const * a_this, NULL); if (a_this->kind.font_face_rule->decl_list) { - stringue = (GString *)g_string_new (NULL) ; + stringue = (GString *) g_string_new (NULL) ; g_return_val_if_fail (stringue, NULL) ; if (a_indent) cr_utils_dump_n_chars2 (' ', stringue, a_indent); g_string_append (stringue, "@font-face {\n"); - tmp_str = (gchar *)cr_declaration_list_to_string2 + tmp_str = (gchar *) cr_declaration_list_to_string2 (a_this->kind.font_face_rule->decl_list, a_indent + DECLARATION_INDENT_NB, TRUE) ; if (tmp_str) { @@ -762,9 +761,10 @@ static gchar * cr_statement_at_page_rule_to_string (CRStatement const *a_this, gulong a_indent) { + GString *stringue = NULL; gchar *result = NULL ; - GString *stringue = (GString *)g_string_new (NULL) ; + stringue = (GString *) g_string_new (NULL) ; cr_utils_dump_n_chars2 (' ', stringue, a_indent) ; g_string_append (stringue, "@page"); @@ -785,7 +785,7 @@ cr_statement_at_page_rule_to_string (CRStatement const *a_this, if (a_this->kind.page_rule->decl_list) { gchar *str = NULL ; g_string_append (stringue, " {\n"); - str = (gchar *)cr_declaration_list_to_string2 + str = (gchar *) cr_declaration_list_to_string2 (a_this->kind.page_rule->decl_list, a_indent + DECLARATION_INDENT_NB, TRUE) ; if (str) { @@ -821,17 +821,17 @@ cr_statement_media_rule_to_string (CRStatement const *a_this, NULL); if (a_this->kind.media_rule) { - stringue = (GString *)g_string_new (NULL) ; + stringue = (GString *) g_string_new (NULL) ; cr_utils_dump_n_chars2 (' ', stringue, a_indent); g_string_append (stringue, "@media"); for (cur = a_this->kind.media_rule->media_list; cur; cur = cur->next) { if (cur->data) { - gchar *str = cr_string_dup2 + gchar *str2 = cr_string_dup2 ((CRString const *) cur->data); - if (str) { + if (str2) { if (cur->prev) { g_string_append (stringue, @@ -839,9 +839,9 @@ cr_statement_media_rule_to_string (CRStatement const *a_this, } g_string_append_printf (stringue, - " %s", str); - g_free (str); - str = NULL; + " %s", str2); + g_free (str2); + str2 = NULL; } } } @@ -878,7 +878,7 @@ cr_statement_import_rule_to_string (CRStatement const *a_this, if (a_this->kind.import_rule->url && a_this->kind.import_rule->url->stryng) { - stringue = (GString *)g_string_new (NULL) ; + stringue = (GString *) g_string_new (NULL) ; g_return_val_if_fail (stringue, NULL) ; str = g_strndup (a_this->kind.import_rule->url->stryng->str, a_this->kind.import_rule->url->stryng->len); @@ -950,8 +950,7 @@ cr_statement_does_buf_parses_against_core (const guchar * a_buf, enum CRStatus status = CR_OK; gboolean result = FALSE; - parser = cr_parser_new_from_buf ((guchar*)a_buf, - strlen ((char *)a_buf), + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), a_encoding, FALSE); g_return_val_if_fail (parser, FALSE); @@ -1071,8 +1070,7 @@ cr_statement_ruleset_parse_from_buf (const guchar * a_buf, g_return_val_if_fail (a_buf, NULL); - parser = cr_parser_new_from_buf ((guchar*)a_buf, - strlen ((char *)a_buf), + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), a_enc, FALSE); g_return_val_if_fail (parser, NULL); @@ -1138,6 +1136,8 @@ cr_statement_new_ruleset (CRStyleSheet * a_sheet, CRDeclaration * a_decl_list, CRStatement * a_parent_media_rule) { + CRStatement *result = NULL; + g_return_val_if_fail (a_sel_list, NULL); if (a_parent_media_rule) { @@ -1148,7 +1148,7 @@ cr_statement_new_ruleset (CRStyleSheet * a_sheet, NULL); } - CRStatement *result = (CRStatement *)g_try_malloc (sizeof (CRStatement)); + result = (CRStatement *) g_try_malloc (sizeof (CRStatement)); if (!result) { cr_utils_trace_info ("Out of memory"); @@ -1157,7 +1157,7 @@ cr_statement_new_ruleset (CRStyleSheet * a_sheet, memset (result, 0, sizeof (CRStatement)); result->type = RULESET_STMT; - result->kind.ruleset = (CRRuleSet *)g_try_malloc (sizeof (CRRuleSet)); + result->kind.ruleset = (CRRuleSet *) g_try_malloc (sizeof (CRRuleSet)); if (!result->kind.ruleset) { cr_utils_trace_info ("Out of memory"); @@ -1207,8 +1207,7 @@ cr_statement_at_media_rule_parse_from_buf (const guchar * a_buf, CRDocHandler *sac_handler = NULL; enum CRStatus status = CR_OK; - parser = cr_parser_new_from_buf ((guchar*)a_buf, - strlen ((char *)a_buf), + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), a_enc, FALSE); if (!parser) { cr_utils_trace_info ("Instanciation of the parser failed"); @@ -1278,12 +1277,13 @@ CRStatement * cr_statement_new_at_media_rule (CRStyleSheet * a_sheet, CRStatement * a_rulesets, GList * a_media) { - CRStatement *cur = NULL; + CRStatement *result = NULL, + *cur = NULL; if (a_rulesets) g_return_val_if_fail (a_rulesets->type == RULESET_STMT, NULL); - CRStatement *result = (CRStatement *)g_try_malloc (sizeof (CRStatement)); + result = (CRStatement *) g_try_malloc (sizeof (CRStatement)); if (!result) { cr_utils_trace_info ("Out of memory"); @@ -1293,7 +1293,7 @@ cr_statement_new_at_media_rule (CRStyleSheet * a_sheet, memset (result, 0, sizeof (CRStatement)); result->type = AT_MEDIA_RULE_STMT; - result->kind.media_rule = (CRAtMediaRule *)g_try_malloc (sizeof (CRAtMediaRule)); + result->kind.media_rule = (CRAtMediaRule *) g_try_malloc (sizeof (CRAtMediaRule)); if (!result->kind.media_rule) { cr_utils_trace_info ("Out of memory"); g_free (result); @@ -1340,7 +1340,9 @@ cr_statement_new_at_import_rule (CRStyleSheet * a_container_sheet, GList * a_media_list, CRStyleSheet * a_imported_sheet) { - CRStatement *result = (CRStatement *)g_try_malloc (sizeof (CRStatement)); + CRStatement *result = NULL; + + result = (CRStatement *) g_try_malloc (sizeof (CRStatement)); if (!result) { cr_utils_trace_info ("Out of memory"); @@ -1350,7 +1352,7 @@ cr_statement_new_at_import_rule (CRStyleSheet * a_container_sheet, memset (result, 0, sizeof (CRStatement)); result->type = AT_IMPORT_RULE_STMT; - result->kind.import_rule = (CRAtImportRule *)g_try_malloc (sizeof (CRAtImportRule)); + result->kind.import_rule = (CRAtImportRule *) g_try_malloc (sizeof (CRAtImportRule)); if (!result->kind.import_rule) { cr_utils_trace_info ("Out of memory"); @@ -1391,8 +1393,7 @@ cr_statement_at_import_rule_parse_from_buf (const guchar * a_buf, CRString *import_string = NULL; CRParsingLocation location = {0,0,0} ; - parser = cr_parser_new_from_buf ((guchar*)a_buf, - strlen ((char *)a_buf), + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), a_encoding, FALSE); if (!parser) { cr_utils_trace_info ("Instanciation of parser failed."); @@ -1425,8 +1426,7 @@ cr_statement_at_import_rule_parse_from_buf (const guchar * a_buf, parser = NULL; } if (media_list) { - GList *cur = NULL; - for (cur = media_list; media_list; + for (; media_list; media_list = g_list_next (media_list)) { if (media_list->data) { cr_string_destroy ((CRString*)media_list->data); @@ -1463,7 +1463,9 @@ cr_statement_new_at_page_rule (CRStyleSheet * a_sheet, CRDeclaration * a_decl_list, CRString * a_name, CRString * a_pseudo) { - CRStatement *result = (CRStatement *)g_try_malloc (sizeof (CRStatement)); + CRStatement *result = NULL; + + result = (CRStatement *) g_try_malloc (sizeof (CRStatement)); if (!result) { cr_utils_trace_info ("Out of memory"); @@ -1473,7 +1475,7 @@ cr_statement_new_at_page_rule (CRStyleSheet * a_sheet, memset (result, 0, sizeof (CRStatement)); result->type = AT_PAGE_RULE_STMT; - result->kind.page_rule = (CRAtPageRule *)g_try_malloc (sizeof (CRAtPageRule)); + result->kind.page_rule = (CRAtPageRule *) g_try_malloc (sizeof (CRAtPageRule)); if (!result->kind.page_rule) { cr_utils_trace_info ("Out of memory"); @@ -1511,14 +1513,14 @@ cr_statement_at_page_rule_parse_from_buf (const guchar * a_buf, enum CREncoding a_encoding) { enum CRStatus status = CR_OK; + CRParser *parser = NULL; CRDocHandler *sac_handler = NULL; CRStatement *result = NULL; CRStatement **resultptr = NULL; g_return_val_if_fail (a_buf, NULL); - CRParser *parser = cr_parser_new_from_buf ((guchar*)a_buf, - strlen ((char *)a_buf), + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), a_encoding, FALSE); if (!parser) { cr_utils_trace_info ("Instanciation of the parser failed."); @@ -1584,9 +1586,11 @@ CRStatement * cr_statement_new_at_charset_rule (CRStyleSheet * a_sheet, CRString * a_charset) { + CRStatement *result = NULL; + g_return_val_if_fail (a_charset, NULL); - CRStatement *result = (CRStatement *)g_try_malloc (sizeof (CRStatement)); + result = (CRStatement *) g_try_malloc (sizeof (CRStatement)); if (!result) { cr_utils_trace_info ("Out of memory"); @@ -1596,7 +1600,7 @@ cr_statement_new_at_charset_rule (CRStyleSheet * a_sheet, memset (result, 0, sizeof (CRStatement)); result->type = AT_CHARSET_RULE_STMT; - result->kind.charset_rule = (CRAtCharsetRule *)g_try_malloc (sizeof (CRAtCharsetRule)); + result->kind.charset_rule = (CRAtCharsetRule *) g_try_malloc (sizeof (CRAtCharsetRule)); if (!result->kind.charset_rule) { cr_utils_trace_info ("Out of memory"); @@ -1626,13 +1630,13 @@ cr_statement_at_charset_rule_parse_from_buf (const guchar * a_buf, enum CREncoding a_encoding) { enum CRStatus status = CR_OK; + CRParser *parser = NULL; CRStatement *result = NULL; CRString *charset = NULL; g_return_val_if_fail (a_buf, NULL); - CRParser *parser = cr_parser_new_from_buf ((guchar*)a_buf, - strlen ((char *)a_buf), + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), a_encoding, FALSE); if (!parser) { cr_utils_trace_info ("Instanciation of the parser failed."); @@ -1678,7 +1682,9 @@ CRStatement * cr_statement_new_at_font_face_rule (CRStyleSheet * a_sheet, CRDeclaration * a_font_decls) { - CRStatement *result = (CRStatement *)g_try_malloc (sizeof (CRStatement)); + CRStatement *result = NULL; + + result = (CRStatement *) g_try_malloc (sizeof (CRStatement)); if (!result) { cr_utils_trace_info ("Out of memory"); @@ -1687,7 +1693,7 @@ cr_statement_new_at_font_face_rule (CRStyleSheet * a_sheet, memset (result, 0, sizeof (CRStatement)); result->type = AT_FONT_FACE_RULE_STMT; - result->kind.font_face_rule = (CRAtFontFaceRule *)g_try_malloc + result->kind.font_face_rule = (CRAtFontFaceRule *) g_try_malloc (sizeof (CRAtFontFaceRule)); if (!result->kind.font_face_rule) { @@ -1723,12 +1729,11 @@ cr_statement_font_face_rule_parse_from_buf (const guchar * a_buf, { CRStatement *result = NULL; CRStatement **resultptr = NULL; + CRParser *parser = NULL; CRDocHandler *sac_handler = NULL; enum CRStatus status = CR_OK; - CRParser *parser = (CRParser *)cr_parser_new_from_buf ( - (guchar*)a_buf, - strlen ((char *)a_buf), + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), a_encoding, FALSE); if (!parser) goto cleanup; @@ -2614,8 +2619,10 @@ cr_statement_dump (CRStatement const * a_this, FILE * a_fp, gulong a_indent) void cr_statement_dump_ruleset (CRStatement const * a_this, FILE * a_fp, glong a_indent) { + gchar *str = NULL; + g_return_if_fail (a_fp && a_this); - gchar *str = cr_statement_ruleset_to_string (a_this, a_indent); + str = cr_statement_ruleset_to_string (a_this, a_indent); if (str) { fprintf (a_fp, "%s", str); g_free (str); @@ -2661,9 +2668,11 @@ cr_statement_dump_font_face_rule (CRStatement const * a_this, FILE * a_fp, void cr_statement_dump_charset (CRStatement const * a_this, FILE * a_fp, gulong a_indent) { + gchar *str = NULL; + g_return_if_fail (a_this && a_this->type == AT_CHARSET_RULE_STMT); - gchar *str = cr_statement_charset_to_string (a_this, + str = cr_statement_charset_to_string (a_this, a_indent) ; if (str) { fprintf (a_fp, "%s", str) ; @@ -2685,11 +2694,13 @@ cr_statement_dump_charset (CRStatement const * a_this, FILE * a_fp, gulong a_ind void cr_statement_dump_page (CRStatement const * a_this, FILE * a_fp, gulong a_indent) { + gchar *str = NULL; + g_return_if_fail (a_this && a_this->type == AT_PAGE_RULE_STMT && a_this->kind.page_rule); - gchar *str = cr_statement_at_page_rule_to_string (a_this, a_indent) ; + str = cr_statement_at_page_rule_to_string (a_this, a_indent) ; if (str) { fprintf (a_fp, "%s", str); g_free (str) ; diff --git a/src/libcroco/cr-string.c b/src/libcroco/cr-string.c index 47d557d5b..86ad3432c 100644 --- a/src/libcroco/cr-string.c +++ b/src/libcroco/cr-string.c @@ -32,7 +32,9 @@ CRString * cr_string_new (void) { - CRString *result = (CRString *)g_try_malloc (sizeof (CRString)) ; + CRString *result = NULL ; + + result = (CRString *) g_try_malloc (sizeof (CRString)) ; if (!result) { cr_utils_trace_info ("Out of memory") ; return NULL ; @@ -51,7 +53,9 @@ cr_string_new (void) CRString * cr_string_new_from_string (const gchar * a_string) { - CRString *result = cr_string_new () ; + CRString *result = NULL ; + + result = cr_string_new () ; if (!result) { cr_utils_trace_info ("Out of memory") ; return NULL ; @@ -70,7 +74,9 @@ cr_string_new_from_string (const gchar * a_string) CRString * cr_string_new_from_gstring (GString const *a_string) { - CRString *result = cr_string_new () ; + CRString *result = NULL ; + + result = cr_string_new () ; if (!result) { cr_utils_trace_info ("Out of memory") ; return NULL ; @@ -87,9 +93,10 @@ cr_string_new_from_gstring (GString const *a_string) CRString * cr_string_dup (CRString const *a_this) { + CRString *result = NULL ; g_return_val_if_fail (a_this, NULL) ; - CRString *result = cr_string_new_from_gstring (a_this->stryng) ; + result = cr_string_new_from_gstring (a_this->stryng) ; if (!result) { cr_utils_trace_info ("Out of memory") ; return NULL ; diff --git a/src/libcroco/cr-style.c b/src/libcroco/cr-style.c index a9c5a5cec..2b865c248 100644 --- a/src/libcroco/cr-style.c +++ b/src/libcroco/cr-style.c @@ -140,9 +140,9 @@ static CRPropertyDesc gv_prop_table[] = { {"font-size", PROP_ID_FONT_SIZE}, {"font-style", PROP_ID_FONT_STYLE}, {"font-weight", PROP_ID_FONT_WEIGHT}, - {"white-space", PROP_ID_WHITE_SPACE}, + {"white-space", PROP_ID_WHITE_SPACE}, /*must be the last one */ - {NULL, (enum CRPropertyID)0} + {NULL, (enum CRPropertyID) 0} }; /** @@ -185,7 +185,7 @@ static struct CRNumPropEnumDumpInfo gv_num_props_dump_infos[] = { {NUM_PROP_MARGIN_BOTTOM, "margin-bottom"}, {NUM_PROP_MARGIN_LEFT, "margin-left"}, {NUM_PROP_WIDTH, "width"}, - {(enum CRNumProp)0, NULL} + {(enum CRNumProp) 0, NULL} }; struct CRRgbPropEnumDumpInfo { @@ -200,7 +200,7 @@ static struct CRRgbPropEnumDumpInfo gv_rgb_props_dump_infos[] = { {RGB_PROP_BORDER_LEFT_COLOR, "left-color"}, {RGB_PROP_COLOR, "color"}, {RGB_PROP_BACKGROUND_COLOR, "background-color"}, - {(enum CRRgbProp)0, NULL} + {(enum CRRgbProp) 0, NULL} }; struct CRBorderStylePropEnumDumpInfo { @@ -215,7 +215,7 @@ static struct CRBorderStylePropEnumDumpInfo gv_border_style_props_dump_infos[] {BORDER_STYLE_PROP_RIGHT, "border-style-right"}, {BORDER_STYLE_PROP_BOTTOM, "boder-style-bottom"}, {BORDER_STYLE_PROP_LEFT, "border-style-left"}, - {(enum CRBorderStyleProp)0, NULL} + {(enum CRBorderStyleProp) 0, NULL} }; static enum CRStatus @@ -319,9 +319,9 @@ set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value); static const gchar * num_prop_code_to_string (enum CRNumProp a_code) { - int len = sizeof (gv_num_props_dump_infos) / + guint len = sizeof (gv_num_props_dump_infos) / sizeof (struct CRNumPropEnumDumpInfo); - if ((int)a_code >= len) { + if (a_code >= len) { cr_utils_trace_info ("A field has been added " "to 'enum CRNumProp' and no matching" " entry has been " @@ -342,10 +342,10 @@ num_prop_code_to_string (enum CRNumProp a_code) static const gchar * rgb_prop_code_to_string (enum CRRgbProp a_code) { - int len = sizeof (gv_rgb_props_dump_infos) / + guint len = sizeof (gv_rgb_props_dump_infos) / sizeof (struct CRRgbPropEnumDumpInfo); - if ((int)a_code >= len) { + if (a_code >= len) { cr_utils_trace_info ("A field has been added " "to 'enum CRRgbProp' and no matching" " entry has been " @@ -366,10 +366,10 @@ rgb_prop_code_to_string (enum CRRgbProp a_code) static const gchar * border_style_prop_code_to_string (enum CRBorderStyleProp a_code) { - int len = sizeof (gv_border_style_props_dump_infos) / + guint len = sizeof (gv_border_style_props_dump_infos) / sizeof (struct CRBorderStylePropEnumDumpInfo); - if ((int)a_code >= len) { + if (a_code >= len) { cr_utils_trace_info ("A field has been added " "to 'enum CRBorderStyleProp' and no matching" " entry has been " @@ -421,7 +421,7 @@ cr_style_get_prop_id (const guchar * a_prop) cr_style_init_properties (); } - raw_id = (gpointer *)g_hash_table_lookup (gv_prop_hash, a_prop); + raw_id = (gpointer *) g_hash_table_lookup (gv_prop_hash, a_prop); if (!raw_id) { return PROP_ID_NOT_KNOWN; } @@ -465,7 +465,7 @@ set_prop_padding_x_from_value (CRStyle * a_style, if (a_value->content.str && a_value->content.str->stryng && a_value->content.str->stryng->str - && !strncmp ("inherit", + && !strncmp ((const char *) "inherit", a_value->content.str->stryng->str, sizeof ("inherit")-1)) { status = cr_num_set (num_val, 0.0, NUM_INHERIT); @@ -569,9 +569,10 @@ static enum CRStatus set_prop_border_width_from_value (CRStyle *a_style, CRTerm *a_value) { + CRTerm *cur_term = NULL ; g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR) ; - CRTerm *cur_term = a_value ; + cur_term = a_value ; if (!cur_term) return CR_ERROR ; @@ -579,7 +580,7 @@ set_prop_border_width_from_value (CRStyle *a_style, int dir; for (dir = (int) DIR_TOP ; dir < (int)NB_DIRS ; dir++) { enum CRDirection direction = (enum CRDirection)dir; - set_prop_border_x_width_from_value (a_style, + set_prop_border_x_width_from_value (a_style, cur_term, direction) ; } @@ -696,16 +697,18 @@ static enum CRStatus set_prop_border_style_from_value (CRStyle *a_style, CRTerm *a_value) { + CRTerm *cur_term = NULL ; + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR) ; - CRTerm *cur_term = a_value ; + cur_term = a_value ; if (!cur_term || cur_term->type != TERM_IDENT) { return CR_ERROR ; } int dir; - for (dir = (int)DIR_TOP ; dir < (int)NB_DIRS ; dir++) { + for (dir = (int)DIR_TOP ; dir < (int)NB_DIRS ; dir++) { enum CRDirection direction = (enum CRDirection)dir; set_prop_border_x_style_from_value (a_style, cur_term, @@ -908,7 +911,7 @@ set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value) break; } - return CR_OK; + return status; } static enum CRStatus @@ -1115,11 +1118,11 @@ set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value, && a_value->content.str->stryng->str) { status = cr_rgb_set_from_name (rgb_color, - (guchar *)a_value->content.str->stryng->str); + (const guchar *) a_value->content.str->stryng->str); } if (status != CR_OK) { - cr_rgb_set_from_name (rgb_color, (guchar *)"black"); + cr_rgb_set_from_name (rgb_color, (const guchar *) "black"); } } else if (a_value->type == TERM_RGB) { if (a_value->content.rgb) { @@ -1354,7 +1357,7 @@ set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value) && cur_term->content.str->stryng->str) { cur_ff = cr_font_family_new (FONT_FAMILY_NON_GENERIC, - (guchar *)cur_term->content.str->stryng->str); + (guchar *) cur_term->content.str->stryng->str); } } break; @@ -1707,7 +1710,9 @@ set_prop_white_space_from_value (CRStyle * a_style, CRTerm * a_value) CRStyle * cr_style_new (gboolean a_set_props_to_initial_values) { - CRStyle *result = (CRStyle *)g_try_malloc (sizeof (CRStyle)); + CRStyle *result = NULL; + + result = (CRStyle *) g_try_malloc (sizeof (CRStyle)); if (!result) { cr_utils_trace_info ("Out of memory"); return NULL; @@ -2018,7 +2023,7 @@ cr_style_set_style_from_decl (CRStyle * a_this, CRDeclaration * a_decl) CR_BAD_PARAM_ERROR); prop_id = cr_style_get_prop_id - ((guchar *)a_decl->property->stryng->str); + ((const guchar *) a_decl->property->stryng->str); value = a_decl->value; switch (prop_id) { @@ -2676,7 +2681,7 @@ cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent) *before outputing it value */ cr_utils_dump_n_chars2 (' ', str, indent); - tmp_str = (gchar *) num_prop_code_to_string ((enum CRNumProp)i); + tmp_str = (gchar *) num_prop_code_to_string ((enum CRNumProp) i); if (tmp_str) { g_string_append_printf (str, "%s: ", tmp_str); } else { @@ -2690,7 +2695,7 @@ cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent) } /*loop over the rgb_props and to_string() them all */ for (i = RGB_PROP_BORDER_TOP_COLOR; i < NB_RGB_PROPS; i++) { - tmp_str = (gchar *) rgb_prop_code_to_string ((enum CRRgbProp)i); + tmp_str = (gchar *) rgb_prop_code_to_string ((enum CRRgbProp) i); cr_utils_dump_n_chars2 (' ', str, indent); if (tmp_str) { g_string_append_printf (str, "%s: ", tmp_str); @@ -2705,8 +2710,7 @@ cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent) } /*loop over the border_style_props and to_string() them */ for (i = BORDER_STYLE_PROP_TOP; i < NB_BORDER_STYLE_PROPS; i++) { - tmp_str = (gchar *) - border_style_prop_code_to_string ((enum CRBorderStyleProp)i); + tmp_str = (gchar *) border_style_prop_code_to_string ((enum CRBorderStyleProp) i); cr_utils_dump_n_chars2 (' ', str, indent); if (tmp_str) { g_string_append_printf (str, "%s: ", tmp_str); @@ -2741,7 +2745,7 @@ cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent) cr_utils_dump_n_chars2 (' ', str, indent); g_string_append (str, "font-family: "); - tmp_str = (gchar *)cr_font_family_to_string (a_this->font_family, TRUE); + tmp_str = (gchar *) cr_font_family_to_string (a_this->font_family, TRUE); if (tmp_str) { g_string_append (str, tmp_str); g_free (tmp_str); diff --git a/src/libcroco/cr-stylesheet.c b/src/libcroco/cr-stylesheet.c index 1b26c64bf..cb5de6958 100644 --- a/src/libcroco/cr-stylesheet.c +++ b/src/libcroco/cr-stylesheet.c @@ -36,7 +36,9 @@ CRStyleSheet * cr_stylesheet_new (CRStatement * a_stmts) { - CRStyleSheet *result = (CRStyleSheet *)g_try_malloc (sizeof (CRStyleSheet)); + CRStyleSheet *result; + + result = (CRStyleSheet *) g_try_malloc (sizeof (CRStyleSheet)); if (!result) { cr_utils_trace_info ("Out of memory"); return NULL; diff --git a/src/libcroco/cr-term.c b/src/libcroco/cr-term.c index 09b6354db..1c50aed2a 100644 --- a/src/libcroco/cr-term.c +++ b/src/libcroco/cr-term.c @@ -84,7 +84,9 @@ cr_term_clear (CRTerm * a_this) CRTerm * cr_term_new (void) { - CRTerm *result = (CRTerm *)g_try_malloc (sizeof (CRTerm)); + CRTerm *result = NULL; + + result = (CRTerm *) g_try_malloc (sizeof (CRTerm)); if (!result) { cr_utils_trace_info ("Out of memory"); return NULL; @@ -104,15 +106,14 @@ CRTerm * cr_term_parse_expression_from_buf (const guchar * a_buf, enum CREncoding a_encoding) { + CRParser *parser = NULL; CRTerm *result = NULL; enum CRStatus status = CR_OK; g_return_val_if_fail (a_buf, NULL); - CRParser *parser = cr_parser_new_from_buf ( - (guchar*)a_buf, - strlen ((char *)a_buf), - a_encoding, FALSE); + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), + a_encoding, FALSE); g_return_val_if_fail (parser, NULL); status = cr_parser_try_to_skip_spaces_and_comments (parser); @@ -279,8 +280,8 @@ cr_term_to_string (CRTerm const * a_this) { GString *str_buf = NULL; CRTerm const *cur = NULL; - guchar *result = NULL; - gchar *content = NULL; + guchar *result = NULL, + *content = NULL; g_return_val_if_fail (a_this, NULL); @@ -329,11 +330,11 @@ cr_term_to_string (CRTerm const * a_this) switch (cur->type) { case TERM_NUMBER: if (cur->content.num) { - content = (gchar *)cr_num_to_string (cur->content.num); + content = cr_num_to_string (cur->content.num); } if (content) { - g_string_append (str_buf, content); + g_string_append (str_buf, (const gchar *) content); g_free (content); content = NULL; } @@ -342,7 +343,7 @@ cr_term_to_string (CRTerm const * a_this) case TERM_FUNCTION: if (cur->content.str) { - content = g_strndup + content = (guchar *) g_strndup (cur->content.str->stryng->str, cur->content.str->stryng->len); } @@ -360,22 +361,21 @@ cr_term_to_string (CRTerm const * a_this) if (tmp_str) { g_string_append (str_buf, - (gchar *)tmp_str); + (const gchar *) tmp_str); g_free (tmp_str); tmp_str = NULL; } - } + g_string_append (str_buf, ")"); g_free (content); content = NULL; - g_string_append (str_buf, ")"); } break; case TERM_STRING: if (cur->content.str) { - content = g_strndup + content = (guchar *) g_strndup (cur->content.str->stryng->str, cur->content.str->stryng->len); } @@ -390,13 +390,13 @@ cr_term_to_string (CRTerm const * a_this) case TERM_IDENT: if (cur->content.str) { - content = g_strndup + content = (guchar *) g_strndup (cur->content.str->stryng->str, cur->content.str->stryng->len); } if (content) { - g_string_append (str_buf, content); + g_string_append (str_buf, (const gchar *) content); g_free (content); content = NULL; } @@ -404,9 +404,9 @@ cr_term_to_string (CRTerm const * a_this) case TERM_URI: if (cur->content.str) { - content = g_strndup - (cur->content.str->stryng->str, - cur->content.str->stryng->len); + content = (guchar *) g_strndup + (cur->content.str->stryng->str, + cur->content.str->stryng->len); } if (content) { @@ -425,7 +425,7 @@ cr_term_to_string (CRTerm const * a_this) tmp_str = cr_rgb_to_string (cur->content.rgb); if (tmp_str) { - g_string_append (str_buf, (gchar *)tmp_str); + g_string_append (str_buf, (const gchar *) tmp_str); g_free (tmp_str); tmp_str = NULL; } @@ -442,7 +442,7 @@ cr_term_to_string (CRTerm const * a_this) case TERM_HASH: if (cur->content.str) { - content = g_strndup + content = (guchar *) g_strndup (cur->content.str->stryng->str, cur->content.str->stryng->len); } @@ -463,7 +463,7 @@ cr_term_to_string (CRTerm const * a_this) } if (str_buf) { - result = (guchar *)str_buf->str; + result =(guchar *) str_buf->str; g_string_free (str_buf, FALSE); str_buf = NULL; } @@ -475,8 +475,8 @@ guchar * cr_term_one_to_string (CRTerm const * a_this) { GString *str_buf = NULL; - guchar *result = NULL; - gchar *content = NULL; + guchar *result = NULL, + *content = NULL; g_return_val_if_fail (a_this, NULL); @@ -524,11 +524,11 @@ cr_term_one_to_string (CRTerm const * a_this) switch (a_this->type) { case TERM_NUMBER: if (a_this->content.num) { - content = (gchar *)cr_num_to_string (a_this->content.num); + content = cr_num_to_string (a_this->content.num); } if (content) { - g_string_append (str_buf, content); + g_string_append (str_buf, (const gchar *) content); g_free (content); content = NULL; } @@ -537,7 +537,7 @@ cr_term_one_to_string (CRTerm const * a_this) case TERM_FUNCTION: if (a_this->content.str) { - content = g_strndup + content = (guchar *) g_strndup (a_this->content.str->stryng->str, a_this->content.str->stryng->len); } @@ -571,7 +571,7 @@ cr_term_one_to_string (CRTerm const * a_this) case TERM_STRING: if (a_this->content.str) { - content = g_strndup + content = (guchar *) g_strndup (a_this->content.str->stryng->str, a_this->content.str->stryng->len); } @@ -586,13 +586,13 @@ cr_term_one_to_string (CRTerm const * a_this) case TERM_IDENT: if (a_this->content.str) { - content = g_strndup + content = (guchar *) g_strndup (a_this->content.str->stryng->str, a_this->content.str->stryng->len); } if (content) { - g_string_append (str_buf, content); + g_string_append (str_buf, (const gchar *) content); g_free (content); content = NULL; } @@ -600,7 +600,7 @@ cr_term_one_to_string (CRTerm const * a_this) case TERM_URI: if (a_this->content.str) { - content = g_strndup + content = (guchar *) g_strndup (a_this->content.str->stryng->str, a_this->content.str->stryng->len); } @@ -615,12 +615,13 @@ cr_term_one_to_string (CRTerm const * a_this) case TERM_RGB: if (a_this->content.rgb) { + guchar *tmp_str = NULL; g_string_append_printf (str_buf, "rgb("); - gchar *tmp_str = (gchar *)cr_rgb_to_string (a_this->content.rgb); + tmp_str = cr_rgb_to_string (a_this->content.rgb); if (tmp_str) { - g_string_append (str_buf, tmp_str); + g_string_append (str_buf, (const gchar *) tmp_str); g_free (tmp_str); tmp_str = NULL; } @@ -637,7 +638,7 @@ cr_term_one_to_string (CRTerm const * a_this) case TERM_HASH: if (a_this->content.str) { - content = g_strndup + content = (guchar *) g_strndup (a_this->content.str->stryng->str, a_this->content.str->stryng->len); } @@ -658,7 +659,7 @@ cr_term_one_to_string (CRTerm const * a_this) } if (str_buf) { - result = (guchar *)str_buf->str; + result = (guchar *) str_buf->str; g_string_free (str_buf, FALSE); str_buf = NULL; } diff --git a/src/libcroco/cr-tknzr.c b/src/libcroco/cr-tknzr.c index 1f762b5c5..228471bf9 100644 --- a/src/libcroco/cr-tknzr.c +++ b/src/libcroco/cr-tknzr.c @@ -1586,7 +1586,9 @@ cr_tknzr_parse_num (CRTknzr * a_this, CRTknzr * cr_tknzr_new (CRInput * a_input) { - CRTknzr *result = (CRTknzr *)g_try_malloc (sizeof (CRTknzr)); + CRTknzr *result = NULL; + + result = (CRTknzr *) g_try_malloc (sizeof (CRTknzr)); if (result == NULL) { cr_utils_trace_info ("Out of memory"); @@ -1636,7 +1638,9 @@ cr_tknzr_new_from_uri (const guchar * a_file_uri, enum CREncoding a_enc) { CRTknzr *result = NULL; - CRInput *input = cr_input_new_from_uri ((gchar *)a_file_uri, a_enc); + CRInput *input = NULL; + + input = cr_input_new_from_uri ((const gchar *) a_file_uri, a_enc); g_return_val_if_fail (input != NULL, NULL); result = cr_tknzr_new (input); @@ -1909,7 +1913,7 @@ cr_tknzr_consume_chars (CRTknzr * a_this, guint32 a_char, glong * a_nb_char) } return cr_input_consume_chars (PRIVATE (a_this)->input, - a_char, (gulong *)a_nb_char); + a_char, a_nb_char); } enum CRStatus @@ -2097,15 +2101,15 @@ cr_tknzr_get_next_token (CRTknzr * a_this, CRToken ** a_tk) if (BYTE (input, 2, NULL) == 'r' && BYTE (input, 3, NULL) == 'l' && BYTE (input, 4, NULL) == '(') { - CRString *str = NULL; + CRString *str2 = NULL; - status = cr_tknzr_parse_uri (a_this, &str); + status = cr_tknzr_parse_uri (a_this, &str2); if (status == CR_OK) { - status = cr_token_set_uri (token, str); + status = cr_token_set_uri (token, str2); CHECK_PARSING_STATUS (status, TRUE); - if (str) { + if (str2) { cr_parsing_location_copy (&token->location, - &str->location) ; + &str2->location) ; } goto done; } diff --git a/src/libcroco/cr-token.c b/src/libcroco/cr-token.c index 3dd73ac3e..dfe83e221 100644 --- a/src/libcroco/cr-token.c +++ b/src/libcroco/cr-token.c @@ -133,7 +133,9 @@ cr_token_clear (CRToken * a_this) CRToken * cr_token_new (void) { - CRToken *result = (CRToken *)g_try_malloc (sizeof (CRToken)); + CRToken *result = NULL; + + result = (CRToken *) g_try_malloc (sizeof (CRToken)); if (result == NULL) { cr_utils_trace_info ("Out of memory"); diff --git a/src/libcroco/cr-utils.c b/src/libcroco/cr-utils.c index a51c76920..bfb587017 100644 --- a/src/libcroco/cr-utils.c +++ b/src/libcroco/cr-utils.c @@ -429,9 +429,8 @@ cr_utils_read_char_from_utf8_buf (const guchar * a_in, gulong a_in_len, guint32 * a_out, gulong * a_consumed) { - gulong in_len = 0, - in_index = 0, - nb_bytes_2_decode = 0; + gulong in_index = 0, + nb_bytes_2_decode = 0; enum CRStatus status = CR_OK; /* @@ -448,8 +447,6 @@ cr_utils_read_char_from_utf8_buf (const guchar * a_in, goto end; } - in_len = a_in_len; - if (*a_in <= 0x7F) { /* *7 bits long char @@ -901,15 +898,10 @@ cr_utils_ucs1_to_utf8 (const guchar * a_in, if (*a_in_len == 0) { *a_out_len = 0 ; - return CR_OK ; + return status; } g_return_val_if_fail (a_out, CR_BAD_PARAM_ERROR) ; - if (*a_in_len < 1) { - status = CR_OK; - goto end; - } - in_len = *a_in_len; out_len = *a_out_len; @@ -930,11 +922,10 @@ cr_utils_ucs1_to_utf8 (const guchar * a_in, } } /*end for */ - end: *a_in_len = in_index; *a_out_len = out_index; - return CR_OK; + return status; } /** @@ -951,8 +942,7 @@ cr_utils_ucs1_str_to_utf8 (const guchar * a_in, gulong * a_in_len, guchar ** a_out, gulong * a_out_len) { - gulong in_len = 0, - out_len = 0; + gulong out_len = 0; enum CRStatus status = CR_OK; g_return_val_if_fail (a_in && a_in_len && a_out @@ -969,8 +959,6 @@ cr_utils_ucs1_str_to_utf8 (const guchar * a_in, g_return_val_if_fail (status == CR_OK, status); - in_len = *a_in_len; - *a_out = (guchar *) g_malloc0 (out_len); status = cr_utils_ucs1_to_utf8 (a_in, a_in_len, *a_out, &out_len); @@ -1023,7 +1011,6 @@ cr_utils_utf8_to_ucs1 (const guchar * a_in, && a_out && a_out_len, CR_BAD_PARAM_ERROR); if (*a_in_len < 1) { - status = CR_OK; goto end; } @@ -1102,7 +1089,6 @@ cr_utils_utf8_to_ucs1 (const guchar * a_in, *(if any) to get the current character. */ if (in_index + nb_bytes_2_decode - 1 >= in_len) { - status = CR_OK; goto end; } @@ -1136,7 +1122,7 @@ cr_utils_utf8_to_ucs1 (const guchar * a_in, *a_out_len = out_index; *a_in_len = in_index; - return CR_OK; + return status; } /** -- cgit v1.2.3 From 2eb442ffbe3a13afe002df5aca335cbefaed156b Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Sat, 7 Nov 2015 20:06:34 +0100 Subject: static code analysis (bzr r14450) --- src/selection.cpp | 52 +++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/selection.cpp b/src/selection.cpp index 77a507eec..020912381 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -255,7 +255,7 @@ void Selection::addList(std::vector const &list) { _invalidateCachedLists(); - for ( std::vector::const_iterator iter=list.begin();iter!=list.end();iter++ ) { + for ( std::vector::const_iterator iter=list.begin();iter!=list.end(); ++iter) { SPObject *obj = *iter; if (includes(obj)) continue; _add (obj); @@ -267,7 +267,7 @@ void Selection::addList(std::vector const &list) { void Selection::setReprList(std::vector const &list) { _clear(); - for ( std::vector::const_reverse_iterator iter=list.rbegin();iter!=list.rend();iter++ ) { + for ( std::vector::const_reverse_iterator iter=list.rbegin();iter!=list.rend(); ++iter) { SPObject *obj=_objectForXMLNode(*iter); if (obj) { _add(obj); @@ -286,7 +286,7 @@ std::vector const &Selection::list() { if(!_objs_vector.empty()) return _objs_vector; - for ( std::list::const_iterator iter=_objs.begin();iter!=_objs.end();iter++ ) { + for ( std::list::const_iterator iter=_objs.begin();iter!=_objs.end(); ++iter) { _objs_vector.push_back(*iter); } return _objs_vector; @@ -298,7 +298,7 @@ std::vector const &Selection::itemList() { return _items; } - for ( std::list::const_iterator iter=_objs.begin();iter!=_objs.end();iter++ ) { + for ( std::list::const_iterator iter=_objs.begin();iter!=_objs.end(); ++iter) { SPObject *obj=*iter; if (SP_IS_ITEM(obj)) { _items.push_back(SP_ITEM(obj)); @@ -310,7 +310,7 @@ std::vector const &Selection::itemList() { std::vector const &Selection::reprList() { if (!_reprs.empty()) { return _reprs; } std::vector list = itemList(); - for ( std::vector::const_iterator iter=list.begin();iter!=list.end();iter++ ) { + for ( std::vector::const_iterator iter=list.begin();iter!=list.end(); ++iter) { SPObject *obj = *iter; _reprs.push_back(obj->getRepr()); } @@ -372,7 +372,7 @@ SPItem *Selection::_sizeistItem(bool sml, Selection::CompareSize compare) { gdouble max = sml ? 1e18 : 0; SPItem *ist = NULL; - for ( std::vector::const_iterator i=items.begin();i!=items.end();i++ ) { + for ( std::vector::const_iterator i=items.begin();i!=items.end(); ++i) { Geom::OptRect obox = SP_ITEM(*i)->desktopPreferredBounds(); if (!obox || obox.isEmpty()) continue; Geom::Rect bbox = *obox; @@ -404,7 +404,7 @@ Geom::OptRect Selection::geometricBounds() const std::vector const items = const_cast(this)->itemList(); Geom::OptRect bbox; - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { + for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { bbox.unionWith(SP_ITEM(*iter)->desktopGeometricBounds()); } return bbox; @@ -415,7 +415,7 @@ Geom::OptRect Selection::visualBounds() const std::vector const items = const_cast(this)->itemList(); Geom::OptRect bbox; - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { + for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { bbox.unionWith(SP_ITEM(*iter)->desktopVisualBounds()); } return bbox; @@ -436,7 +436,7 @@ Geom::OptRect Selection::documentBounds(SPItem::BBoxType type) const std::vector const items = const_cast(this)->itemList(); if (items.empty()) return bbox; - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { + for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { SPItem *item = SP_ITEM(*iter); bbox |= item->documentBounds(type); } @@ -463,19 +463,21 @@ boost::optional Selection::center() const { } std::vector Selection::getSnapPoints(SnapPreferences const *snapprefs) const { - std::vector const items = const_cast(this)->itemList(); - - SnapPreferences snapprefs_dummy = *snapprefs; // create a local copy of the snapping prefs - snapprefs_dummy.setTargetSnappable(Inkscape::SNAPTARGET_ROTATION_CENTER, false); // locally disable snapping to the item center std::vector p; - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { - SPItem *this_item = *iter; - this_item->getSnappoints(p, &snapprefs_dummy); - - //Include the transformation origin for snapping - //For a selection or group only the overall center is considered, not for each item individually - if (snapprefs != NULL && snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_ROTATION_CENTER)) { - p.push_back(Inkscape::SnapCandidatePoint(this_item->getCenter(), SNAPSOURCE_ROTATION_CENTER)); + + if (snapprefs != NULL){ + SnapPreferences snapprefs_dummy = *snapprefs; // create a local copy of the snapping prefs + snapprefs_dummy.setTargetSnappable(Inkscape::SNAPTARGET_ROTATION_CENTER, false); // locally disable snapping to the item center + std::vector const items = const_cast(this)->itemList(); + for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { + SPItem *this_item = *iter; + this_item->getSnappoints(p, &snapprefs_dummy); + + //Include the transformation origin for snapping + //For a selection or group only the overall center is considered, not for each item individually + if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_ROTATION_CENTER)) { + p.push_back(Inkscape::SnapCandidatePoint(this_item->getCenter(), SNAPSOURCE_ROTATION_CENTER)); + } } } @@ -484,7 +486,7 @@ std::vector Selection::getSnapPoints(SnapPreferenc void Selection::_removeObjectDescendants(SPObject *obj) { std::vector toremove; - for ( std::list::const_iterator iter=_objs.begin();iter!=_objs.end();iter++ ) { + for ( std::list::const_iterator iter=_objs.begin();iter!=_objs.end(); ++iter) { SPObject *sel_obj= dynamic_cast(*iter); SPObject *parent = sel_obj->parent; while (parent) { @@ -495,7 +497,7 @@ void Selection::_removeObjectDescendants(SPObject *obj) { parent = parent->parent; } } - for ( std::vector::const_iterator iter=toremove.begin();iter!=toremove.end();iter++ ) { + for ( std::vector::const_iterator iter=toremove.begin();iter!=toremove.end(); ++iter) { _remove(*iter); } } @@ -522,7 +524,7 @@ SPObject *Selection::_objectForXMLNode(Inkscape::XML::Node *repr) const { size_t Selection::numberOfLayers() { std::vector const items = const_cast(this)->itemList(); std::set layers; - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { + for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { SPObject *layer = _layers->layerForObject(*iter); layers.insert(layer); } @@ -532,7 +534,7 @@ size_t Selection::numberOfLayers() { size_t Selection::numberOfParents() { std::vector const items = const_cast(this)->itemList(); std::set parents; - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { + for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { SPObject *parent = (*iter)->parent; parents.insert(parent); } -- cgit v1.2.3 From e27c914a9673a447a13e1be8eba799939100acf7 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Sat, 7 Nov 2015 20:15:21 +0100 Subject: static code analysis (bzr r14451) --- src/sp-clippath.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/sp-clippath.h b/src/sp-clippath.h index c9a8c68df..8abe97f3f 100644 --- a/src/sp-clippath.h +++ b/src/sp-clippath.h @@ -93,10 +93,10 @@ protected: Inkscape::XML::Node * const owner_repr = owner->getRepr(); //XML Tree being used directly here while it shouldn't be... Inkscape::XML::Node * const obj_repr = obj->getRepr(); - char const * owner_name = NULL; - char const * owner_clippath = NULL; - char const * obj_name = NULL; - char const * obj_id = NULL; + char const * owner_name = ""; + char const * owner_clippath = ""; + char const * obj_name = ""; + char const * obj_id = ""; if (owner_repr != NULL) { owner_name = owner_repr->name(); owner_clippath = owner_repr->attribute("clippath"); -- cgit v1.2.3 From ac14e8884b153cf94b7c88d21ad06efadd9373ce Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 7 Nov 2015 21:57:55 +0100 Subject: Use color if trace dialog is disabled (bzr r14422.1.43) --- src/ui/dialog/clonetiler.cpp | 2 +- src/ui/tools/spray-tool.cpp | 14 ++++++++++++-- src/widgets/spray-toolbar.cpp | 6 +++--- 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index e842cf78f..1ea80e9f7 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -3017,7 +3017,7 @@ 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, true); + gtk_toggle_button_set_active ((GtkToggleButton *) b, false); } diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 03a225b6e..a57d1db5e 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -538,6 +538,7 @@ static bool fit_item(SPDesktop *desktop, if(!nooverlap){ doc->ensureUpToDate(); } + bool trace = prefs->getBool("/dialogs/clonetiler/dotrace"); int pick = prefs->getInt("/dialogs/clonetiler/pick"); bool pick_to_presence = prefs->getBool("/dialogs/clonetiler/pick_to_presence", false); bool pick_to_color = prefs->getBool("/dialogs/clonetiler/pick_to_color"); @@ -561,7 +562,7 @@ static bool fit_item(SPDesktop *desktop, return false; } - if(picker){ + if(picker && trace){ float hsl[3]; sp_color_rgb_to_hsl_floatv (hsl, r, g, b); @@ -675,7 +676,7 @@ static bool fit_item(SPDesktop *desktop, if (pick_to_presence) { if (g_random_double_range (0, 1) > val) { //Hidding the element is a way to retain original - //beabiohur of tiled clones for presence option. + //behabiohur of tiled clones for presence option. sp_repr_css_set_property(css, "opacity", "0"); } } @@ -692,6 +693,15 @@ static bool fit_item(SPDesktop *desktop, return false; } } + if(!trace){ + sp_svg_write_color(color_string, sizeof(color_string), rgba); + if(pickfill){ + sp_repr_css_set_property(css, "fill", color_string); + } + if(pickstroke){ + sp_repr_css_set_property(css, "stroke", color_string); + } + } if(!nooverlap && (picker || visible)){ for (std::vector::const_iterator k=items_down.begin(); k!=items_down.end(); k++) { SPItem *item_hidden = *k; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index fa9722bdb..cfd3c6332 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -424,8 +424,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Picker */ { InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction", - _("Pick down. Fill or Stroke must be unset on original when spraying color to clones"), - _("Pick down. Fill or Stroke must be unset on original when spraying color to clones"), + _("Pick down. You can use trace clones dialog for avanced effects. In clone mode original fill or stroke colors must be unset"), + _("Pick down. You can use trace clones dialog for avanced effects. In clone mode original fill or stroke colors must be unset"), INKSCAPE_ICON("color-picker"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picker", false) ); @@ -504,7 +504,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Offset */ { EgeAdjustmentAction *eact = create_adjustment_action( "SprayToolOffsetAction", - _("Offset precent"), _("Offset percent:"), + _("Offset %"), _("Offset %:"), _("Increase to segregate objects more (value in percent)"), "/tools/spray/offset", 100, GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, -- cgit v1.2.3 From d2b9a1e46cd23379f3800ea65cd3f3337f4d1f1e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 7 Nov 2015 22:27:41 +0100 Subject: Fix for scale bug pointed by Mc- (bzr r14422.1.45) --- src/ui/tools/spray-tool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index a57d1db5e..6af30b5fc 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -459,7 +459,8 @@ static bool fit_item(SPDesktop *desktop, } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool pick_to_size = prefs->getBool("/dialogs/clonetiler/pick_to_size"); - if(picker && pick_to_size && !trace_scale){ + bool trace = prefs->getBool("/dialogs/clonetiler/dotrace"); + if(picker && pick_to_size && !trace_scale && trace){ _scale = 0.1; } Geom::OptRect bbox_procesed = Geom::Rect(Geom::Point(bbox->left() - offset_min, bbox->top() - offset_min),Geom::Point(bbox->right() + offset_min, bbox->bottom() + offset_min)); @@ -538,7 +539,6 @@ static bool fit_item(SPDesktop *desktop, if(!nooverlap){ doc->ensureUpToDate(); } - bool trace = prefs->getBool("/dialogs/clonetiler/dotrace"); int pick = prefs->getInt("/dialogs/clonetiler/pick"); bool pick_to_presence = prefs->getBool("/dialogs/clonetiler/pick_to_presence", false); bool pick_to_color = prefs->getBool("/dialogs/clonetiler/pick_to_color"); -- cgit v1.2.3 From 26783ada6dd88c1f2df732707628bae6a4d68e42 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 8 Nov 2015 00:18:24 +0100 Subject: Fixes from review form Mc- (bzr r14422.1.46) --- src/ui/dialog/clonetiler.cpp | 6 +++--- src/ui/tools/spray-tool.cpp | 5 +---- src/widgets/spray-toolbar.cpp | 6 ++---- 3 files changed, 6 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index 1ea80e9f7..fd8afd4a3 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -785,11 +785,11 @@ CloneTiler::CloneTiler () : #endif gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); - b = gtk_check_button_new_with_label (_("Trace the drawing under the tiles/spray tool")); + 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/ Sprayed item, pick a value from the drawing in that clone's or item spayed location and apply it")); + gtk_widget_set_tooltip_text (b, _("For each clone/sparayed 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", @@ -998,7 +998,7 @@ CloneTiler::CloneTiler () : gtk_widget_set_sensitive (vvb, prefs->getBool(prefs_path + "dotrace")); } } - // Info + { #if GTK_CHECK_VERSION(3,0,0) GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, VB_MARGIN); diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 6af30b5fc..17b82fe1d 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -331,7 +331,6 @@ 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); - //g_warning("Pressure, population: %f, %f", pressure, pressure * tc->population); return pressure * tc->width; } @@ -353,14 +352,12 @@ static double get_path_standard_deviation(SprayTool *tc) static double get_population(SprayTool *tc) { double pressure = (tc->usepressurepopulation? tc->pressure / TC_DEFAULT_PRESSURE : 1); - //g_warning("Pressure, population: %f, %f", pressure, pressure * tc->population); return pressure * tc->population; } static double get_pressure(SprayTool *tc) { double pressure = tc->pressure / TC_DEFAULT_PRESSURE; - //g_warning("Pressure, population: %f, %f", pressure, pressure * tc->population); return pressure; } @@ -676,7 +673,7 @@ static bool fit_item(SPDesktop *desktop, if (pick_to_presence) { if (g_random_double_range (0, 1) > val) { //Hidding the element is a way to retain original - //behabiohur of tiled clones for presence option. + //behaviour of tiled clones for presence option. sp_repr_css_set_property(css, "opacity", "0"); } } diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index cfd3c6332..5e0d81964 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -424,8 +424,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Picker */ { InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction", - _("Pick down. You can use trace clones dialog for avanced effects. In clone mode original fill or stroke colors must be unset"), - _("Pick down. You can use trace clones dialog for avanced effects. In clone mode original fill or stroke colors must be unset"), + _("Pick color from the drawing. You can use clonetiler trace dialog for avanced effects. In clone mode original fill or stroke colors must be unset."), + _("Pick color from the drawing. You can use clonetiler trace dialog for avanced effects. In clone mode original fill or stroke colors must be unset."), INKSCAPE_ICON("color-picker"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picker", false) ); @@ -495,8 +495,6 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/nooverlap", false) ); g_object_set_data( holder, "nooverlap", act ); - //g_object_set_data (context_object, "holder", holder); - //g_object_set_data (context_object, "desktop", desktop); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_nooverlap), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } -- cgit v1.2.3 From 298e5a9a28984e062b3901172cdc356836266d58 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 8 Nov 2015 10:49:26 +0100 Subject: Fix a typo (bzr r14422.1.47) --- src/ui/dialog/clonetiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index fd8afd4a3..fbd050f8e 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -789,7 +789,7 @@ CloneTiler::CloneTiler () : 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/sparayed item, pick a value from the drawing in its location and apply it")); + 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", -- cgit v1.2.3 From 6f6964733c7de8c54dc60f946e10ea66bac269ea Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 8 Nov 2015 17:41:53 +0000 Subject: Use external Potrace (bzr r14449.1.1) --- src/trace/Makefile_insert | 17 +- src/trace/potrace/auxiliary.h | 80 -- src/trace/potrace/bitops.h | 83 --- src/trace/potrace/curve.cpp | 108 --- src/trace/potrace/curve.h | 77 -- src/trace/potrace/decompose.cpp | 511 ------------- src/trace/potrace/decompose.h | 16 - src/trace/potrace/greymap.cpp | 941 ------------------------ src/trace/potrace/greymap.h | 58 -- src/trace/potrace/inkscape-potrace.cpp | 7 +- src/trace/potrace/inkscape-potrace.h | 2 +- src/trace/potrace/lists.h | 285 -------- src/trace/potrace/potracelib.cpp | 128 ---- src/trace/potrace/potracelib.h | 139 ---- src/trace/potrace/progress.h | 77 -- src/trace/potrace/render.cpp | 243 ------- src/trace/potrace/render.h | 27 - src/trace/potrace/trace.cpp | 1245 -------------------------------- src/trace/potrace/trace.h | 15 - 19 files changed, 5 insertions(+), 4054 deletions(-) delete mode 100644 src/trace/potrace/auxiliary.h delete mode 100644 src/trace/potrace/bitops.h delete mode 100644 src/trace/potrace/curve.cpp delete mode 100644 src/trace/potrace/curve.h delete mode 100644 src/trace/potrace/decompose.cpp delete mode 100644 src/trace/potrace/decompose.h delete mode 100644 src/trace/potrace/greymap.cpp delete mode 100644 src/trace/potrace/greymap.h delete mode 100644 src/trace/potrace/lists.h delete mode 100644 src/trace/potrace/potracelib.cpp delete mode 100644 src/trace/potrace/potracelib.h delete mode 100644 src/trace/potrace/progress.h delete mode 100644 src/trace/potrace/render.cpp delete mode 100644 src/trace/potrace/render.h delete mode 100644 src/trace/potrace/trace.cpp delete mode 100644 src/trace/potrace/trace.h (limited to 'src') diff --git a/src/trace/Makefile_insert b/src/trace/Makefile_insert index 21ec4ac0c..9c300aa8d 100644 --- a/src/trace/Makefile_insert +++ b/src/trace/Makefile_insert @@ -14,21 +14,6 @@ ink_common_sources += \ trace/filterset.cpp \ trace/siox.h \ trace/siox.cpp \ - trace/potrace/auxiliary.h \ - trace/potrace/bitmap.h \ - trace/potrace/curve.cpp \ - trace/potrace/curve.h \ - trace/potrace/decompose.cpp \ - trace/potrace/decompose.h \ - trace/potrace/greymap.cpp \ - trace/potrace/greymap.h \ - trace/potrace/lists.h \ - trace/potrace/potracelib.cpp \ - trace/potrace/potracelib.h \ - trace/potrace/progress.h \ - trace/potrace/render.cpp \ - trace/potrace/render.h \ - trace/potrace/trace.cpp \ - trace/potrace/trace.h \ + trace/potrace/bitmap.h \ trace/potrace/inkscape-potrace.cpp \ trace/potrace/inkscape-potrace.h diff --git a/src/trace/potrace/auxiliary.h b/src/trace/potrace/auxiliary.h deleted file mode 100644 index dbf124d7c..000000000 --- a/src/trace/potrace/auxiliary.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - -/* This header file collects some general-purpose macros (and static - inline functions) that are used in various places. */ - -#ifndef AUXILIARY_H -#define AUXILIARY_H - -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* ---------------------------------------------------------------------- */ -/* point arithmetic */ - -#include "potracelib.h" - -struct point_s { - long x; - long y; -}; -typedef struct point_s point_t; - -typedef potrace_dpoint_t dpoint_t; - -/* convert point_t to dpoint_t */ -static inline dpoint_t dpoint(point_t p) { - dpoint_t res; - res.x = p.x; - res.y = p.y; - return res; -} - -/* range over the straight line segment [a,b] when lambda ranges over [0,1] */ -static inline dpoint_t interval(double lambda, dpoint_t a, dpoint_t b) { - dpoint_t res; - - res.x = a.x + lambda * (b.x - a.x); - res.y = a.y + lambda * (b.y - a.y); - return res; -} - -/* ---------------------------------------------------------------------- */ -/* some useful macros. Note: the "mod" macro works correctly for - negative a. Also note that the test for a>=n, while redundant, - speeds up the mod function by 70% in the average case (significant - since the program spends about 16% of its time here - or 40% - without the test). The "floordiv" macro returns the largest integer - <= a/n, and again this works correctly for negative a, as long as - a,n are integers and n>0. */ - -/* integer arithmetic */ - -static inline int mod(int a, int n) { - return a>=n ? a%n : a>=0 ? a : n-1-(-1-a)%n; -} - -static inline int floordiv(int a, int n) { - return a>=0 ? a/n : -1-(-1-a)/n; -} - -/* Note: the following work for integers and other numeric types. */ -#undef sign -#undef abs -#undef min -#undef max -#undef sq -#undef cu -#define sign(x) ((x)>0 ? 1 : (x)<0 ? -1 : 0) -#define abs(a) ((a)>0 ? (a) : -(a)) -#define min(a,b) ((a)<(b) ? (a) : (b)) -#define max(a,b) ((a)>(b) ? (a) : (b)) -#define sq(a) ((a)*(a)) -#define cu(a) ((a)*(a)*(a)) - -#endif /* AUXILIARY_H */ diff --git a/src/trace/potrace/bitops.h b/src/trace/potrace/bitops.h deleted file mode 100644 index cff734a46..000000000 --- a/src/trace/potrace/bitops.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - - -/* bits.h: this file defines some macros for bit manipulations. We - provide a generic implementation, as well as machine- and - compiler-specific fast implementations */ - -/* lobit: return the position of the rightmost "1" bit of an int, or - 32 if none. hibit: return 1 + the position of the leftmost "1" bit - of an int, or 0 if none. Note: these functions work on 32-bit - integers. */ - -#ifndef BITOPS_H -#define BITOPS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* ---------------------------------------------------------------------- */ -/* machine specific macros */ - -#if defined(HAVE_I386) - -static inline unsigned int lobit(unsigned int x) { - unsigned int res; - asm ("bsf %1,%0\n\t" - "jnz 0f\n\t" - "movl $32,%0\n" - "0:" - : "=r" (res) - : "r" (x) - : "cc"); - return res; -} - -static inline unsigned int hibit(unsigned int x) { - unsigned int res; - - asm ("bsr %1,%0\n\t" - "jnz 0f\n\t" - "movl $-1,%0\n" - "0:" - : "=r" (res) - : "r" (x) - : "cc"); - return res+1; -} - -/* ---------------------------------------------------------------------- */ -#else /* generic macros */ - -static inline unsigned int lobit(unsigned int x) { - unsigned int res = 32; - while (x & 0xffffff) { - x <<= 8; - res -= 8; - } - while (x) { - x <<= 1; - res -= 1; - } - return res; -} - -static inline unsigned int hibit(unsigned int x) { - unsigned int res = 0; - while (x > 0xff) { - x >>= 8; - res += 8; - } - while (x) { - x >>= 1; - res += 1; - } - return res; -} - -#endif - -#endif /* BITOPS_H */ diff --git a/src/trace/potrace/curve.cpp b/src/trace/potrace/curve.cpp deleted file mode 100644 index e6a9a4721..000000000 --- a/src/trace/potrace/curve.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - -/* private part of the path and curve data structures */ - -#include -#include -#include - -#include "potracelib.h" -#include "lists.h" -#include "curve.h" - -#define SAFE_CALLOC(var, n, typ) \ - if ((var = (typ *)calloc(n, sizeof(typ))) == NULL) goto calloc_error - -/* ---------------------------------------------------------------------- */ -/* allocate and free path objects */ - -path_t *path_new(void) { - path_t *p = NULL; - privpath_t *priv = NULL; - - SAFE_CALLOC(p, 1, path_t); - memset(p, 0, sizeof(path_t)); - SAFE_CALLOC(priv, 1, privpath_t); - memset(priv, 0, sizeof(privpath_t)); - p->priv = priv; - return p; - - calloc_error: - free(p); - free(priv); - return NULL; -} - -/* free the members of the given curve structure. Leave errno unchanged. */ -static void privcurve_free_members(privcurve_t *curve) { - free(curve->tag); - free(curve->c); - free(curve->vertex); - free(curve->alpha); - free(curve->alpha0); - free(curve->beta); -} - -/* free a path. Leave errno untouched. */ -void path_free(path_t *p) { - if (p) { - if (p->priv) { - free(p->priv->pt); - free(p->priv->lon); - free(p->priv->sums); - free(p->priv->po); - privcurve_free_members(&p->priv->curve); - privcurve_free_members(&p->priv->ocurve); - } - free(p->priv); - /* do not free p->fcurve ! */ - } - free(p); -} - -/* free a pathlist, leaving errno untouched. */ -void pathlist_free(path_t *plist) { - path_t *p; - - list_forall_unlink(p, plist) { - path_free(p); - } -} - -/* ---------------------------------------------------------------------- */ -/* initialize and finalize curve structures */ - -typedef dpoint_t dpoint3_t[3]; - -/* initialize the members of the given curve structure to size m. - Return 0 on success, 1 on error with errno set. */ -int privcurve_init(privcurve_t *curve, int n) { - memset(curve, 0, sizeof(privcurve_t)); - curve->n = n; - SAFE_CALLOC(curve->tag, n, int); - SAFE_CALLOC(curve->c, n, dpoint3_t); - SAFE_CALLOC(curve->vertex, n, dpoint_t); - SAFE_CALLOC(curve->alpha, n, double); - SAFE_CALLOC(curve->alpha0, n, double); - SAFE_CALLOC(curve->beta, n, double); - return 0; - - calloc_error: - free(curve->tag); - free(curve->c); - free(curve->vertex); - free(curve->alpha); - free(curve->alpha0); - free(curve->beta); - return 1; -} - -/* copy private to public curve structure */ -void privcurve_to_curve(privcurve_t *pc, potrace_curve_t *c) { - c->n = pc->n; - c->tag = pc->tag; - c->c = pc->c; -} - diff --git a/src/trace/potrace/curve.h b/src/trace/potrace/curve.h deleted file mode 100644 index feb95b39b..000000000 --- a/src/trace/potrace/curve.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - -#ifndef CURVE_H -#define CURVE_H - -#include "auxiliary.h" - -/* vertex is c[1] for tag=POTRACE_CORNER, and the intersection of - .c[-1][2]..c[0] and c[1]..c[2] for tag=POTRACE_CURVETO. alpha is only - defined for tag=POTRACE_CURVETO and is the alpha parameter of the curve: - .c[-1][2]..c[0] = alpha*(.c[-1][2]..vertex), and - c[2]..c[1] = alpha*(c[2]..vertex). - Beta is so that (.beta[i])[.vertex[i],.vertex[i+1]] = .c[i][2]. -*/ - -struct privcurve_s { - int n; /* number of segments */ - int *tag; /* tag[n]: POTRACE_CORNER or POTRACE_CURVETO */ - dpoint_t (*c)[3]; /* c[n][i]: control points. - c[n][0] is unused for tag[n]=POTRACE_CORNER */ - /* the remainder of this structure is special to privcurve, and is - used in EPS debug output and special EPS "short coding". These - fields are valid only if "alphacurve" is set. */ - int alphacurve; /* have the following fields been initialized? */ - dpoint_t *vertex; /* for POTRACE_CORNER, this equals c[1] */ - double *alpha; /* only for POTRACE_CURVETO */ - double *alpha0; /* "uncropped" alpha parameter - for debug output only */ - double *beta; -}; -typedef struct privcurve_s privcurve_t; - -struct sums_s { - double x; - double y; - double x2; - double xy; - double y2; -}; -typedef struct sums_s sums_t; - -/* the path structure is filled in with information about a given path - as it is accumulated and passed through the different stages of the - Potrace algorithm. Backends only need to read the fcurve and fm - fields of this data structure, but debugging backends may read - other fields. */ -struct potrace_privpath_s { - int len; - point_t *pt; /* pt[len]: path as extracted from bitmap */ - int *lon; /* lon[len]: (i,lon[i]) = longest straight line from i */ - - int x0, y0; /* origin for sums */ - sums_t *sums; /* sums[len+1]: cache for fast summing */ - - int m; /* length of optimal polygon */ - int *po; /* po[m]: optimal polygon */ - - privcurve_t curve; /* curve[m]: array of curve elements */ - privcurve_t ocurve; /* ocurve[om]: array of curve elements */ - privcurve_t *fcurve; /* final curve: this points to either curve or - ocurve. Do not free this separately. */ -}; -typedef struct potrace_privpath_s potrace_privpath_t; - -/* shorter names */ -typedef potrace_privpath_t privpath_t; -typedef potrace_path_t path_t; - -path_t *path_new(void); -void path_free(path_t *p); -void pathlist_free(path_t *plist); -int privcurve_init(privcurve_t *curve, int n); -void privcurve_to_curve(privcurve_t *pc, potrace_curve_t *c); - -#endif /* CURVE_H */ - diff --git a/src/trace/potrace/decompose.cpp b/src/trace/potrace/decompose.cpp deleted file mode 100644 index 7628b202d..000000000 --- a/src/trace/potrace/decompose.cpp +++ /dev/null @@ -1,511 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - - -#include -#include -#include -#include - -#include "potracelib.h" -#include "curve.h" -#include "lists.h" -#include "bitmap.h" -#include "decompose.h" -#include "progress.h" - -/* ---------------------------------------------------------------------- */ -/* deterministically and efficiently hash (x,y) into a pseudo-random bit */ - -static inline int detrand(int x, int y) { - unsigned int z; - static const unsigned char t[256] = { - /* non-linear sequence: constant term of inverse in GF(8), - mod x^8+x^4+x^3+x+1 */ - 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, - 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, - 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, - 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - }; - - /* 0x04b3e375 and 0x05a8ef93 are chosen to contain every possible - 5-bit sequence */ - z = ((0x04b3e375 * x) ^ y) * 0x05a8ef93; - z = t[z & 0xff] ^ t[(z>>8) & 0xff] ^ t[(z>>16) & 0xff] ^ t[(z>>24) & 0xff]; - return z; -} - -/* ---------------------------------------------------------------------- */ -/* auxiliary bitmap manipulations */ - -/* set the excess padding to 0 */ -static void bm_clearexcess(potrace_bitmap_t *bm) { - if (bm->w % BM_WORDBITS != 0) { - potrace_word mask = BM_ALLBITS << (BM_WORDBITS - (bm->w % BM_WORDBITS)); - for (int y=0; yh; y++) { - *bm_index(bm, bm->w, y) &= mask; - } - } -} - -struct bbox_s { - int x0, x1, y0, y1; /* bounding box */ -}; -typedef struct bbox_s bbox_t; - -/* clear the bm, assuming the bounding box is set correctly (faster - than clearing the whole bitmap) */ -static void clear_bm_with_bbox(potrace_bitmap_t *bm, bbox_t *bbox) { - int imin = (bbox->x0 / BM_WORDBITS); - int imax = ((bbox->x1 + BM_WORDBITS-1) / BM_WORDBITS); - int i, y; - - for (y=bbox->y0; yy1; y++) { - for (i=imin; i0) { - return 1; - } else if (ct<0) { - return 0; - } - } - return 0; -} - -/* ---------------------------------------------------------------------- */ -/* decompose image into paths */ - -/* efficiently invert bits [x,infty) and [xa,infty) in line y. Here xa - must be a multiple of BM_WORDBITS. */ -static void xor_to_ref(potrace_bitmap_t *bm, int x, int y, int xa) { - int xhi = x & -BM_WORDBITS; - int xlo = x & (BM_WORDBITS-1); /* = x % BM_WORDBITS */ - int i; - - if (xhipriv->len <= 0) { /* a path of length 0 is silly, but legal */ - return; - } - - y1 = p->priv->pt[p->priv->len-1].y; - - xa = p->priv->pt[0].x & -BM_WORDBITS; - for (k=0; kpriv->len; k++) { - x = p->priv->pt[k].x; - y = p->priv->pt[k].y; - - if (y != y1) { - /* efficiently invert the rectangle [x,xa] x [y,y1] */ - xor_to_ref(bm, x, min(y,y1), xa); - y1 = y; - } - } -} - -/* Find the bounding box of a given path. Path is assumed to be of - non-zero length. */ -static void setbbox_path(bbox_t *bbox, path_t *p) { - int x, y; - int k; - - bbox->y0 = INT_MAX; - bbox->y1 = 0; - bbox->x0 = INT_MAX; - bbox->x1 = 0; - - for (k=0; kpriv->len; k++) { - x = p->priv->pt[k].x; - y = p->priv->pt[k].y; - - if (x < bbox->x0) { - bbox->x0 = x; - } - if (x > bbox->x1) { - bbox->x1 = x; - } - if (y < bbox->y0) { - bbox->y0 = y; - } - if (y > bbox->y1) { - bbox->y1 = y; - } - } -} - -/* compute a path in the given pixmap, separating black from white. - Start path at the point (x0,x1), which must be an upper left corner - of the path. Also compute the area enclosed by the path. Return a - new path_t object, or NULL on error (note that a legitimate path - cannot have length 0). Sign is required for correct interpretation - of turnpolicies. */ -static path_t *findpath(potrace_bitmap_t *bm, int x0, int y0, int sign, int turnpolicy) { - int x, y, dirx, diry, len, size, area; - int c, d, tmp; - point_t *pt, *pt1; - path_t *p = NULL; - - x = x0; - y = y0; - dirx = 0; - diry = -1; - - len = size = 0; - pt = NULL; - area = 0; - - while (1) { - /* add point to path */ - if (len>=size) { - size += 100; - size = (int)(1.3 * size); - pt1 = (point_t *)realloc(pt, size * sizeof(point_t)); - if (!pt1) { - goto error; - } - pt = pt1; - } - pt[len].x = x; - pt[len].y = y; - len++; - - /* move to next point */ - x += dirx; - y += diry; - area += x*diry; - - /* path complete? */ - if (x==x0 && y==y0) { - break; - } - - /* determine next direction */ - c = BM_GET(bm, x + (dirx+diry-1)/2, y + (diry-dirx-1)/2); - d = BM_GET(bm, x + (dirx-diry-1)/2, y + (diry+dirx-1)/2); - - if (c && !d) { /* ambiguous turn */ - if (turnpolicy == POTRACE_TURNPOLICY_RIGHT - || (turnpolicy == POTRACE_TURNPOLICY_BLACK && sign == '+') - || (turnpolicy == POTRACE_TURNPOLICY_WHITE && sign == '-') - || (turnpolicy == POTRACE_TURNPOLICY_RANDOM && detrand(x,y)) - || (turnpolicy == POTRACE_TURNPOLICY_MAJORITY && majority(bm, x, y)) - || (turnpolicy == POTRACE_TURNPOLICY_MINORITY && !majority(bm, x, y))) { - tmp = dirx; /* right turn */ - dirx = diry; - diry = -tmp; - } else { - tmp = dirx; /* left turn */ - dirx = -diry; - diry = tmp; - } - } else if (c) { /* right turn */ - tmp = dirx; - dirx = diry; - diry = -tmp; - } else if (!d) { /* left turn */ - tmp = dirx; - dirx = -diry; - diry = tmp; - } - } /* while this path */ - - /* allocate new path object */ - p = path_new(); - if (!p) { - goto error; - } - - p->priv->pt = pt; - p->priv->len = len; - p->area = area; - p->sign = sign; - - return p; - - error: - free(pt); - return NULL; -} - -/* Give a tree structure to the given path list, based on "insideness" - testing. I.e., path A is considered "below" path B if it is inside - path B. The input pathlist is assumed to be ordered so that "outer" - paths occur before "inner" paths. The tree structure is stored in - the "childlist" and "sibling" components of the path_t - structure. The linked list structure is also changed so that - negative path components are listed immediately after their - positive parent. Note: some backends may ignore the tree - structure, others may use it e.g. to group path components. We - assume that in the input, point 0 of each path is an "upper left" - corner of the path, as returned by bm_to_pathlist. This makes it - easy to find an "interior" point. The bm argument should be a - bitmap of the correct size (large enough to hold all the paths), - and will be used as scratch space. Return 0 on success or -1 on - error with errno set. */ - -static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) { - path_t *p, *p1; - path_t *heap, *heap1; - path_t *cur; - path_t *head; - path_t **plist_hook; /* for fast appending to linked list */ - path_t **hook_in, **hook_out; /* for fast appending to linked list */ - bbox_t bbox; - - bm_clear(bm, 0); - - /* save original "next" pointers */ - list_forall(p, plist) { - p->sibling = p->next; - p->childlist = NULL; - } - - heap = plist; - - /* the heap holds a list of lists of paths. Use "childlist" field - for outer list, "next" field for inner list. Each of the sublists - is to be turned into a tree. This code is messy, but it is - actually fast. Each path is rendered exactly once. We use the - heap to get a tail recursive algorithm: the heap holds a list of - pathlists which still need to be transformed. */ - - while (heap) { - /* unlink first sublist */ - cur = heap; - heap = heap->childlist; - cur->childlist = NULL; - - /* unlink first path */ - head = cur; - cur = cur->next; - head->next = NULL; - - /* render path */ - xor_path(bm, head); - setbbox_path(&bbox, head); - - /* now do insideness test for each element of cur; append it to - head->childlist if it's inside head, else append it to - head->next. */ - hook_in=&head->childlist; - hook_out=&head->next; - list_forall_unlink(p, cur) { - if (p->priv->pt[0].y <= bbox.y0) { - list_insert_beforehook(p, hook_out); - /* append the remainder of the list to hook_out */ - *hook_out = cur; - break; - } - if (BM_GET(bm, p->priv->pt[0].x, p->priv->pt[0].y-1)) { - list_insert_beforehook(p, hook_in); - } else { - list_insert_beforehook(p, hook_out); - } - } - - /* clear bm */ - clear_bm_with_bbox(bm, &bbox); - - /* now schedule head->childlist and head->next for further - processing */ - if (head->next) { - head->next->childlist = heap; - heap = head->next; - } - if (head->childlist) { - head->childlist->childlist = heap; - heap = head->childlist; - } - } - - /* copy sibling structure from "next" to "sibling" component */ - p = plist; - while (p) { - p1 = p->sibling; - p->sibling = p->next; - p = p1; - } - - /* reconstruct a new linked list ("next") structure from tree - ("childlist", "sibling") structure. This code is slightly messy, - because we use a heap to make it tail recursive: the heap - contains a list of childlists which still need to be - processed. */ - heap = plist; - if (heap) { - heap->next = NULL; /* heap is a linked list of childlists */ - } - plist = NULL; - plist_hook = &plist; - while (heap) { - heap1 = heap->next; - for (p=heap; p; p=p->sibling) { - /* p is a positive path */ - /* append to linked list */ - list_insert_beforehook(p, plist_hook); - - /* go through its children */ - for (p1=p->childlist; p1; p1=p1->sibling) { - /* append to linked list */ - list_insert_beforehook(p1, plist_hook); - /* append its childlist to heap, if non-empty */ - if (p1->childlist) { - list_append(path_t, heap1, p1->childlist); - } - } - } - heap = heap1; - } - - return; -} - -/* find the next set pixel in a row <= y. Pixels are searched first - left-to-right, then top-down. In other words, (x,y)<(x',y') if y>y' - or y=y' and x=0; y--) { - for (x=x0; xw; x+=BM_WORDBITS) { - if (*bm_index(bm, x, y)) { - while (!BM_GET(bm, x, y)) { - x++; - } - /* found */ - *xp = x; - *yp = y; - return 0; - } - } - x0 = 0; - } - /* not found */ - return 1; -} - -/* Decompose the given bitmap into paths. Returns a linked list of - path_t objects with the fields len, pt, area, sign filled - in. Returns 0 on success with plistp set, or -1 on error with errno - set. */ - -int bm_to_pathlist(const potrace_bitmap_t *bm, path_t **plistp, const potrace_param_t *param, progress_t *progress) { - int x; - int y; - path_t *p; - path_t *plist = NULL; /* linked list of path objects */ - path_t **plist_hook = &plist; /* used to speed up appending to linked list */ - potrace_bitmap_t *bm1 = NULL; - int sign; - - bm1 = bm_dup(bm); - if (!bm1) { - goto error; - } - - /* be sure the byte padding on the right is set to 0, as the fast - pixel search below relies on it */ - bm_clearexcess(bm1); - - /* iterate through components */ - x = 0; - y = bm1->h - 1; - while (findnext(bm1, &x, &y) == 0) { - /* calculate the sign by looking at the original */ - sign = BM_GET(bm, x, y) ? '+' : '-'; - - /* calculate the path */ - p = findpath(bm1, x, y+1, sign, param->turnpolicy); - if (p==NULL) { - goto error; - } - - /* update buffered image */ - xor_path(bm1, p); - - /* if it's a turd, eliminate it, else append it to the list */ - if (p->area <= param->turdsize) { - path_free(p); - } else { - list_insert_beforehook(p, plist_hook); - } - - if (bm1->h > 0) { /* to be sure */ - progress_update(1-y/(double)bm1->h, progress); - } - } - - pathlist_to_tree(plist, bm1); - bm_free(bm1); - *plistp = plist; - - progress_update(1.0, progress); - - return 0; - - error: - bm_free(bm1); - list_forall_unlink(p, plist) { - path_free(p); - } - return -1; -} diff --git a/src/trace/potrace/decompose.h b/src/trace/potrace/decompose.h deleted file mode 100644 index 8ae89b8ad..000000000 --- a/src/trace/potrace/decompose.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - - -#ifndef DECOMPOSE_H -#define DECOMPOSE_H - -#include "potracelib.h" -#include "progress.h" -#include "curve.h" - -int bm_to_pathlist(const potrace_bitmap_t *bm, path_t **plistp, const potrace_param_t *param, progress_t *progress); - -#endif /* DECOMPOSE_H */ - diff --git a/src/trace/potrace/greymap.cpp b/src/trace/potrace/greymap.cpp deleted file mode 100644 index 4ef2ec8df..000000000 --- a/src/trace/potrace/greymap.cpp +++ /dev/null @@ -1,941 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - - -/* Routines for manipulating greymaps, including reading pgm files. We - only deal with greymaps of depth 8 bits. */ - -#include -#include -#include -#include - -#include "greymap.h" -#include "bitops.h" - -#define INTBITS (8*sizeof(int)) - -#define mod(a,n) ((a)>=(n) ? (a)%(n) : (a)>=0 ? (a) : (n)-1-(-1-(a))%(n)) - -static int gm_readbody_pnm(FILE *f, greymap_t **gmp, int magic); -static int gm_readbody_bmp(FILE *f, greymap_t **gmp); - -/* ---------------------------------------------------------------------- */ -/* basic greymap routines */ - -/* return new un-initialized greymap. NULL with errno on error. - Assumes w, h >= 0. */ -greymap_t *gm_new(int w, int h) { - greymap_t *gm; - ssize_t size = (ssize_t)w * (ssize_t)h * (ssize_t)sizeof(signed short int); - - /* check for overflow error */ - if (size < 0 || size / w / h != sizeof(signed short int)) { - errno = ENOMEM; - return NULL; - } - - gm = (greymap_t *) malloc(sizeof(greymap_t)); - if (!gm) { - return NULL; - } - gm->w = w; - gm->h = h; - gm->map = (signed short int *) malloc(size); - if (!gm->map) { - free(gm); - return NULL; - } - return gm; -} - -/* free the given greymap */ -void gm_free(greymap_t *gm) { - if (gm) { - free(gm->map); - } - free(gm); -} - -/* duplicate the given greymap. Return NULL on error with errno set. */ -greymap_t *gm_dup(greymap_t *gm) { - greymap_t *gm1 = gm_new(gm->w, gm->h); - if (!gm1) { - return NULL; - } - memcpy(gm1->map, gm->map, gm->w*gm->h*sizeof(signed short int)); - return gm1; -} - -/* clear the given greymap to color b. */ -void gm_clear(greymap_t *gm, int b) { - if (b==0) { - memset(gm->map, 0, gm->w*gm->h*sizeof(signed short int)); - } else { - for (int i=0; iw*gm->h; i++) { - gm->map[i] = b; - } - } -} - -/* ---------------------------------------------------------------------- */ -/* routines for reading pnm streams */ - -/* read next character after whitespace and comments. Return EOF on - end of file or error. */ -static int fgetc_ws(FILE *f) { - int c; - - while (1) { - c = fgetc(f); - if (c=='#') { - while (1) { - c = fgetc(f); - if (c=='\n' || c==EOF) { - break; - } - } - } - /* space, tab, line feed, carriage return, form-feed */ - if (c!=' ' && c!='\t' && c!='\r' && c!='\n' && c!=12) { - return c; - } - } -} - -/* skip whitespace and comments, then read a non-negative decimal - number from a stream. Return -1 on EOF. Tolerate other errors (skip - bad characters). Do not the read any characters following the - number (put next character back into the stream) */ - -static int readnum(FILE *f) { - int c; - int acc; - - /* skip whitespace and comments */ - while (1) { - c = fgetc_ws(f); - if (c==EOF) { - return -1; - } - if (c>='0' && c<='9') { - break; - } - } - - /* first digit is already in c */ - acc = c-'0'; - while (1) { - c = fgetc(f); - if (c==EOF) { - break; - } - if (c<'0' || c>'9') { - ungetc(c, f); - break; - } - acc *= 10; - acc += c-'0'; - } - return acc; -} - -/* similar to readnum, but read only a single 0 or 1, and do not read - any characters after it. */ - -static int readbit(FILE *f) { - int c; - - /* skip whitespace and comments */ - while (1) { - c = fgetc_ws(f); - if (c==EOF) { - return -1; - } - if (c>='0' && c<='1') { - break; - } - } - - return c-'0'; -} - -/* ---------------------------------------------------------------------- */ - -/* read a PNM stream: P1-P6 format (see pnm(5)), or a BMP stream, and - convert the output to a greymap. Return greymap in *gmp. Return 0 - on success, -1 on error with errno set, -2 on bad file format (with - error message in gm_read_error), and 1 on premature end of file, -3 - on empty file (including files with only whitespace and comments), - -4 if wrong magic number. If the return value is >=0, *gmp is - valid. */ - -char const *gm_read_error = NULL; - -int gm_read(FILE *f, greymap_t **gmp) { - int magic[2]; - - /* read magic number. We ignore whitespace and comments before the - magic, for the benefit of concatenated files in P1-P3 format. - Multiple P1-P3 images in a single file are not formally allowed - by the PNM standard, but there is no harm in being lenient. */ - - magic[0] = fgetc_ws(f); - if (magic[0] == EOF) { - /* files which contain only comments and whitespace count as "empty" */ - return -3; - } - magic[1] = fgetc(f); - if (magic[0] == 'P' && magic[1] >= '1' && magic[1] <= '6') { - return gm_readbody_pnm(f, gmp, magic[1]); - } - if (magic[0] == 'B' && magic[1] == 'M') { - return gm_readbody_bmp(f, gmp); - } - return -4; -} - -/* ---------------------------------------------------------------------- */ -/* read PNM format */ - -/* read PNM stream after magic number. Return values as for gm_read */ -static int gm_readbody_pnm(FILE *f, greymap_t **gmp, int magic) { - greymap_t *gm; - int x, y, i, j, b, b1, sum; - int bpr; /* bytes per row (as opposed to 4*gm->c) */ - int w, h, max; - - gm = NULL; - - w = readnum(f); - if (w<0) { - goto format_error; - } - - h = readnum(f); - if (h<0) { - goto format_error; - } - - /* allocate greymap */ - gm = gm_new(w, h); - if (!gm) { - return -1; - } - - /* zero it out */ - gm_clear(gm, 0); - - switch (magic) { - default: - /* not reached */ - goto format_error; - - case '1': - /* read P1 format: PBM ascii */ - - for (y=h-1; y>=0; y--) { - for (x=0; x=0; y--) { - for (x=0; x=0; y--) { - for (x=0; x=0; y--) { - for (i=0; i> j) ? 0 : 255); - } - } - } - break; - - case '5': - /* read P5 format: PGM raw */ - - max = readnum(f); - if (max<1) { - goto format_error; - } - - b = fgetc(f); /* read single white-space character after max */ - if (b==EOF) { - goto format_error; - } - - for (y=h-1; y>=0; y--) { - for (x=0; x=256) { - b <<= 8; - b1 = fgetc(f); - if (b1==EOF) - goto eof; - b |= b1; - } - GM_UPUT(gm, x, y, b*255/max); - } - } - break; - - case '6': - /* read P6 format: PPM raw */ - - max = readnum(f); - if (max<1) { - goto format_error; - } - - b = fgetc(f); /* read single white-space character after max */ - if (b==EOF) { - goto format_error; - } - - for (y=h-1; y>=0; y--) { - for (x=0; x=256) { - b <<= 8; - b1 = fgetc(f); - if (b1==EOF) - goto eof; - b |= b1; - } - sum += b; - } - GM_UPUT(gm, x, y, sum*(255/3)/max); - } - } - break; - } - - *gmp = gm; - return 0; - - eof: - *gmp = gm; - return 1; - - format_error: - gm_free(gm); - if (magic == '1' || magic == '4') { - gm_read_error = "invalid pbm file"; - } else if (magic == '2' || magic == '5') { - gm_read_error = "invalid pgm file"; - } else { - gm_read_error = "invalid ppm file"; - } - return -2; -} - -/* ---------------------------------------------------------------------- */ -/* read BMP format */ - -struct bmp_info_s { - unsigned int FileSize; - unsigned int reserved; - unsigned int DataOffset; - unsigned int InfoSize; - unsigned int w; /* width */ - unsigned int h; /* height */ - unsigned int Planes; - unsigned int bits; /* bits per sample */ - unsigned int comp; /* compression mode */ - unsigned int ImageSize; - unsigned int XpixelsPerM; - unsigned int YpixelsPerM; - unsigned int ncolors; /* number of colors in palette */ - unsigned int ColorsImportant; - unsigned int RedMask; - unsigned int GreenMask; - unsigned int BlueMask; - unsigned int AlphaMask; - unsigned int ctbits; /* sample size for color table */ - int topdown; /* top-down mode? */ -}; -typedef struct bmp_info_s bmp_info_t; - -/* auxiliary */ - -static int bmp_count = 0; /* counter for byte padding */ -static int bmp_pos = 0; /* counter from start of BMP data */ - -/* read n-byte little-endian integer. Return 1 on EOF or error, else - 0. Assume n<=4. */ -static int bmp_readint(FILE *f, int n, unsigned int *p) { - int i; - unsigned int sum = 0; - int b; - - for (i=0; i= 108) { /* V4 and V5 bitmaps */ - TRY(bmp_readint(f, 4, &bmpinfo.RedMask)); - TRY(bmp_readint(f, 4, &bmpinfo.GreenMask)); - TRY(bmp_readint(f, 4, &bmpinfo.BlueMask)); - TRY(bmp_readint(f, 4, &bmpinfo.AlphaMask)); - } - if (bmpinfo.w > 0x7fffffff) { - goto format_error; - } - if (bmpinfo.h > 0x7fffffff) { - bmpinfo.h = (-bmpinfo.h) & 0xffffffff; - bmpinfo.topdown = 1; - } else { - bmpinfo.topdown = 0; - } - if (bmpinfo.h > 0x7fffffff) { - goto format_error; - } - } else if (bmpinfo.InfoSize == 12) { - /* old OS/2 format */ - bmpinfo.ctbits = 24; /* sample size in color table */ - TRY(bmp_readint(f, 2, &bmpinfo.w)); - TRY(bmp_readint(f, 2, &bmpinfo.h)); - TRY(bmp_readint(f, 2, &bmpinfo.Planes)); - TRY(bmp_readint(f, 2, &bmpinfo.bits)); - bmpinfo.comp = 0; - bmpinfo.ncolors = 0; - bmpinfo.topdown = 0; - } else { - goto format_error; - } - - if (bmpinfo.comp == 3 && bmpinfo.InfoSize < 108) { - /* bitfield feature is only understood with V4 and V5 format */ - goto format_error; - } - - /* forward to color table (e.g., if bmpinfo.InfoSize == 64) */ - TRY(bmp_forward(f, 14+bmpinfo.InfoSize)); - - if (bmpinfo.Planes != 1) { - gm_read_error = "cannot handle bmp planes"; - goto format_error; /* can't handle planes */ - } - - if (bmpinfo.ncolors == 0) { - bmpinfo.ncolors = 1 << bmpinfo.bits; - } - - /* color table, present only if bmpinfo.bits <= 8. */ - if (bmpinfo.bits <= 8) { - coltable = (int *) calloc(bmpinfo.ncolors, sizeof(int)); - if (!coltable) { - goto std_error; - } - /* NOTE: since we are reading a greymap, we can immediately convert - the color table entries to grey values. */ - for (i=0; i>16) & 0xff) + ((c>>8) & 0xff) + (c & 0xff); - coltable[i] = c/3; - } - } - - /* forward to data */ - if (bmpinfo.InfoSize != 12) { /* not old OS/2 format */ - TRY(bmp_forward(f, bmpinfo.DataOffset)); - } - - /* allocate greymap */ - gm = gm_new(bmpinfo.w, bmpinfo.h); - if (!gm) { - goto std_error; - } - - /* zero it out */ - gm_clear(gm, 0); - - switch (bmpinfo.bits + 0x100*bmpinfo.comp) { - - default: - goto format_error; - break; - - case 0x001: /* monochrome palette */ - - /* raster data */ - for (y=0; y> j) ? coltable[1] : coltable[0]); - } - } - TRY(bmp_pad(f)); - } - break; - - case 0x002: /* 2-bit to 8-bit palettes */ - case 0x003: - case 0x004: - case 0x005: - case 0x006: - case 0x007: - case 0x008: - for (y=0; y> (INTBITS - bmpinfo.bits); - bitbuf <<= bmpinfo.bits; - n -= bmpinfo.bits; - GM_UPUT(gm, x, ycorr(y), coltable[b]); - } - TRY(bmp_pad(f)); - } - break; - - case 0x010: /* 16-bit encoding */ - /* can't do this format because it is not well-documented and I - don't have any samples */ - gm_read_error = "cannot handle bmp 16-bit coding"; - goto format_error; - break; - - case 0x018: /* 24-bit encoding */ - case 0x020: /* 32-bit encoding */ - for (y=0; y>16) & 0xff) + ((c>>8) & 0xff) + (c & 0xff); - GM_UPUT(gm, x, ycorr(y), c/3); - } - TRY(bmp_pad(f)); - } - break; - - case 0x320: /* 32-bit encoding with bitfields */ - redshift = lobit(bmpinfo.RedMask); - greenshift = lobit(bmpinfo.GreenMask); - blueshift = lobit(bmpinfo.BlueMask); - - for (y=0; y> redshift) + ((c & bmpinfo.GreenMask) >> greenshift) + ((c & bmpinfo.BlueMask) >> blueshift); - GM_UPUT(gm, x, ycorr(y), c/3); - } - TRY(bmp_pad(f)); - } - break; - - case 0x204: /* 4-bit runlength compressed encoding (RLE4) */ - x = 0; - y = 0; - while (1) { - TRY_EOF(bmp_readint(f, 1, &b)); /* opcode */ - TRY_EOF(bmp_readint(f, 1, &c)); /* argument */ - if (b>0) { - /* repeat count */ - col[0] = coltable[(c>>4) & 0xf]; - col[1] = coltable[c & 0xf]; - for (i=0; i=bmpinfo.w) { - x=0; - y++; - } - if (y>=bmpinfo.h) { - break; - } - GM_UPUT(gm, x, ycorr(y), col[i&1]); - x++; - } - } else if (c == 0) { - /* end of line */ - y++; - x = 0; - } else if (c == 1) { - /* end of greymap */ - break; - } else if (c == 2) { - /* "delta": skip pixels in x and y directions */ - TRY_EOF(bmp_readint(f, 1, &b)); /* x offset */ - TRY_EOF(bmp_readint(f, 1, &c)); /* y offset */ - x += b; - y += c; - } else { - /* verbatim segment */ - for (i=0; i=bmpinfo.w) { - x=0; - y++; - } - if (y>=bmpinfo.h) { - break; - } - GM_PUT(gm, x, ycorr(y), coltable[(b>>(4-4*(i&1))) & 0xf]); - x++; - } - if ((c+1) & 2) { - /* pad to 16-bit boundary */ - TRY_EOF(bmp_readint(f, 1, &b)); - } - } - } - break; - - case 0x108: /* 8-bit runlength compressed encoding (RLE8) */ - x = 0; - y = 0; - while (1) { - TRY_EOF(bmp_readint(f, 1, &b)); /* opcode */ - TRY_EOF(bmp_readint(f, 1, &c)); /* argument */ - if (b>0) { - /* repeat count */ - for (i=0; i=bmpinfo.w) { - x=0; - y++; - } - if (y>=bmpinfo.h) { - break; - } - GM_UPUT(gm, x, ycorr(y), coltable[c]); - x++; - } - } else if (c == 0) { - /* end of line */ - y++; - x = 0; - } else if (c == 1) { - /* end of greymap */ - break; - } else if (c == 2) { - /* "delta": skip pixels in x and y directions */ - TRY_EOF(bmp_readint(f, 1, &b)); /* x offset */ - TRY_EOF(bmp_readint(f, 1, &c)); /* y offset */ - x += b; - y += c; - } else { - /* verbatim segment */ - for (i=0; i=bmpinfo.w) { - x=0; - y++; - } - if (y>=bmpinfo.h) { - break; - } - GM_PUT(gm, x, ycorr(y), coltable[b]); - x++; - } - if (c & 1) { - /* pad input to 16-bit boundary */ - TRY_EOF(bmp_readint(f, 1, &b)); - } - } - } - break; - - } /* switch */ - - /* skip any potential junk after the data section, but don't - complain in case EOF is encountered */ - bmp_forward(f, bmpinfo.FileSize); - - free(coltable); - *gmp = gm; - return 0; - - eof: - free(coltable); - *gmp = gm; - return 1; - - format_error: - try_error: - free(coltable); - free(gm); - if (!gm_read_error) { - gm_read_error = "invalid bmp file"; - } - return -2; - - std_error: - free(coltable); - free(gm); - return -1; -} - -/* ---------------------------------------------------------------------- */ - -/* write a pgm stream, either P2 or (if raw != 0) P5 format. Include - one-line comment if non-NULL. Mode determines how out-of-range - color values are converted. Gamma is the desired gamma correction, - if any (set to 2.2 if the image is to look optimal on a CRT monitor, - 2.8 for LCD). Set to 1.0 for no gamma correction */ - -int gm_writepgm(FILE *f, greymap_t *gm, char *comment, int raw, int mode, double gamma) { - int x, y, v; - int gammatable[256]; - - /* prepare gamma correction lookup table */ - if (gamma != 1.0) { - gammatable[0] = 0; - for (v=1; v<256; v++) { - gammatable[v] = (int)(255 * exp(log(v/255.0)/gamma) + 0.5); - } - } else { - for (v=0; v<256; v++) { - gammatable[v] = v; - } - } - - fprintf(f, raw ? "P5\n" : "P2\n"); - if (comment && *comment) { - fprintf(f, "# %s\n", comment); - } - fprintf(f, "%d %d 255\n", gm->w, gm->h); - for (y=gm->h-1; y>=0; y--) { - for (x=0; xw; x++) { - v = GM_UGET(gm, x, y); - if (mode == GM_MODE_NONZERO) { - if (v > 255) { - v = 510 - v; - } - if (v < 0) { - v = 0; - } - } else if (mode == GM_MODE_ODD) { - v = mod(v, 510); - if (v > 255) { - v = 510 - v; - } - } else if (mode == GM_MODE_POSITIVE) { - if (v < 0) { - v = 0; - } else if (v > 255) { - v = 255; - } - } else if (mode == GM_MODE_NEGATIVE) { - v = 510 - v; - if (v < 0) { - v = 0; - } else if (v > 255) { - v = 255; - } - } - v = gammatable[v]; - - if (raw) { - fputc(v, f); - } else { - fprintf(f, x == gm->w-1 ? "%d\n" : "%d ", v); - } - } - } - return 0; -} - -/* ---------------------------------------------------------------------- */ -/* output - for primitive debugging purposes only! */ - -/* print greymap to screen */ -int gm_print(FILE *f, greymap_t *gm) { - int x, y; - int xx, yy; - int d, t; - int sw, sh; - - sw = gm->w < 79 ? gm->w : 79; - sh = gm->w < 79 ? gm->h : gm->h*sw*44/(79*gm->w); - - for (yy=sh-1; yy>=0; yy--) { - for (xx=0; xxw/sw; x<(xx+1)*gm->w/sw; x++) { - for (y=yy*gm->h/sh; y<(yy+1)*gm->h/sh; y++) { - d += GM_GET(gm, x, y); - t += 256; - } - } - fputc("*#=- "[5*d/t], f); /* what a cute trick :) */ - } - fputc('\n', f); - } - return 0; -} diff --git a/src/trace/potrace/greymap.h b/src/trace/potrace/greymap.h deleted file mode 100644 index 8c9db9bbf..000000000 --- a/src/trace/potrace/greymap.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - - -#ifndef GREYMAP_H -#define GREYMAP_H - -#include -#include - -/* internal format for greymaps. Note: in this format, rows are - ordered from bottom to top. The pixels in each row are given from - left to right. */ - -struct greymap_s { - int w; /* width, in pixels */ - int h; /* height, in pixels */ - signed short int *map; /* raw data, w*h values */ -}; -typedef struct greymap_s greymap_t; - -/* macros for accessing pixel at index (x,y). Note that the origin is - in the *lower* left corner. U* macros omit the bounds check. */ - -#define gm_index(gm, x, y) (&(gm)->map[(x)+(y)*(ssize_t)(gm)->w]) -#define gm_safe(gm, x, y) ((int)(x)>=0 && (int)(x)<(gm)->w && (int)(y)>=0 && (int)(y)<(gm)->h) -#define gm_bound(x, m) ((x)<0 ? 0 : (x)>=(m) ? (m)-1 : (x)) -#define GM_UGET(gm, x, y) (*gm_index(gm, x, y)) -#define GM_UINC(gm, x, y, b) (*gm_index(gm, x, y) += (short int)(b)) -#define GM_UINV(gm, x, y) (*gm_index(gm, x, y) = 255 - *gm_index(gm, x, y)) -#define GM_UPUT(gm, x, y, b) (*gm_index(gm, x, y) = (short int)(b)) -#define GM_GET(gm, x, y) (gm_safe(gm, x, y) ? GM_UGET(gm, x, y) : 0) -#define GM_INC(gm, x, y, b) (gm_safe(gm, x, y) ? GM_UINC(gm, x, y, b) : 0) -#define GM_INV(gm, x, y) (gm_safe(gm, x, y) ? GM_UINV(gm, x, y) : 0) -#define GM_PUT(gm, x, y, b) (gm_safe(gm, x, y) ? GM_UPUT(gm, x, y, b) : 0) -#define GM_BGET(gm, x, y) GM_UGET(gm, gm_bound(x, gm->w), gm_bound(y, gm->h)) - -/* modes for cutting off out-of-range values. The following names - refer to winding numbers. I.e., make a pixel black if winding - number is nonzero, odd, or positive, respectively. We assume that 0 - winding number corresponds to white (255). */ -#define GM_MODE_NONZERO 1 -#define GM_MODE_ODD 2 -#define GM_MODE_POSITIVE 3 -#define GM_MODE_NEGATIVE 4 - -extern char const *gm_read_error; - -greymap_t *gm_new(int w, int h); -greymap_t *gm_dup(greymap_t *gm); -void gm_free(greymap_t *gm); -void gm_clear(greymap_t *gm, int b); -int gm_read(FILE *f, greymap_t **gmp); -int gm_writepgm(FILE *f, greymap_t *gm, char *comment, int raw, int mode, double gamma); -int gm_print(FILE *f, greymap_t *gm); - -#endif /* GREYMAP_H */ diff --git a/src/trace/potrace/inkscape-potrace.cpp b/src/trace/potrace/inkscape-potrace.cpp index 8f3bb7bdf..a0b0df1f6 100644 --- a/src/trace/potrace/inkscape-potrace.cpp +++ b/src/trace/potrace/inkscape-potrace.cpp @@ -29,7 +29,6 @@ #include "message-stack.h" #include #include -#include "curve.h" #include "bitmap.h" using Glib::ustring; @@ -128,7 +127,7 @@ static bool hasPoint(std::vector &points, double x, double y) /** - * Recursively descend the path_t node tree, writing paths in SVG + * Recursively descend the potrace_path_t node tree, writing paths in SVG * format into the output stream. The Point vector is used to prevent * redundant paths. Returns number of paths processed. */ @@ -144,7 +143,7 @@ static long writePaths(PotraceTracingEngine *engine, potrace_path_t *plist, //g_message("node->fm:%d\n", node->fm); if (!curve->n) continue; - dpoint_t *pt = curve->c[curve->n - 1]; + const potrace_dpoint_t *pt = curve->c[curve->n - 1]; double x0 = 0.0; double y0 = 0.0; double x1 = 0.0; @@ -192,7 +191,7 @@ static long writePaths(PotraceTracingEngine *engine, potrace_path_t *plist, } data.closePath(); - for (path_t *child=node->childlist; child ; child=child->sibling) + for (potrace_path_t *child=node->childlist; child ; child=child->sibling) { nodeCount += writePaths(engine, child, data, points); } diff --git a/src/trace/potrace/inkscape-potrace.h b/src/trace/potrace/inkscape-potrace.h index 88da56abb..e8e654973 100644 --- a/src/trace/potrace/inkscape-potrace.h +++ b/src/trace/potrace/inkscape-potrace.h @@ -18,7 +18,7 @@ #define __INKSCAPE_POTRACE_H__ #include -#include "potracelib.h" +#include struct GrayMap_def; typedef GrayMap_def GrayMap; diff --git a/src/trace/potrace/lists.h b/src/trace/potrace/lists.h deleted file mode 100644 index 394262c23..000000000 --- a/src/trace/potrace/lists.h +++ /dev/null @@ -1,285 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - - -#ifndef _PS_LISTS_H -#define _PS_LISTS_H - -/* here we define some general list macros. Because they are macros, - they should work on any datatype with a "->next" component. Some of - them use a "hook". If elt and list are of type t* then hook is of - type t**. A hook stands for an insertion point in the list, i.e., - either before the first element, or between two elements, or after - the last element. If an operation "sets the hook" for an element, - then the hook is set to just before the element. One can insert - something at a hook. One can also unlink at a hook: this means, - unlink the element just after the hook. By "to unlink", we mean the - element is removed from the list, but not deleted. Thus, it and its - components still need to be freed. */ - -/* Note: these macros are somewhat experimental. Only the ones that - are actually *used* have been tested. So be careful to test any - that you use. Looking at the output of the preprocessor, "gcc -E" - (possibly piped though "indent"), might help too. Also: these - macros define some internal (local) variables that start with - "_". */ - -/* we enclose macro definitions whose body consists of more than one - statement in MACRO_BEGIN and MACRO_END, rather than '{' and '}'. The - reason is that we want to be able to use the macro in a context - such as "if (...) macro(...); else ...". If we didn't use this obscure - trick, we'd have to omit the ";" in such cases. */ - -#define MACRO_BEGIN do { -#define MACRO_END } while (0) - -/* ---------------------------------------------------------------------- */ -/* macros for singly-linked lists */ - -/* traverse list. At the end, elt is set to NULL. */ -#define list_forall(elt, list) for (elt=list; elt!=NULL; elt=elt->next) - -/* set elt to the first element of list satisfying boolean condition - c, or NULL if not found */ -#define list_find(elt, list, c) \ - MACRO_BEGIN list_forall(elt, list) if (c) break; MACRO_END - -/* like forall, except also set hook for elt. */ -#define list_forall2(elt, list, hook) \ - for (elt=list, hook=&list; elt!=NULL; hook=&elt->next, elt=elt->next) - -/* same as list_find, except also set hook for elt. */ -#define list_find2(elt, list, c, hook) \ - MACRO_BEGIN list_forall2(elt, list, hook) if (c) break; MACRO_END - -/* same, except only use hook. */ -#define _list_forall_hook(list, hook) \ - for (hook=&list; *hook!=NULL; hook=&(*hook)->next) - -/* same, except only use hook. Note: c may only refer to *hook, not elt. */ -#define _list_find_hook(list, c, hook) \ - MACRO_BEGIN _list_forall_hook(list, hook) if (c) break; MACRO_END - -/* insert element after hook */ -#define list_insert_athook(elt, hook) \ - MACRO_BEGIN elt->next = *hook; *hook = elt; MACRO_END - -/* insert element before hook */ -#define list_insert_beforehook(elt, hook) \ - MACRO_BEGIN elt->next = *hook; *hook = elt; hook=&elt->next; MACRO_END - -/* unlink element after hook, let elt be unlinked element, or NULL. - hook remains. */ -#define list_unlink_athook(list, elt, hook) \ - MACRO_BEGIN \ - elt = hook ? *hook : NULL; if (elt) { *hook = elt->next; elt->next = NULL; }\ - MACRO_END - -/* unlink the specific element, if it is in the list. Otherwise, set - elt to NULL */ -#define list_unlink(listtype, list, elt) \ - MACRO_BEGIN \ - listtype **_hook; \ - _list_find_hook(list, *_hook==elt, _hook); \ - list_unlink_athook(list, elt, _hook); \ - MACRO_END - -/* prepend elt to list */ -#define list_prepend(list, elt) \ - MACRO_BEGIN elt->next = list; list = elt; MACRO_END - -/* append elt to list. */ -#define list_append(listtype, list, elt) \ - MACRO_BEGIN \ - listtype **_hook; \ - _list_forall_hook(list, _hook) {} \ - list_insert_athook(elt, _hook); \ - MACRO_END - -/* unlink the first element that satisfies the condition. */ -#define list_unlink_cond(listtype, list, elt, c) \ - MACRO_BEGIN \ - listtype **_hook; \ - list_find2(elt, list, c, _hook); \ - list_unlink_athook(list, elt, _hook); \ - MACRO_END - -/* let elt be the nth element of the list, starting to count from 0. - Return NULL if out of bounds. */ -#define list_nth(elt, list, n) \ - MACRO_BEGIN \ - int _x; /* only evaluate n once */ \ - for (_x=(n), elt=list; _x && elt; _x--, elt=elt->next) {} \ - MACRO_END - -/* let elt be the nth element of the list, starting to count from 0. - Return NULL if out of bounds. */ -#define list_nth_hook(elt, list, n, hook) \ - MACRO_BEGIN \ - int _x; /* only evaluate n once */ \ - for (_x=(n), elt=list, hook=&list; _x && elt; _x--, hook=&elt->next, elt=elt->next) {} \ - MACRO_END - -/* set n to the length of the list */ -#define list_length(listtype, list, n) \ - MACRO_BEGIN \ - listtype *_elt; \ - n=0; \ - list_forall(_elt, list) \ - n++; \ - MACRO_END - -/* set n to the index of the first element satisfying cond, or -1 if - none found. Also set elt to the element, or NULL if none found. */ -#define list_index(list, n, elt, c) \ - MACRO_BEGIN \ - n=0; \ - list_forall(elt, list) { \ - if (c) break; \ - n++; \ - } \ - if (!elt) \ - n=-1; \ - MACRO_END - -/* set n to the number of elements in the list that satisfy condition c */ -#define list_count(list, n, elt, c) \ - MACRO_BEGIN \ - n=0; \ - list_forall(elt, list) { \ - if (c) n++; \ - } \ - MACRO_END - -/* let elt be each element of the list, unlinked. At the end, set list=NULL. */ -#define list_forall_unlink(elt, list) \ - for (elt=list; elt ? (list=elt->next, elt->next=NULL), 1 : 0; elt=list) - -/* reverse a list (efficient) */ -#define list_reverse(listtype, list) \ - MACRO_BEGIN \ - listtype *_list1=NULL, *elt; \ - list_forall_unlink(elt, list) \ - list_prepend(_list1, elt); \ - list = _list1; \ - MACRO_END - -/* insert the element ELT just before the first element TMP of the - list for which COND holds. Here COND must be a condition of ELT and - TMP. Typical usage is to insert an element into an ordered list: - for instance, list_insert_ordered(listtype, list, elt, tmp, - elt->size <= tmp->size). Note: if we give a "less than or equal" - condition, the new element will be inserted just before a sequence - of equal elements. If we give a "less than" condition, the new - element will be inserted just after a list of equal elements. - Note: it is much more efficient to construct a list with - list_prepend and then order it with list_merge_sort, than to - construct it with list_insert_ordered. */ -#define list_insert_ordered(listtype, list, elt, tmp, cond) \ - MACRO_BEGIN \ - listtype **_hook; \ - _list_find_hook(list, (tmp=*_hook, (cond)), _hook); \ - list_insert_athook(elt, _hook); \ - MACRO_END - -/* sort the given list, according to the comparison condition. - Typical usage is list_sort(listtype, list, a, b, a->size < - b->size). Note: if we give "less than or equal" condition, each - segment of equal elements will be reversed in order. If we give a - "less than" condition, each segment of equal elements will retain - the original order. The latter is slower but sometimes - prettier. Average running time: n*n/2. */ -#define list_sort(listtype, list, a, b, cond) \ - MACRO_BEGIN \ - listtype *_newlist=NULL; \ - list_forall_unlink(a, list) \ - list_insert_ordered(listtype, _newlist, a, b, cond); \ - list = _newlist; \ - MACRO_END - -/* a much faster sort algorithm (merge sort, n log n worst case). It - is required that the list type has an additional, unused next1 - component. Note there is no curious reversal of order of equal - elements as for list_sort. */ - -#define list_mergesort(listtype, list, a, b, cond) \ - MACRO_BEGIN \ - listtype *_elt, **_hook1; \ - \ - for (_elt=list; _elt; _elt=_elt->next1) { \ - _elt->next1 = _elt->next; \ - _elt->next = NULL; \ - } \ - do { \ - _hook1 = &(list); \ - while ((a = *_hook1) != NULL && (b = a->next1) != NULL ) { \ - _elt = b->next1; \ - _list_merge_cond(listtype, a, b, cond, *_hook1); \ - _hook1 = &((*_hook1)->next1); \ - *_hook1 = _elt; \ - } \ - } while (_hook1 != &(list)); \ - MACRO_END - -/* merge two sorted lists. Store result at &result */ -#define _list_merge_cond(listtype, a, b, cond, result) \ - MACRO_BEGIN \ - listtype **_hook; \ - _hook = &(result); \ - while (1) { \ - if (a==NULL) { \ - *_hook = b; \ - break; \ - } else if (b==NULL) { \ - *_hook = a; \ - break; \ - } else if (cond) { \ - *_hook = a; \ - _hook = &(a->next); \ - a = a->next; \ - } else { \ - *_hook = b; \ - _hook = &(b->next); \ - b = b->next; \ - } \ - } \ - MACRO_END - -/* ---------------------------------------------------------------------- */ -/* macros for doubly-linked lists */ - -#define dlist_append(head, end, elt) \ - MACRO_BEGIN \ - elt->prev = end; \ - elt->next = NULL; \ - if (end) { \ - end->next = elt; \ - } else { \ - head = elt; \ - } \ - end = elt; \ - MACRO_END - -/* let elt be each element of the list, unlinked. At the end, set list=NULL. */ -#define dlist_forall_unlink(elt, head, end) \ - for (elt=head; elt ? (head=elt->next, elt->next=NULL, elt->prev=NULL), 1 : (end=NULL, 0); elt=head) - -/* unlink the first element of the list */ -#define dlist_unlink_first(head, end, elt) \ - MACRO_BEGIN \ - elt = head; \ - if (head) { \ - head = head->next; \ - if (head) { \ - head->prev = NULL; \ - } else { \ - end = NULL; \ - } \ - elt->prev = NULL; \ - elt->next = NULL; \ - } \ - MACRO_END - -#endif /* _PS_LISTS_H */ - diff --git a/src/trace/potrace/potracelib.cpp b/src/trace/potrace/potracelib.cpp deleted file mode 100644 index b5463d676..000000000 --- a/src/trace/potrace/potracelib.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - -#include -#include -#include - -#include "potracelib.h" -#include "inkscape-version.h" -#include "curve.h" -#include "decompose.h" -#include "trace.h" -#include "progress.h" - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* default parameters */ -static const potrace_param_t param_default = { - 2, /* turdsize */ - POTRACE_TURNPOLICY_MINORITY, /* turnpolicy */ - 1.0, /* alphamax */ - 1, /* opticurve */ - 0.2, /* opttolerance */ - { - NULL, /* callback function */ - NULL, /* callback data */ - 0.0, 1.0, /* progress range */ - 0.0, /* granularity */ - }, -}; - -/* Return a fresh copy of the set of default parameters, or NULL on - failure with errno set. */ -potrace_param_t *potrace_param_default(void) { - potrace_param_t *p; - - p = (potrace_param_t *) malloc(sizeof(potrace_param_t)); - if (!p) { - return NULL; - } - memcpy(p, ¶m_default, sizeof(potrace_param_t)); - return p; -} - -/* On success, returns a Potrace state st with st->status == - POTRACE_STATUS_OK. On failure, returns NULL if no Potrace state - could be created (with errno set), or returns an incomplete Potrace - state (with st->status == POTRACE_STATUS_INCOMPLETE, and with errno - set). Complete or incomplete Potrace state can be freed with - potrace_state_free(). */ -potrace_state_t *potrace_trace(const potrace_param_t *param, const potrace_bitmap_t *bm) { - int r; - path_t *plist = NULL; - potrace_state_t *st; - progress_t prog; - progress_t subprog; - - /* prepare private progress bar state */ - prog.callback = param->progress.callback; - prog.data = param->progress.data; - prog.min = param->progress.min; - prog.max = param->progress.max; - prog.epsilon = param->progress.epsilon; - prog.d_prev = param->progress.min; - - /* allocate state object */ - st = (potrace_state_t *)malloc(sizeof(potrace_state_t)); - if (!st) { - return NULL; - } - - progress_subrange_start(0.0, 0.1, &prog, &subprog); - - /* process the image */ - r = bm_to_pathlist(bm, &plist, param, &subprog); - if (r) { - free(st); - return NULL; - } - - st->status = POTRACE_STATUS_OK; - st->plist = plist; - st->priv = NULL; /* private state currently unused */ - - progress_subrange_end(&prog, &subprog); - - progress_subrange_start(0.1, 1.0, &prog, &subprog); - - /* partial success. */ - r = process_path(plist, param, &subprog); - if (r) { - st->status = POTRACE_STATUS_INCOMPLETE; - } - - progress_subrange_end(&prog, &subprog); - - return st; -} - -/* free a Potrace state, without disturbing errno. */ -void potrace_state_free(potrace_state_t *st) { - pathlist_free(st->plist); - free(st); -} - -/* free a parameter list, without disturbing errno. */ -void potrace_param_free(potrace_param_t *p) { - free(p); -} - -char *potrace_version(void) { - static char *ver = g_strdup_printf("potracelib %s", Inkscape::version_string); - return ver; -} - -/* - 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/trace/potrace/potracelib.h b/src/trace/potrace/potracelib.h deleted file mode 100644 index 0a6ddbf1f..000000000 --- a/src/trace/potrace/potracelib.h +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - -#ifndef POTRACELIB_H -#define POTRACELIB_H - -/* this file defines the API for the core Potrace library. For a more - detailed description of the API, see potracelib.pdf */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* ---------------------------------------------------------------------- */ -/* tracing parameters */ - -/* turn policies */ -#define POTRACE_TURNPOLICY_BLACK 0 -#define POTRACE_TURNPOLICY_WHITE 1 -#define POTRACE_TURNPOLICY_LEFT 2 -#define POTRACE_TURNPOLICY_RIGHT 3 -#define POTRACE_TURNPOLICY_MINORITY 4 -#define POTRACE_TURNPOLICY_MAJORITY 5 -#define POTRACE_TURNPOLICY_RANDOM 6 - -/* structure to hold progress bar callback data */ -struct potrace_progress_s { - void (*callback)(double progress, void *privdata); /* callback fn */ - void *data; /* callback function's private data */ - double min, max; /* desired range of progress, e.g. 0.0 to 1.0 */ - double epsilon; /* granularity: can skip smaller increments */ -}; -typedef struct potrace_progress_s potrace_progress_t; - -/* structure to hold tracing parameters */ -struct potrace_param_s { - int turdsize; /* area of largest path to be ignored */ - int turnpolicy; /* resolves ambiguous turns in path decomposition */ - double alphamax; /* corner threshold */ - int opticurve; /* use curve optimization? */ - double opttolerance; /* curve optimization tolerance */ - potrace_progress_t progress; /* progress callback function */ -}; -typedef struct potrace_param_s potrace_param_t; - -/* ---------------------------------------------------------------------- */ -/* bitmaps */ - -/* native word size */ -typedef unsigned long potrace_word; - -/* Internal bitmap format. The n-th scanline starts at scanline(n) = - (map + n*dy). Raster data is stored as a sequence of potrace_words - (NOT bytes). The leftmost bit of scanline n is the most significant - bit of scanline(n)[0]. */ -struct potrace_bitmap_s { - int w, h; /* width and height, in pixels */ - int dy; /* words per scanline (not bytes) */ - potrace_word *map; /* raw data, dy*h words */ -}; -typedef struct potrace_bitmap_s potrace_bitmap_t; - -/* ---------------------------------------------------------------------- */ -/* curves */ - -/* point */ -struct potrace_dpoint_s { - double x, y; -}; -typedef struct potrace_dpoint_s potrace_dpoint_t; - -/* segment tags */ -#define POTRACE_CURVETO 1 -#define POTRACE_CORNER 2 - -/* closed curve segment */ -struct potrace_curve_s { - int n; /* number of segments */ - int *tag; /* tag[n]: POTRACE_CURVETO or POTRACE_CORNER */ - potrace_dpoint_t (*c)[3]; /* c[n][3]: control points. - c[n][0] is unused for tag[n]=POTRACE_CORNER */ -}; -typedef struct potrace_curve_s potrace_curve_t; - -/* Linked list of signed curve segments. Also carries a tree structure. */ -struct potrace_path_s { - int area; /* area of the bitmap path */ - int sign; /* '+' or '-', depending on orientation */ - potrace_curve_t curve; /* this path's vector data */ - - struct potrace_path_s *next; /* linked list structure */ - - struct potrace_path_s *childlist; /* tree structure */ - struct potrace_path_s *sibling; /* tree structure */ - - struct potrace_privpath_s *priv; /* private state */ -}; -typedef struct potrace_path_s potrace_path_t; - -/* ---------------------------------------------------------------------- */ -/* Potrace state */ - -#define POTRACE_STATUS_OK 0 -#define POTRACE_STATUS_INCOMPLETE 1 - -struct potrace_state_s { - int status; - potrace_path_t *plist; /* vector data */ - - struct potrace_privstate_s *priv; /* private state */ -}; -typedef struct potrace_state_s potrace_state_t; - -/* ---------------------------------------------------------------------- */ -/* API functions */ - -/* get default parameters */ -potrace_param_t *potrace_param_default(void); - -/* free parameter set */ -void potrace_param_free(potrace_param_t *p); - -/* trace a bitmap*/ -potrace_state_t *potrace_trace(const potrace_param_t *param, - const potrace_bitmap_t *bm); - -/* free a Potrace state */ -void potrace_state_free(potrace_state_t *st); - -/* return a static plain text version string identifying this version - of potracelib */ -char *potrace_version(void); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif /* POTRACELIB_H */ diff --git a/src/trace/potrace/progress.h b/src/trace/potrace/progress.h deleted file mode 100644 index ecc2ba217..000000000 --- a/src/trace/potrace/progress.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - -/* operations on potrace_progress_t objects, which are defined in - potracelib.h. Note: the code attempts to minimize runtime overhead - when no progress monitoring was requested. It also tries to - minimize excessive progress calculations beneath the "epsilon" - threshold. */ - -#ifndef PROGRESS_H -#define PROGRESS_H - -/* structure to hold progress bar callback data */ -struct progress_s { - void (*callback)(double progress, void *privdata); /* callback fn */ - void *data; /* callback function's private data */ - double min, max; /* desired range of progress, e.g. 0.0 to 1.0 */ - double epsilon; /* granularity: can skip smaller increments */ - double b; /* upper limit of subrange in superrange units */ - double d_prev; /* previous value of d */ -}; -typedef struct progress_s progress_t; - -/* notify given progress object of current progress. Note that d is - given in the 0.0-1.0 range, which will be scaled and translated to - the progress object's range. */ -static inline void progress_update(double d, progress_t *prog) { - if (prog != NULL && prog->callback != NULL) { - double d_scaled = prog->min * (1-d) + prog->max * d; - if (d == 1.0 || d_scaled >= prog->d_prev + prog->epsilon) { - prog->callback(prog->min * (1-d) + prog->max * d, prog->data); - prog->d_prev = d_scaled; - } - } -} - -/* start a subrange of the given progress object. The range is - narrowed to [a..b], relative to 0.0-1.0 coordinates. If new range - is below granularity threshold, disable further subdivisions. */ -static inline void progress_subrange_start(double a, double b, const progress_t *prog, progress_t *sub) { - double min, max; - - if (prog == NULL || prog->callback == NULL) { - sub->callback = NULL; - return; - } - - min = prog->min * (1-a) + prog->max * a; - max = prog->min * (1-b) + prog->max * b; - - if (max - min < prog->epsilon) { - sub->callback = NULL; /* no further progress info in subrange */ - sub->b = b; - return; - } - sub->callback = prog->callback; - sub->data = prog->data; - sub->epsilon = prog->epsilon; - sub->min = min; - sub->max = max; - sub->d_prev = prog->d_prev; - return; -} - -static inline void progress_subrange_end(progress_t *prog, progress_t *sub) { - if (prog != NULL && prog->callback != NULL) { - if (sub->callback == NULL) { - progress_update(sub->b, prog); - } else { - prog->d_prev = sub->d_prev; - } - } -} - -#endif /* PROGRESS_H */ - diff --git a/src/trace/potrace/render.cpp b/src/trace/potrace/render.cpp deleted file mode 100644 index 4f44ae6a6..000000000 --- a/src/trace/potrace/render.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - - -#include -#include -#include -#include - -#include "render.h" -#include "greymap.h" -#include "auxiliary.h" - -/* ---------------------------------------------------------------------- */ -/* routines for anti-aliased rendering of curves */ - -/* we use the following method. Given a point (x,y) (with real-valued - coordinates) in the plane, let (xi,yi) be the integer part of the - coordinates, i.e., xi=floor(x), yi=floor(y). Define a path from - (x,y) to infinity as follows: path(x,y) = - (x,y)--(xi+1,y)--(xi+1,yi)--(+infty,yi). Now as the point (x,y) - moves smoothly across the plane, the path path(x,y) sweeps - (non-smoothly) across a certain area. We proportionately blacken - the area as the path moves "downward", and we whiten the area as - the path moves "upward". This way, after the point has traversed a - closed curve, the interior of the curve has been darkened - (counterclockwise movement) or lightened (clockwise movement). (The - "grey shift" is actually proportional to the winding number). By - choosing the above path with mostly integer coordinates, we achieve - that only pixels close to (x,y) receive grey values and are subject - to round-off errors. The grey value of pixels far away from (x,y) - is always in "integer" (where 0=black, 1=white). As a special - trick, we keep an accumulator rm->a1, which holds a double value to - be added to the grey value to be added to the current pixel - (xi,yi). Only when changing "current" pixels, we convert this - double value to an integer. This way we avoid round-off errors at - the meeting points of line segments. Another speedup measure is - that we sometimes use the rm->incrow_buf array to postpone - incrementing or decrementing an entire row. If incrow_buf[y]=x+1!=0, - then all the pixels (x,y),(x+1,y),(x+2,y),... are scheduled to be - incremented/decremented (which one is the case will be clear from - context). This keeps the greymap operations reasonably local. */ - -/* allocate a new rendering state */ -render_t *render_new(greymap_t *gm) { - render_t *rm; - - rm = (render_t *) malloc(sizeof(render_t)); - if (!rm) { - return NULL; - } - memset(rm, 0, sizeof(render_t)); - rm->gm = gm; - rm->incrow_buf = (int *) calloc(gm->h, sizeof(int)); - if (!rm->incrow_buf) { - free(rm); - return NULL; - } - memset(rm->incrow_buf, 0, gm->h * sizeof(int)); - return rm; -} - -/* free a given rendering state. Note: this does not free the - underlying greymap. */ -void render_free(render_t *rm) { - free(rm->incrow_buf); - free(rm); -} - -/* close path */ -void render_close(render_t *rm) { - if (rm->x0 != rm->x1 || rm->y0 != rm->y1) { - render_lineto(rm, rm->x0, rm->y0); - } - GM_INC(rm->gm, rm->x0i, rm->y0i, (rm->a0+rm->a1)*255); - - /* assert (rm->x0i != rm->x1i || rm->y0i != rm->y1i); */ - - /* the persistent state is now undefined */ -} - -/* move point */ -void render_moveto(render_t *rm, double x, double y) { - /* close the previous path */ - render_close(rm); - - rm->x0 = rm->x1 = x; - rm->y0 = rm->y1 = y; - rm->x0i = (int)floor(rm->x0); - rm->x1i = (int)floor(rm->x1); - rm->y0i = (int)floor(rm->y0); - rm->y1i = (int)floor(rm->y1); - rm->a0 = rm->a1 = 0; -} - -/* add b to pixels (x,y) and all pixels to the right of it. However, - use rm->incrow_buf as a buffer to economize on multiple calls */ -static void incrow(render_t *rm, int x, int y, int b) { - int i, x0; - - if (y < 0 || y >= rm->gm->h) { - return; - } - - if (x < 0) { - x = 0; - } else if (x > rm->gm->w) { - x = rm->gm->w; - } - if (rm->incrow_buf[y] == 0) { - rm->incrow_buf[y] = x+1; /* store x+1 so that we can use 0 for "vacant" */ - return; - } - x0 = rm->incrow_buf[y]-1; - rm->incrow_buf[y] = 0; - if (x0 < x) { - for (i=x0; igm, i, y, -b); - } - } else { - for (i=x; igm, i, y, b); - } - } -} - -/* render a straight line */ -void render_lineto(render_t *rm, double x2, double y2) { - int x2i, y2i; - double t0=2, s0=2; - int sn, tn; - double ss=2, ts=2; - double r0, r1; - int i, j; - int rxi, ryi; - int s; - - x2i = (int)floor(x2); - y2i = (int)floor(y2); - - sn = abs(x2i - rm->x1i); - tn = abs(y2i - rm->y1i); - - if (sn) { - s0 = ((x2>rm->x1 ? rm->x1i+1 : rm->x1i) - rm->x1)/(x2-rm->x1); - ss = fabs(1.0/(x2-rm->x1)); - } - if (tn) { - t0 = ((y2>rm->y1 ? rm->y1i+1 : rm->y1i) - rm->y1)/(y2-rm->y1); - ts = fabs(1.0/(y2-rm->y1)); - } - - r0 = 0; - - i = 0; - j = 0; - - rxi = rm->x1i; - ryi = rm->y1i; - - while (i=tn || (ix1,rm->y1)..(x2,y2) */ - - /* move point to r1 */ - rm->a1 += (r1-r0)*(y2-rm->y1)*(rxi+1-((r0+r1)/2.0*(x2-rm->x1)+rm->x1)); - - /* move point across pixel boundary */ - if (s && x2>rm->x1) { - GM_INC(rm->gm, rxi, ryi, rm->a1*255); - rm->a1 = 0; - rxi++; - rm->a1 += rm->y1+r1*(y2-rm->y1)-ryi; - } else if (!s && y2>rm->y1) { - GM_INC(rm->gm, rxi, ryi, rm->a1*255); - rm->a1 = 0; - incrow(rm, rxi+1, ryi, 255); - ryi++; - } else if (s && x2<=rm->x1) { - rm->a1 -= rm->y1+r1*(y2-rm->y1)-ryi; - GM_INC(rm->gm, rxi, ryi, rm->a1*255); - rm->a1 = 0; - rxi--; - } else if (!s && y2<=rm->y1) { - GM_INC(rm->gm, rxi, ryi, rm->a1*255); - rm->a1 = 0; - ryi--; - incrow(rm, rxi+1, ryi, -255); - } - - r0 = r1; - } - - /* move point to (x2,y2) */ - - r1 = 1; - rm->a1 += (r1-r0)*(y2-rm->y1)*(rxi+1-((r0+r1)/2.0*(x2-rm->x1)+rm->x1)); - - rm->x1i = x2i; - rm->y1i = y2i; - rm->x1 = x2; - rm->y1 = y2; - - /* assert (rxi != rm->x1i || ryi != rm->y1i); */ -} - -/* render a Bezier curve. */ -void render_curveto(render_t *rm, double x2, double y2, double x3, double y3, double x4, double y4) { - double x1, y1, dd0, dd1, dd, delta, e2, epsilon, t; - - x1 = rm->x1; /* starting point */ - y1 = rm->y1; - - /* we approximate the curve by small line segments. The interval - size, epsilon, is determined on the fly so that the distance - between the true curve and its approximation does not exceed the - desired accuracy delta. */ - - delta = .1; /* desired accuracy, in pixels */ - - /* let dd = maximal value of 2nd derivative over curve - this must - occur at an endpoint. */ - dd0 = sq(x1-2*x2+x3) + sq(y1-2*y2+y3); - dd1 = sq(x2-2*x3+x4) + sq(y2-2*y3+y4); - dd = 6*sqrt(max(dd0, dd1)); - e2 = 8*delta <= dd ? 8*delta/dd : 1; - epsilon = sqrt(e2); /* necessary interval size */ - - for (t=epsilon; t<1; t+=epsilon) { - render_lineto(rm, x1*cu(1-t)+3*x2*sq(1-t)*t+3*x3*(1-t)*sq(t)+x4*cu(t), - y1*cu(1-t)+3*y2*sq(1-t)*t+3*y3*(1-t)*sq(t)+y4*cu(t)); - } - render_lineto(rm, x4, y4); -} diff --git a/src/trace/potrace/render.h b/src/trace/potrace/render.h deleted file mode 100644 index 0caaedff6..000000000 --- a/src/trace/potrace/render.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - - -#ifndef RENDER_H -#define RENDER_H - -#include "greymap.h" - -struct render_s { - greymap_t *gm; - double x0, y0, x1, y1; - int x0i, y0i, x1i, y1i; - double a0, a1; - int *incrow_buf; -}; -typedef struct render_s render_t; - -render_t *render_new(greymap_t *gm); -void render_free(render_t *rm); -void render_close(render_t *rm); -void render_moveto(render_t *rm, double x, double y); -void render_lineto(render_t *rm, double x, double y); -void render_curveto(render_t *rm, double x2, double y2, double x3, double y3, double x4, double y4); - -#endif /* RENDER_H */ diff --git a/src/trace/potrace/trace.cpp b/src/trace/potrace/trace.cpp deleted file mode 100644 index 469262b67..000000000 --- a/src/trace/potrace/trace.cpp +++ /dev/null @@ -1,1245 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - -/* transform jaggy paths into smooth curves */ - -#include -#include -#include -#include - -#include "potracelib.h" -#include "curve.h" -#include "lists.h" -#include "auxiliary.h" -#include "trace.h" -#include "progress.h" - -#define INFTY 10000000 /* it suffices that this is longer than any - path; it need not be really infinite */ -#define COS179 -0.999847695156 /* the cosine of 179 degrees */ - -/* ---------------------------------------------------------------------- */ -#define SAFE_CALLOC(var, n, typ) \ - if ((var = (typ *)calloc(n, sizeof(typ))) == NULL) goto calloc_error - -/* ---------------------------------------------------------------------- */ -/* auxiliary functions */ - -/* return a direction that is 90 degrees counterclockwise from p2-p0, - but then restricted to one of the major wind directions (n, nw, w, etc) */ -static inline point_t dorth_infty(dpoint_t p0, dpoint_t p2) { - point_t r; - - r.y = sign(p2.x-p0.x); - r.x = -sign(p2.y-p0.y); - - return r; -} - -/* return (p1-p0)x(p2-p0), the area of the parallelogram */ -static inline double dpara(dpoint_t p0, dpoint_t p1, dpoint_t p2) { - double x1, y1, x2, y2; - - x1 = p1.x-p0.x; - y1 = p1.y-p0.y; - x2 = p2.x-p0.x; - y2 = p2.y-p0.y; - - return x1*y2 - x2*y1; -} - -/* ddenom/dpara have the property that the square of radius 1 centered - at p1 intersects the line p0p2 iff |dpara(p0,p1,p2)| <= ddenom(p0,p2) */ -static inline double ddenom(dpoint_t p0, dpoint_t p2) { - point_t r = dorth_infty(p0, p2); - - return r.y*(p2.x-p0.x) - r.x*(p2.y-p0.y); -} - -/* return 1 if a <= b < c < a, in a cyclic sense (mod n) */ -static inline int cyclic(int a, int b, int c) { - if (a<=c) { - return (a<=b && blen; - sums_t *sums = pp->sums; - - double x, y, x2, xy, y2; - double k; - double a, b, c, lambda2, l; - int r=0; /* rotations from i to j */ - - while (j>=n) { - j-=n; - r+=1; - } - while (i>=n) { - i-=n; - r-=1; - } - while (j<0) { - j+=n; - r-=1; - } - while (i<0) { - i+=n; - r+=1; - } - - x = sums[j+1].x-sums[i].x+r*sums[n].x; - y = sums[j+1].y-sums[i].y+r*sums[n].y; - x2 = sums[j+1].x2-sums[i].x2+r*sums[n].x2; - xy = sums[j+1].xy-sums[i].xy+r*sums[n].xy; - y2 = sums[j+1].y2-sums[i].y2+r*sums[n].y2; - k = j+1-i+r*n; - - ctr->x = x/k; - ctr->y = y/k; - - a = (x2-(double)x*x/k)/k; - b = (xy-(double)x*y/k)/k; - c = (y2-(double)y*y/k)/k; - - lambda2 = (a+c+sqrt((a-c)*(a-c)+4*b*b))/2; /* larger e.value */ - - /* now find e.vector for lambda2 */ - a -= lambda2; - c -= lambda2; - - if (fabs(a) >= fabs(c)) { - l = sqrt(a*a+b*b); - if (l!=0) { - dir->x = -b/l; - dir->y = a/l; - } - } else { - l = sqrt(c*c+b*b); - if (l!=0) { - dir->x = -c/l; - dir->y = b/l; - } - } - if (l==0) { - dir->x = dir->y = 0; /* sometimes this can happen when k=4: - the two eigenvalues coincide */ - } -} - -/* the type of (affine) quadratic forms, represented as symmetric 3x3 - matrices. The value of the quadratic form at a vector (x,y) is v^t - Q v, where v = (x,y,1)^t. */ -typedef double quadform_t[3][3]; - -/* Apply quadratic form Q to vector w = (w.x,w.y) */ -static inline double quadform(quadform_t Q, dpoint_t w) { - double v[3]; - int i, j; - double sum; - - v[0] = w.x; - v[1] = w.y; - v[2] = 1; - sum = 0.0; - - for (i=0; i<3; i++) { - for (j=0; j<3; j++) { - sum += v[i] * Q[i][j] * v[j]; - } - } - return sum; -} - -/* calculate p1 x p2 */ -static inline int xprod(point_t p1, point_t p2) { - return p1.x*p2.y - p1.y*p2.x; -} - -/* calculate (p1-p0)x(p3-p2) */ -static inline double cprod(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) { - double x1, y1, x2, y2; - - x1 = p1.x - p0.x; - y1 = p1.y - p0.y; - x2 = p3.x - p2.x; - y2 = p3.y - p2.y; - - return x1*y2 - x2*y1; -} - -/* calculate (p1-p0)*(p2-p0) */ -static inline double iprod(dpoint_t p0, dpoint_t p1, dpoint_t p2) { - double x1, y1, x2, y2; - - x1 = p1.x - p0.x; - y1 = p1.y - p0.y; - x2 = p2.x - p0.x; - y2 = p2.y - p0.y; - - return x1*x2 + y1*y2; -} - -/* calculate (p1-p0)*(p3-p2) */ -static inline double iprod1(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) { - double x1, y1, x2, y2; - - x1 = p1.x - p0.x; - y1 = p1.y - p0.y; - x2 = p3.x - p2.x; - y2 = p3.y - p2.y; - - return x1*x2 + y1*y2; -} - -/* calculate distance between two points */ -static inline double ddist(dpoint_t p, dpoint_t q) { - return sqrt(sq(p.x-q.x)+sq(p.y-q.y)); -} - -/* calculate point of a bezier curve */ -static inline dpoint_t bezier(double t, dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) { - double s = 1-t; - dpoint_t res; - - /* Note: a good optimizing compiler (such as gcc-3) reduces the - following to 16 multiplications, using common subexpression - elimination. */ - - res.x = s*s*s*p0.x + 3*(s*s*t)*p1.x + 3*(t*t*s)*p2.x + t*t*t*p3.x; - res.y = s*s*s*p0.y + 3*(s*s*t)*p1.y + 3*(t*t*s)*p2.y + t*t*t*p3.y; - - return res; -} - -/* calculate the point t in [0..1] on the (convex) bezier curve - (p0,p1,p2,p3) which is tangent to q1-q0. Return -1.0 if there is no - solution in [0..1]. */ -static double tangent(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3, dpoint_t q0, dpoint_t q1) { - double A, B, C; /* (1-t)^2 A + 2(1-t)t B + t^2 C = 0 */ - double a, b, c; /* a t^2 + b t + c = 0 */ - double d, s, r1, r2; - - A = cprod(p0, p1, q0, q1); - B = cprod(p1, p2, q0, q1); - C = cprod(p2, p3, q0, q1); - - a = A - 2*B + C; - b = -2*A + 2*B; - c = A; - - d = b*b - 4*a*c; - - if (a==0 || d<0) { - return -1.0; - } - - s = sqrt(d); - - r1 = (-b + s) / (2 * a); - r2 = (-b - s) / (2 * a); - - if (r1 >= 0 && r1 <= 1) { - return r1; - } else if (r2 >= 0 && r2 <= 1) { - return r2; - } else { - return -1.0; - } -} - -/* ---------------------------------------------------------------------- */ -/* Preparation: fill in the sum* fields of a path (used for later - rapid summing). Return 0 on success, 1 with errno set on - failure. */ -static int calc_sums(privpath_t *pp) { - int i, x, y; - int n = pp->len; - - SAFE_CALLOC(pp->sums, pp->len+1, sums_t); - - /* origin */ - pp->x0 = pp->pt[0].x; - pp->y0 = pp->pt[0].y; - - /* preparatory computation for later fast summing */ - pp->sums[0].x2 = pp->sums[0].xy = pp->sums[0].y2 = pp->sums[0].x = pp->sums[0].y = 0; - for (i=0; ipt[i].x - pp->x0; - y = pp->pt[i].y - pp->y0; - pp->sums[i+1].x = pp->sums[i].x + x; - pp->sums[i+1].y = pp->sums[i].y + y; - pp->sums[i+1].x2 = pp->sums[i].x2 + x*x; - pp->sums[i+1].xy = pp->sums[i].xy + x*y; - pp->sums[i+1].y2 = pp->sums[i].y2 + y*y; - } - return 0; - - calloc_error: - return 1; -} - -/* ---------------------------------------------------------------------- */ -/* Stage 1: determine the straight subpaths (Sec. 2.2.1). Fill in the - "lon" component of a path object (based on pt/len). For each i, - lon[i] is the furthest index such that a straight line can be drawn - from i to lon[i]. Return 1 on error with errno set, else 0. */ - -/* this algorithm depends on the fact that the existence of straight - subpaths is a triplewise property. I.e., there exists a straight - line through squares i0,...,in iff there exists a straight line - through i,j,k, for all i0<=i= 0 and xprod(constraint[1], - cur) <= 0. */ - -/* Remark for Potrace 1.1: the current implementation of calc_lon is - more complex than the implementation found in Potrace 1.0, but it - is considerably faster. The introduction of the "nc" data structure - means that we only have to test the constraints for "corner" - points. On a typical input file, this speeds up the calc_lon - function by a factor of 31.2, thereby decreasing its time share - within the overall Potrace algorithm from 72.6% to 7.82%, and - speeding up the overall algorithm by a factor of 3.36. On another - input file, calc_lon was sped up by a factor of 6.7, decreasing its - time share from 51.4% to 13.61%, and speeding up the overall - algorithm by a factor of 1.78. In any case, the savings are - substantial. */ - -/* returns 0 on success, 1 on error with errno set */ -static int calc_lon(privpath_t *pp) { - point_t *pt = pp->pt; - int n = pp->len; - int i, j, k, k1; - int ct[4], dir; - point_t constraint[2]; - point_t cur; - point_t off; - int *pivk = NULL; /* pivk[n] */ - int *nc = NULL; /* nc[n]: next corner */ - point_t dk; /* direction of k-k1 */ - int a, b, c, d; - - SAFE_CALLOC(pivk, n, int); - SAFE_CALLOC(nc, n, int); - - /* initialize the nc data structure. Point from each point to the - furthest future point to which it is connected by a vertical or - horizontal segment. We take advantage of the fact that there is - always a direction change at 0 (due to the path decomposition - algorithm). But even if this were not so, there is no harm, as - in practice, correctness does not depend on the word "furthest" - above. */ - k = 0; - for (i=n-1; i>=0; i--) { - if (pt[i].x != pt[k].x && pt[i].y != pt[k].y) { - k = i+1; /* necessarily ilon, n, int); - - /* determine pivot points: for each i, let pivk[i] be the furthest k - such that all j with i=0; i--) { - ct[0] = ct[1] = ct[2] = ct[3] = 0; - - /* keep track of "directions" that have occurred */ - dir = (3+3*(pt[mod(i+1,n)].x-pt[i].x)+(pt[mod(i+1,n)].y-pt[i].y))/2; - ct[dir]++; - - constraint[0].x = 0; - constraint[0].y = 0; - constraint[1].x = 0; - constraint[1].y = 0; - - /* find the next k such that no straight line from i to k */ - k = nc[i]; - k1 = i; - while (1) { - - dir = (3+3*sign(pt[k].x-pt[k1].x)+sign(pt[k].y-pt[k1].y))/2; - ct[dir]++; - - /* if all four "directions" have occurred, cut this path */ - if (ct[0] && ct[1] && ct[2] && ct[3]) { - pivk[i] = k1; - goto foundk; - } - - cur.x = pt[k].x - pt[i].x; - cur.y = pt[k].y - pt[i].y; - - /* see if current constraint is violated */ - if (xprod(constraint[0], cur) < 0 || xprod(constraint[1], cur) > 0) { - goto constraint_viol; - } - - /* else, update constraint */ - if (abs(cur.x) <= 1 && abs(cur.y) <= 1) { - /* no constraint */ - } else { - off.x = cur.x + ((cur.y>=0 && (cur.y>0 || cur.x<0)) ? 1 : -1); - off.y = cur.y + ((cur.x<=0 && (cur.x<0 || cur.y<0)) ? 1 : -1); - if (xprod(constraint[0], off) >= 0) { - constraint[0] = off; - } - off.x = cur.x + ((cur.y<=0 && (cur.y<0 || cur.x<0)) ? 1 : -1); - off.y = cur.y + ((cur.x>=0 && (cur.x>0 || cur.y<0)) ? 1 : -1); - if (xprod(constraint[1], off) <= 0) { - constraint[1] = off; - } - } - k1 = k; - k = nc[k1]; - if (!cyclic(k,i,k1)) { - break; - } - } - constraint_viol: - /* k1 was the last "corner" satisfying the current constraint, and - k is the first one violating it. We now need to find the last - point along k1..k which satisfied the constraint. */ - dk.x = sign(pt[k].x-pt[k1].x); - dk.y = sign(pt[k].y-pt[k1].y); - cur.x = pt[k1].x - pt[i].x; - cur.y = pt[k1].y - pt[i].y; - /* find largest integer j such that xprod(constraint[0], cur+j*dk) - >= 0 and xprod(constraint[1], cur+j*dk) <= 0. Use bilinearity - of xprod. */ - a = xprod(constraint[0], cur); - b = xprod(constraint[0], dk); - c = xprod(constraint[1], cur); - d = xprod(constraint[1], dk); - /* find largest integer j such that a+j*b>=0 and c+j*d<=0. This - can be solved with integer arithmetic. */ - j = INFTY; - if (b<0) { - j = floordiv(a,-b); - } - if (d>0) { - j = min(j, floordiv(-c,d)); - } - pivk[i] = mod(k1+j,n); - foundk: - ; - } /* for i */ - - /* clean up: for each i, let lon[i] be the largest k such that for - all i' with i<=i'lon[n-1]=j; - for (i=n-2; i>=0; i--) { - if (cyclic(i+1,pivk[i],j)) { - j=pivk[i]; - } - pp->lon[i]=j; - } - - for (i=n-1; cyclic(mod(i+1,n),j,pp->lon[i]); i--) { - pp->lon[i] = j; - } - - free(pivk); - free(nc); - return 0; - - calloc_error: - free(pivk); - free(nc); - return 1; -} - - -/* ---------------------------------------------------------------------- */ -/* Stage 2: calculate the optimal polygon (Sec. 2.2.2-2.2.4). */ - -/* Auxiliary function: calculate the penalty of an edge from i to j in - the given path. This needs the "lon" and "sum*" data. */ - -static double penalty3(privpath_t *pp, int i, int j) { - int n = pp->len; - point_t *pt = pp->pt; - sums_t *sums = pp->sums; - - /* assume 0<=i=n) { - j -= n; - r = 1; - } - - /* critical inner loop: the "if" gives a 4.6 percent speedup */ - if (r == 0) { - x = sums[j+1].x - sums[i].x; - y = sums[j+1].y - sums[i].y; - x2 = sums[j+1].x2 - sums[i].x2; - xy = sums[j+1].xy - sums[i].xy; - y2 = sums[j+1].y2 - sums[i].y2; - k = j+1 - i; - } else { - x = sums[j+1].x - sums[i].x + sums[n].x; - y = sums[j+1].y - sums[i].y + sums[n].y; - x2 = sums[j+1].x2 - sums[i].x2 + sums[n].x2; - xy = sums[j+1].xy - sums[i].xy + sums[n].xy; - y2 = sums[j+1].y2 - sums[i].y2 + sums[n].y2; - k = j+1 - i + n; - } - - px = (pt[i].x + pt[j].x) / 2.0 - pt[0].x; - py = (pt[i].y + pt[j].y) / 2.0 - pt[0].y; - ey = (pt[j].x - pt[i].x); - ex = -(pt[j].y - pt[i].y); - - a = ((x2 - 2*x*px) / k + px*px); - b = ((xy - x*py - y*px) / k + px*py); - c = ((y2 - 2*y*py) / k + py*py); - - s = ex*ex*a + 2*ex*ey*b + ey*ey*c; - - return sqrt(s); -} - -/* find the optimal polygon. Fill in the m and po components. Return 1 - on failure with errno set, else 0. Non-cyclic version: assumes i=0 - is in the polygon. Fixme: implement cyclic version. */ -static int bestpolygon(privpath_t *pp) -{ - int i, j, m, k; - int n = pp->len; - double *pen = NULL; /* pen[n+1]: penalty vector */ - int *prev = NULL; /* prev[n+1]: best path pointer vector */ - int *clip0 = NULL; /* clip0[n]: longest segment pointer, non-cyclic */ - int *clip1 = NULL; /* clip1[n+1]: backwards segment pointer, non-cyclic */ - int *seg0 = NULL; /* seg0[m+1]: forward segment bounds, m<=n */ - int *seg1 = NULL; /* seg1[m+1]: backward segment bounds, m<=n */ - double thispen; - double best; - int c; - - SAFE_CALLOC(pen, n+1, double); - SAFE_CALLOC(prev, n+1, int); - SAFE_CALLOC(clip0, n, int); - SAFE_CALLOC(clip1, n+1, int); - SAFE_CALLOC(seg0, n+1, int); - SAFE_CALLOC(seg1, n+1, int); - - /* calculate clipped paths */ - for (i=0; ilon[mod(i-1,n)]-1,n); - if (c == i) { - c = mod(i+1,n); - } - if (c < i) { - clip0[i] = n; - } else { - clip0[i] = c; - } - } - - /* calculate backwards path clipping, non-cyclic. j <= clip0[i] iff - clip1[j] <= i, for i,j=0..n. */ - j = 1; - for (i=0; i0; j--) { - seg1[j] = i; - i = clip1[i]; - } - seg1[0] = 0; - - /* now find the shortest path with m segments, based on penalty3 */ - /* note: the outer 2 loops jointly have at most n iterations, thus - the worst-case behavior here is quadratic. In practice, it is - close to linear since the inner loop tends to be short. */ - pen[0]=0; - for (j=1; j<=m; j++) { - for (i=seg1[j]; i<=seg0[j]; i++) { - best = -1; - for (k=seg0[j-1]; k>=clip1[i]; k--) { - thispen = penalty3(pp, k, i) + pen[k]; - if (best < 0 || thispen < best) { - prev[i] = k; - best = thispen; - } - } - pen[i] = best; - } - } - - pp->m = m; - SAFE_CALLOC(pp->po, m, int); - - /* read off shortest path */ - for (i=n, j=m-1; i>0; j--) { - i = prev[i]; - pp->po[j] = i; - } - - free(pen); - free(prev); - free(clip0); - free(clip1); - free(seg0); - free(seg1); - return 0; - - calloc_error: - free(pen); - free(prev); - free(clip0); - free(clip1); - free(seg0); - free(seg1); - return 1; -} - -/* ---------------------------------------------------------------------- */ -/* Stage 3: vertex adjustment (Sec. 2.3.1). */ - -/* Adjust vertices of optimal polygon: calculate the intersection of - the two "optimal" line segments, then move it into the unit square - if it lies outside. Return 1 with errno set on error; 0 on - success. */ - -static int adjust_vertices(privpath_t *pp) { - int m = pp->m; - int *po = pp->po; - int n = pp->len; - point_t *pt = pp->pt; - int x0 = pp->x0; - int y0 = pp->y0; - - dpoint_t *ctr = NULL; /* ctr[m] */ - dpoint_t *dir = NULL; /* dir[m] */ - quadform_t *q = NULL; /* q[m] */ - double v[3]; - double d; - int i, j, k, l; - dpoint_t s; - int r; - - SAFE_CALLOC(ctr, m, dpoint_t); - SAFE_CALLOC(dir, m, dpoint_t); - SAFE_CALLOC(q, m, quadform_t); - - r = privcurve_init(&pp->curve, m); - if (r) { - goto calloc_error; - } - - /* calculate "optimal" point-slope representation for each line - segment */ - for (i=0; iQ[1][1]) { - v[0] = -Q[0][1]; - v[1] = Q[0][0]; - } else if (Q[1][1]) { - v[0] = -Q[1][1]; - v[1] = Q[1][0]; - } else { - v[0] = 1; - v[1] = 0; - } - d = sq(v[0]) + sq(v[1]); - v[2] = - v[1] * s.y - v[0] * s.x; - for (l=0; l<3; l++) { - for (k=0; k<3; k++) { - Q[l][k] += v[l] * v[k] / d; - } - } - } - dx = fabs(w.x-s.x); - dy = fabs(w.y-s.y); - if (dx <= .5 && dy <= .5) { - pp->curve.vertex[i].x = w.x+x0; - pp->curve.vertex[i].y = w.y+y0; - continue; - } - - /* the minimum was not in the unit square; now minimize quadratic - on boundary of square */ - min = quadform(Q, s); - xmin = s.x; - ymin = s.y; - - if (Q[0][0] == 0.0) { - goto fixx; - } - for (z=0; z<2; z++) { /* value of the y-coordinate */ - w.y = s.y-0.5+z; - w.x = - (Q[0][1] * w.y + Q[0][2]) / Q[0][0]; - dx = fabs(w.x-s.x); - cand = quadform(Q, w); - if (dx <= .5 && cand < min) { - min = cand; - xmin = w.x; - ymin = w.y; - } - } - fixx: - if (Q[1][1] == 0.0) { - goto corners; - } - for (z=0; z<2; z++) { /* value of the x-coordinate */ - w.x = s.x-0.5+z; - w.y = - (Q[1][0] * w.x + Q[1][2]) / Q[1][1]; - dy = fabs(w.y-s.y); - cand = quadform(Q, w); - if (dy <= .5 && cand < min) { - min = cand; - xmin = w.x; - ymin = w.y; - } - } - corners: - /* check four corners */ - for (l=0; l<2; l++) { - for (k=0; k<2; k++) { - w.x = s.x-0.5+l; - w.y = s.y-0.5+k; - cand = quadform(Q, w); - if (cand < min) { - min = cand; - xmin = w.x; - ymin = w.y; - } - } - } - - pp->curve.vertex[i].x = xmin + x0; - pp->curve.vertex[i].y = ymin + y0; - continue; - } - - free(ctr); - free(dir); - free(q); - return 0; - - calloc_error: - free(ctr); - free(dir); - free(q); - return 1; -} - -/* ---------------------------------------------------------------------- */ -/* Stage 4: smoothing and corner analysis (Sec. 2.3.3) */ - -/* reverse orientation of a path */ -static void reverse(privcurve_t *curve) { - int m = curve->n; - int i, j; - dpoint_t tmp; - - for (i=0, j=m-1; ivertex[i]; - curve->vertex[i] = curve->vertex[j]; - curve->vertex[j] = tmp; - } -} - -/* Always succeeds */ -static void smooth(privcurve_t *curve, double alphamax) { - int m = curve->n; - - int i, j, k; - double dd, denom, alpha; - dpoint_t p2, p3, p4; - - /* examine each vertex and find its best fit */ - for (i=0; ivertex[k], curve->vertex[j]); - - denom = ddenom(curve->vertex[i], curve->vertex[k]); - if (denom != 0.0) { - dd = dpara(curve->vertex[i], curve->vertex[j], curve->vertex[k]) / denom; - dd = fabs(dd); - alpha = dd>1 ? (1 - 1.0/dd) : 0; - alpha = alpha / 0.75; - } else { - alpha = 4/3.0; - } - curve->alpha0[j] = alpha; /* remember "original" value of alpha */ - - if (alpha >= alphamax) { /* pointed corner */ - curve->tag[j] = POTRACE_CORNER; - curve->c[j][1] = curve->vertex[j]; - curve->c[j][2] = p4; - } else { - if (alpha < 0.55) { - alpha = 0.55; - } else if (alpha > 1) { - alpha = 1; - } - p2 = interval(.5+.5*alpha, curve->vertex[i], curve->vertex[j]); - p3 = interval(.5+.5*alpha, curve->vertex[k], curve->vertex[j]); - curve->tag[j] = POTRACE_CURVETO; - curve->c[j][0] = p2; - curve->c[j][1] = p3; - curve->c[j][2] = p4; - } - curve->alpha[j] = alpha; /* store the "cropped" value of alpha */ - curve->beta[j] = 0.5; - } - curve->alphacurve = 1; - - return; -} - -/* ---------------------------------------------------------------------- */ -/* Stage 5: Curve optimization (Sec. 2.4) */ - -/* a private type for the result of opti_penalty */ -struct opti_s { - double pen; /* penalty */ - dpoint_t c[2]; /* curve parameters */ - double t, s; /* curve parameters */ - double alpha; /* curve parameter */ -}; -typedef struct opti_s opti_t; - -/* calculate best fit from i+.5 to j+.5. Assume icurve.n; - int k, k1, k2, conv, i1; - double area, alpha, d, d1, d2; - dpoint_t p0, p1, p2, p3, pt; - double A, R, A1, A2, A3, A4; - double s, t; - - /* check convexity, corner-freeness, and maximum bend < 179 degrees */ - - if (i==j) { /* sanity - a full loop can never be an opticurve */ - return 1; - } - - k = i; - i1 = mod(i+1, m); - k1 = mod(k+1, m); - conv = convc[k1]; - if (conv == 0) { - return 1; - } - d = ddist(pp->curve.vertex[i], pp->curve.vertex[i1]); - for (k=k1; k!=j; k=k1) { - k1 = mod(k+1, m); - k2 = mod(k+2, m); - if (convc[k1] != conv) { - return 1; - } - if (sign(cprod(pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1], pp->curve.vertex[k2])) != conv) { - return 1; - } - if (iprod1(pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1], pp->curve.vertex[k2]) < d * ddist(pp->curve.vertex[k1], pp->curve.vertex[k2]) * COS179) { - return 1; - } - } - - /* the curve we're working in: */ - p0 = pp->curve.c[mod(i,m)][2]; - p1 = pp->curve.vertex[mod(i+1,m)]; - p2 = pp->curve.vertex[mod(j,m)]; - p3 = pp->curve.c[mod(j,m)][2]; - - /* determine its area */ - area = areac[j] - areac[i]; - area -= dpara(pp->curve.vertex[0], pp->curve.c[i][2], pp->curve.c[j][2])/2; - if (i>=j) { - area += areac[m]; - } - - /* find intersection o of p0p1 and p2p3. Let t,s such that o = - interval(t,p0,p1) = interval(s,p3,p2). Let A be the area of the - triangle (p0,o,p3). */ - - A1 = dpara(p0, p1, p2); - A2 = dpara(p0, p1, p3); - A3 = dpara(p0, p2, p3); - /* A4 = dpara(p1, p2, p3); */ - A4 = A1+A3-A2; - - if (A2 == A1) { /* this should never happen */ - return 1; - } - - t = A3/(A3-A4); - s = A2/(A2-A1); - A = A2 * t / 2.0; - - if (A == 0.0) { /* this should never happen */ - return 1; - } - - R = area / A; /* relative area */ - alpha = 2 - sqrt(4 - R / 0.3); /* overall alpha for p0-o-p3 curve */ - - res->c[0] = interval(t * alpha, p0, p1); - res->c[1] = interval(s * alpha, p3, p2); - res->alpha = alpha; - res->t = t; - res->s = s; - - p1 = res->c[0]; - p2 = res->c[1]; /* the proposed curve is now (p0,p1,p2,p3) */ - - res->pen = 0; - - /* calculate penalty */ - /* check tangency with edges */ - for (k=mod(i+1,m); k!=j; k=k1) { - k1 = mod(k+1,m); - t = tangent(p0, p1, p2, p3, pp->curve.vertex[k], pp->curve.vertex[k1]); - if (t<-.5) { - return 1; - } - pt = bezier(t, p0, p1, p2, p3); - d = ddist(pp->curve.vertex[k], pp->curve.vertex[k1]); - if (d == 0.0) { /* this should never happen */ - return 1; - } - d1 = dpara(pp->curve.vertex[k], pp->curve.vertex[k1], pt) / d; - if (fabs(d1) > opttolerance) { - return 1; - } - if (iprod(pp->curve.vertex[k], pp->curve.vertex[k1], pt) < 0 || iprod(pp->curve.vertex[k1], pp->curve.vertex[k], pt) < 0) { - return 1; - } - res->pen += sq(d1); - } - - /* check corners */ - for (k=i; k!=j; k=k1) { - k1 = mod(k+1,m); - t = tangent(p0, p1, p2, p3, pp->curve.c[k][2], pp->curve.c[k1][2]); - if (t<-.5) { - return 1; - } - pt = bezier(t, p0, p1, p2, p3); - d = ddist(pp->curve.c[k][2], pp->curve.c[k1][2]); - if (d == 0.0) { /* this should never happen */ - return 1; - } - d1 = dpara(pp->curve.c[k][2], pp->curve.c[k1][2], pt) / d; - d2 = dpara(pp->curve.c[k][2], pp->curve.c[k1][2], pp->curve.vertex[k1]) / d; - d2 *= 0.75 * pp->curve.alpha[k1]; - if (d2 < 0) { - d1 = -d1; - d2 = -d2; - } - if (d1 < d2 - opttolerance) { - return 1; - } - if (d1 < d2) { - res->pen += sq(d1 - d2); - } - } - - return 0; -} - -/* optimize the path p, replacing sequences of Bezier segments by a - single segment when possible. Return 0 on success, 1 with errno set - on failure. */ -static int opticurve(privpath_t *pp, double opttolerance) { - int m = pp->curve.n; - int *pt = NULL; /* pt[m+1] */ - double *pen = NULL; /* pen[m+1] */ - int *len = NULL; /* len[m+1] */ - opti_t *opt = NULL; /* opt[m+1] */ - int om; - int i,j,r; - opti_t o; - dpoint_t p0; - int i1; - double area; - double alpha; - double *s = NULL; - double *t = NULL; - - int *convc = NULL; /* conv[m]: pre-computed convexities */ - double *areac = NULL; /* cumarea[m+1]: cache for fast area computation */ - - SAFE_CALLOC(pt, m+1, int); - SAFE_CALLOC(pen, m+1, double); - SAFE_CALLOC(len, m+1, int); - SAFE_CALLOC(opt, m+1, opti_t); - SAFE_CALLOC(convc, m, int); - SAFE_CALLOC(areac, m+1, double); - - /* pre-calculate convexity: +1 = right turn, -1 = left turn, 0 = corner */ - for (i=0; icurve.tag[i] == POTRACE_CURVETO) { - convc[i] = sign(dpara(pp->curve.vertex[mod(i-1,m)], pp->curve.vertex[i], pp->curve.vertex[mod(i+1,m)])); - } else { - convc[i] = 0; - } - } - - /* pre-calculate areas */ - area = 0.0; - areac[0] = 0.0; - p0 = pp->curve.vertex[0]; - for (i=0; icurve.tag[i1] == POTRACE_CURVETO) { - alpha = pp->curve.alpha[i1]; - area += 0.3*alpha*(4-alpha)*dpara(pp->curve.c[i][2], pp->curve.vertex[i1], pp->curve.c[i1][2])/2; - area += dpara(p0, pp->curve.c[i][2], pp->curve.c[i1][2])/2; - } - areac[i+1] = area; - } - - pt[0] = -1; - pen[0] = 0; - len[0] = 0; - - /* Fixme: we always start from a fixed point -- should find the best - curve cyclically */ - - for (j=1; j<=m; j++) { - /* calculate best path from 0 to j */ - pt[j] = j-1; - pen[j] = pen[j-1]; - len[j] = len[j-1]+1; - - for (i=j-2; i>=0; i--) { - r = opti_penalty(pp, i, mod(j,m), &o, opttolerance, convc, areac); - if (r) { - break; - } - if (len[j] > len[i]+1 || (len[j] == len[i]+1 && pen[j] > pen[i] + o.pen)) { - pt[j] = i; - pen[j] = pen[i] + o.pen; - len[j] = len[i] + 1; - opt[j] = o; - } - } - } - om = len[m]; - r = privcurve_init(&pp->ocurve, om); - if (r) { - goto calloc_error; - } - SAFE_CALLOC(s, om, double); - SAFE_CALLOC(t, om, double); - - j = m; - for (i=om-1; i>=0; i--) { - if (pt[j]==j-1) { - pp->ocurve.tag[i] = pp->curve.tag[mod(j,m)]; - pp->ocurve.c[i][0] = pp->curve.c[mod(j,m)][0]; - pp->ocurve.c[i][1] = pp->curve.c[mod(j,m)][1]; - pp->ocurve.c[i][2] = pp->curve.c[mod(j,m)][2]; - pp->ocurve.vertex[i] = pp->curve.vertex[mod(j,m)]; - pp->ocurve.alpha[i] = pp->curve.alpha[mod(j,m)]; - pp->ocurve.alpha0[i] = pp->curve.alpha0[mod(j,m)]; - pp->ocurve.beta[i] = pp->curve.beta[mod(j,m)]; - s[i] = t[i] = 1.0; - } else { - pp->ocurve.tag[i] = POTRACE_CURVETO; - pp->ocurve.c[i][0] = opt[j].c[0]; - pp->ocurve.c[i][1] = opt[j].c[1]; - pp->ocurve.c[i][2] = pp->curve.c[mod(j,m)][2]; - pp->ocurve.vertex[i] = interval(opt[j].s, pp->curve.c[mod(j,m)][2], pp->curve.vertex[mod(j,m)]); - pp->ocurve.alpha[i] = opt[j].alpha; - pp->ocurve.alpha0[i] = opt[j].alpha; - s[i] = opt[j].s; - t[i] = opt[j].t; - } - j = pt[j]; - } - - /* calculate beta parameters */ - for (i=0; iocurve.beta[i] = s[i] / (s[i] + t[i1]); - } - pp->ocurve.alphacurve = 1; - - free(pt); - free(pen); - free(len); - free(opt); - free(s); - free(t); - free(convc); - free(areac); - return 0; - - calloc_error: - free(pt); - free(pen); - free(len); - free(opt); - free(s); - free(t); - free(convc); - free(areac); - return 1; -} - -/* ---------------------------------------------------------------------- */ - -#define TRY(x) if (x) goto try_error - -/* return 0 on success, 1 on error with errno set. */ -int process_path(path_t *plist, const potrace_param_t *param, progress_t *progress) { - path_t *p; - double nn = 0, cn = 0; - - if (progress->callback) { - /* precompute task size for progress estimates */ - nn = 0; - list_forall (p, plist) { - nn += p->priv->len; - } - cn = 0; - } - - /* call downstream function with each path */ - list_forall (p, plist) { - TRY(calc_sums(p->priv)); - TRY(calc_lon(p->priv)); - TRY(bestpolygon(p->priv)); - TRY(adjust_vertices(p->priv)); - if (p->sign == '-') { /* reverse orientation of negative paths */ - reverse(&p->priv->curve); - } - smooth(&p->priv->curve, param->alphamax); - if (param->opticurve) { - TRY(opticurve(p->priv, param->opttolerance)); - p->priv->fcurve = &p->priv->ocurve; - } else { - p->priv->fcurve = &p->priv->curve; - } - privcurve_to_curve(p->priv->fcurve, &p->curve); - - if (progress->callback) { - cn += p->priv->len; - progress_update(cn/nn, progress); - } - } - - progress_update(1.0, progress); - - return 0; - - try_error: - return 1; -} diff --git a/src/trace/potrace/trace.h b/src/trace/potrace/trace.h deleted file mode 100644 index c53cdd10f..000000000 --- a/src/trace/potrace/trace.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright (C) 2001-2015 Peter Selinger. - This file is part of Potrace. It is free software and it is covered - by the GNU General Public License. See the file COPYING for details. */ - - -#ifndef TRACE_H -#define TRACE_H - -#include "potracelib.h" -#include "progress.h" -#include "curve.h" - -int process_path(path_t *plist, const potrace_param_t *param, progress_t *progress); - -#endif /* TRACE_H */ -- cgit v1.2.3 From 58771b947fcc68fd14ecc00752e5ec44c89955e9 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 8 Nov 2015 17:47:56 +0000 Subject: Update Potrace bitmap macros to upstream 1.13 (bzr r14449.1.2) --- src/trace/potrace/bitmap.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/trace/potrace/bitmap.h b/src/trace/potrace/bitmap.h index 086bbb046..7b5a94bb1 100644 --- a/src/trace/potrace/bitmap.h +++ b/src/trace/potrace/bitmap.h @@ -8,6 +8,7 @@ #include #include #include +#include /* The bitmap type is defined in potracelib.h */ #include "potracelib.h" @@ -28,7 +29,7 @@ /* macros for accessing pixel at index (x,y). U* macros omit the bounds check. */ -#define bm_scanline(bm, y) ((bm)->map + (ssize_t)(y)*(ssize_t)(bm)->dy) +#define bm_scanline(bm, y) ((bm)->map + (ptrdiff_t)(y)*(ptrdiff_t)(bm)->dy) #define bm_index(bm, x, y) (&bm_scanline(bm, y)[(x)/BM_WORDBITS]) #define bm_mask(x) (BM_HIBIT >> ((x) & (BM_WORDBITS-1))) #define bm_range(x, a) ((int)(x) >= 0 && (int)(x) < (a)) @@ -57,10 +58,10 @@ static inline void bm_free(potrace_bitmap_t *bm) { static inline potrace_bitmap_t *bm_new(int w, int h) { potrace_bitmap_t *bm; int dy = w == 0 ? 0 : (w - 1) / BM_WORDBITS + 1; - ssize_t size = (ssize_t)dy * (ssize_t)h * (ssize_t)BM_WORDSIZE; + ptrdiff_t size = (ptrdiff_t)dy * (ptrdiff_t)h * (ptrdiff_t)BM_WORDSIZE; /* check for overflow error */ - if (size < 0 || size / h / dy != BM_WORDSIZE) { + if (size < 0 || (h != 0 && dy != 0 && size / h / dy != BM_WORDSIZE)) { errno = ENOMEM; return NULL; } @@ -83,15 +84,15 @@ static inline potrace_bitmap_t *bm_new(int w, int h) { /* clear the given bitmap. Set all bits to c. */ static inline void bm_clear(potrace_bitmap_t *bm, int c) { /* Note: if the bitmap was created with bm_new, then it is - guaranteed that size will fit into the ssize_t type. */ - ssize_t size = (ssize_t)bm->dy * (ssize_t)bm->h * (ssize_t)BM_WORDSIZE; + guaranteed that size will fit into the ptrdiff_t type. */ + ptrdiff_t size = (ptrdiff_t)bm->dy * (ptrdiff_t)bm->h * (ptrdiff_t)BM_WORDSIZE; memset(bm->map, c ? -1 : 0, size); } /* duplicate the given bitmap. Return NULL on error with errno set. */ static inline potrace_bitmap_t *bm_dup(const potrace_bitmap_t *bm) { potrace_bitmap_t *bm1 = bm_new(bm->w, bm->h); - ssize_t size = (ssize_t)bm->dy * (ssize_t)bm->h * (ssize_t)BM_WORDSIZE; + ptrdiff_t size = (ptrdiff_t)bm->dy * (ptrdiff_t)bm->h * (ptrdiff_t)BM_WORDSIZE; if (!bm1) { return NULL; } @@ -101,8 +102,8 @@ static inline potrace_bitmap_t *bm_dup(const potrace_bitmap_t *bm) { /* invert the given bitmap. */ static inline void bm_invert(potrace_bitmap_t *bm) { - ssize_t i; - ssize_t size = (ssize_t)bm->dy * (ssize_t)bm->h; + ptrdiff_t i; + ptrdiff_t size = (ptrdiff_t)bm->dy * (ptrdiff_t)bm->h; for (i = 0; i < size; i++) { bm->map[i] ^= BM_ALLBITS; -- cgit v1.2.3 From 6484d2580d5facccf1b4bd7719c5d26fb8d07602 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Mon, 9 Nov 2015 00:03:27 +0000 Subject: Add CMake check for Potrace from OSP: http://goo.gl/AEzbkQ Fixed bugs: - https://launchpad.net/bugs/1156664 (bzr r14449.1.3) --- src/trace/CMakeLists.txt | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'src') diff --git a/src/trace/CMakeLists.txt b/src/trace/CMakeLists.txt index bf7cfa276..776d96158 100644 --- a/src/trace/CMakeLists.txt +++ b/src/trace/CMakeLists.txt @@ -7,14 +7,7 @@ set(trace_SRC siox.cpp trace.cpp - potrace/curve.cpp - potrace/decompose.cpp - potrace/greymap.cpp potrace/inkscape-potrace.cpp - potrace/potracelib.cpp - potrace/render.cpp - potrace/trace.cpp - # ------- # Headers @@ -26,18 +19,8 @@ set(trace_SRC siox.h trace.h - potrace/auxiliary.h potrace/bitmap.h - potrace/bitops.h - potrace/curve.h - potrace/decompose.h - potrace/greymap.h potrace/inkscape-potrace.h - potrace/lists.h - potrace/potracelib.h - potrace/progress.h - potrace/render.h - potrace/trace.h ) # add_inkscape_lib(trace_LIB "${trace_SRC}") -- cgit v1.2.3 From 94f3d50ddcbd6ceca8d3d834554a5100142648e4 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Mon, 9 Nov 2015 00:46:25 +0000 Subject: Enable builds without flood/trace on systems without Potrace (bzr r14449.1.4) --- src/menus-skeleton.h | 8 +++++++- src/trace/Makefile_insert | 4 ++++ src/ui/dialog/Makefile_insert | 10 ++++++++-- src/ui/dialog/dialog-manager.cpp | 14 +++++++++++++- src/ui/tool-factory.cpp | 8 +++++++- src/ui/tools/Makefile_insert | 10 ++++++++-- src/widgets/Makefile_insert | 10 ++++++++-- src/widgets/toolbox.cpp | 15 ++++++++++++++- 8 files changed, 69 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index f5e815bf6..b02b31bd9 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -1,7 +1,9 @@ #ifndef SEEN_MENUS_SKELETON_H #define SEEN_MENUS_SKELETON_H -#include "config.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif #ifdef __cplusplus #undef N_ @@ -221,7 +223,11 @@ static char const menus_skeleton[] = " \n" " \n" " \n" + +#if HAVE_POTRACE " \n" +#endif + " \n" " \n" " \n" diff --git a/src/trace/Makefile_insert b/src/trace/Makefile_insert index 9c300aa8d..27353df15 100644 --- a/src/trace/Makefile_insert +++ b/src/trace/Makefile_insert @@ -1,5 +1,7 @@ ## Makefile.am fragment sourced by src/Makefile.am. +if HAVE_POTRACE + ink_common_sources += \ trace/pool.h \ trace/trace.h \ @@ -17,3 +19,5 @@ ink_common_sources += \ trace/potrace/bitmap.h \ trace/potrace/inkscape-potrace.cpp \ trace/potrace/inkscape-potrace.h + +endif diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index cbdae1cb0..793988a7d 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -106,8 +106,6 @@ ink_common_sources += \ ui/dialog/text-edit.h \ ui/dialog/tile.cpp \ ui/dialog/tile.h \ - ui/dialog/tracedialog.cpp \ - ui/dialog/tracedialog.h \ ui/dialog/pixelartdialog.cpp \ ui/dialog/pixelartdialog.h \ ui/dialog/transformation.cpp \ @@ -123,3 +121,11 @@ ink_common_sources += \ ui/dialog/lpe-fillet-chamfer-properties.cpp \ ui/dialog/lpe-fillet-chamfer-properties.h \ $(inkboard_dialogs) + +if HAVE_POTRACE + +ink_common_sources += \ + ui/dialog/tracedialog.cpp \ + ui/dialog/tracedialog.h + +endif diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 7b1b36908..49853277c 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -34,7 +34,11 @@ #include "ui/dialog/messages.h" #include "ui/dialog/symbols.h" #include "ui/dialog/tile.h" -#include "ui/dialog/tracedialog.h" + +#if HAVE_POTRACE +# include "ui/dialog/tracedialog.h" +#endif + #include "ui/dialog/pixelartdialog.h" #include "ui/dialog/transformation.h" #include "ui/dialog/undo-history.h" @@ -124,7 +128,11 @@ DialogManager::DialogManager() { registerFactory("Swatches", &create); registerFactory("TileDialog", &create); registerFactory("Symbols", &create); + +#if HAVE_POTRACE registerFactory("Trace", &create); +#endif + registerFactory("PixelArt", &create); registerFactory("Transformation", &create); registerFactory("UndoHistory", &create); @@ -159,7 +167,11 @@ DialogManager::DialogManager() { registerFactory("Swatches", &create); registerFactory("TileDialog", &create); registerFactory("Symbols", &create); + +#if HAVE_POTRACE registerFactory("Trace", &create); +#endif + registerFactory("PixelArt", &create); registerFactory("Transformation", &create); registerFactory("UndoHistory", &create); diff --git a/src/ui/tool-factory.cpp b/src/ui/tool-factory.cpp index 700bd40ce..c6c579c9e 100644 --- a/src/ui/tool-factory.cpp +++ b/src/ui/tool-factory.cpp @@ -16,7 +16,11 @@ #include "ui/tools/connector-tool.h" #include "ui/tools/dropper-tool.h" #include "ui/tools/eraser-tool.h" -#include "ui/tools/flood-tool.h" + +#if HAVE_POTRACE +# include "ui/tools/flood-tool.h" +#endif + #include "ui/tools/gradient-tool.h" #include "ui/tools/lpe-tool.h" #include "ui/tools/measure-tool.h" @@ -52,8 +56,10 @@ ToolBase *ToolFactory::createObject(std::string const& id) tool = new DropperTool; else if (id == "/tools/eraser") tool = new EraserTool; +#if HAVE_POTRACE else if (id == "/tools/paintbucket") tool = new FloodTool; +#endif else if (id == "/tools/gradient") tool = new GradientTool; else if (id == "/tools/lpetool") diff --git a/src/ui/tools/Makefile_insert b/src/ui/tools/Makefile_insert index cd09a3230..686dfedd8 100644 --- a/src/ui/tools/Makefile_insert +++ b/src/ui/tools/Makefile_insert @@ -8,7 +8,6 @@ ink_common_sources += \ ui/tools/dropper-tool.cpp ui/tools/dropper-tool.h \ ui/tools/dynamic-base.cpp ui/tools/dynamic-base.h \ ui/tools/eraser-tool.cpp ui/tools/eraser-tool.h \ - ui/tools/flood-tool.cpp ui/tools/flood-tool.h \ ui/tools/freehand-base.cpp ui/tools/freehand-base.h \ ui/tools/gradient-tool.cpp ui/tools/gradient-tool.h \ ui/tools/lpe-tool.cpp ui/tools/lpe-tool.h \ @@ -25,4 +24,11 @@ ink_common_sources += \ ui/tools/text-tool.cpp ui/tools/text-tool.h \ ui/tools/tool-base.cpp ui/tools/tool-base.h \ ui/tools/tweak-tool.cpp ui/tools/tweak-tool.h \ - ui/tools/zoom-tool.cpp ui/tools/zoom-tool.h \ No newline at end of file + ui/tools/zoom-tool.cpp ui/tools/zoom-tool.h + +if HAVE_POTRACE + +ink_common_sources += \ + ui/tools/flood-tool.cpp ui/tools/flood-tool.h + +endif diff --git a/src/widgets/Makefile_insert b/src/widgets/Makefile_insert index f66be66ed..6913f4a58 100644 --- a/src/widgets/Makefile_insert +++ b/src/widgets/Makefile_insert @@ -58,8 +58,6 @@ ink_common_sources += \ widgets/node-toolbar.h \ widgets/paint-selector.cpp \ widgets/paint-selector.h \ - widgets/paintbucket-toolbar.cpp \ - widgets/paintbucket-toolbar.h \ widgets/pencil-toolbar.cpp \ widgets/pencil-toolbar.h \ widgets/rect-toolbar.cpp \ @@ -109,5 +107,13 @@ ink_common_sources += \ widgets/zoom-toolbar.h \ widgets/widget-sizes.h +if HAVE_POTRACE + +ink_common_sources += \ + widgets/paintbucket-toolbar.cpp \ + widgets/paintbucket-toolbar.h + +endif + widgets/button.$(OBJEXT): helper/sp-marshal.h widgets/menu.$(OBJEXT): helper/sp-marshal.h diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 90103325a..4a047d4de 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -78,7 +78,11 @@ #include "measure-toolbar.h" #include "node-toolbar.h" #include "rect-toolbar.h" -#include "paintbucket-toolbar.h" + +#if HAVE_POTRACE +# include "paintbucket-toolbar.h" +#endif + #include "pencil-toolbar.h" #include "select-toolbar.h" #include "spray-toolbar.h" @@ -150,7 +154,9 @@ static struct { { "/tools/calligraphic", "dyna_draw_tool", SP_VERB_CONTEXT_CALLIGRAPHIC, SP_VERB_CONTEXT_CALLIGRAPHIC_PREFS }, { "/tools/lpetool", "lpetool_tool", SP_VERB_CONTEXT_LPETOOL, SP_VERB_CONTEXT_LPETOOL_PREFS }, { "/tools/eraser", "eraser_tool", SP_VERB_CONTEXT_ERASER, SP_VERB_CONTEXT_ERASER_PREFS }, +#if HAVE_POTRACE { "/tools/paintbucket", "paintbucket_tool", SP_VERB_CONTEXT_PAINTBUCKET, SP_VERB_CONTEXT_PAINTBUCKET_PREFS }, +#endif { "/tools/text", "text_tool", SP_VERB_CONTEXT_TEXT, SP_VERB_CONTEXT_TEXT_PREFS }, { "/tools/connector","connector_tool", SP_VERB_CONTEXT_CONNECTOR, SP_VERB_CONTEXT_CONNECTOR_PREFS }, { "/tools/gradient", "gradient_tool", SP_VERB_CONTEXT_GRADIENT, SP_VERB_CONTEXT_GRADIENT_PREFS }, @@ -211,8 +217,10 @@ static struct { SP_VERB_INVALID, 0, 0}, { "/tools/mesh", "mesh_toolbox", 0, sp_mesh_toolbox_prep, "MeshToolbar", SP_VERB_INVALID, 0, 0}, +#if HAVE_POTRACE { "/tools/paintbucket", "paintbucket_toolbox", 0, sp_paintbucket_toolbox_prep, "PaintbucketToolbar", SP_VERB_CONTEXT_PAINTBUCKET_PREFS, "/tools/paintbucket", N_("Style of Paint Bucket fill objects")}, +#endif { NULL, NULL, NULL, NULL, NULL, SP_VERB_INVALID, NULL, NULL } }; @@ -454,6 +462,7 @@ static gchar const * ui_descr = " " " " +#if HAVE_POTRACE " " " " " " @@ -466,6 +475,7 @@ static gchar const * ui_descr = " " " " " " +#endif " " " " @@ -1308,8 +1318,11 @@ void setup_tool_toolbox(GtkWidget *toolbox, SPDesktop *desktop) " " " " +#if HAVE_POTRACE " " " " +#endif + " " #ifdef WITH_MESH " " -- cgit v1.2.3 From 322711ea12ec4ec3b129e3415fa1a1bd8bc7060f Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 10 Nov 2015 13:57:55 +0100 Subject: 'direction' is an inherited property, remove 'set' requirement. (bzr r14430.1.4) --- src/libnrtype/Layout-TNG-Compute.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 7cae1eb8a..8f7f6bca0 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -1072,11 +1072,10 @@ void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) con para->direction = LEFT_TO_RIGHT; // CSS default if (_flow._input_stream[para->first_input_index]->Type() == TEXT_SOURCE) { Layout::InputStreamTextSource const *text_source = static_cast(_flow._input_stream[para->first_input_index]); - if (text_source->style->direction.set) { - para->direction = (text_source->style->direction.computed == SP_CSS_DIRECTION_LTR) ? LEFT_TO_RIGHT : RIGHT_TO_LEFT; - PangoDirection pango_direction = (text_source->style->direction.computed == SP_CSS_DIRECTION_LTR) ? PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL; - pango_items_glist = pango_itemize_with_base_dir(_pango_context, pango_direction, para_text.data(), 0, para_text.bytes(), attributes_list, NULL); - } + + para->direction = (text_source->style->direction.computed == SP_CSS_DIRECTION_LTR) ? LEFT_TO_RIGHT : RIGHT_TO_LEFT; + PangoDirection pango_direction = (text_source->style->direction.computed == SP_CSS_DIRECTION_LTR) ? PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL; + pango_items_glist = pango_itemize_with_base_dir(_pango_context, pango_direction, para_text.data(), 0, para_text.bytes(), attributes_list, NULL); } if( pango_items_glist == NULL ) { -- cgit v1.2.3 From 31aa6219ac721c59cb1a98788dbca7b7a58c5000 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 10 Nov 2015 18:23:11 +0100 Subject: Spray Tool: Change hide invisibe by over visible and over invisible, sugested by Ivan Louette (bzr r14453) --- src/ui/tools/spray-tool.cpp | 47 +++++++++++++++++++++++++++---------------- src/ui/tools/spray-tool.h | 3 ++- src/widgets/spray-toolbar.cpp | 41 ++++++++++++++++++++++++++++--------- src/widgets/toolbox.cpp | 3 ++- 4 files changed, 65 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 17b82fe1d..99cb78936 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -178,7 +178,8 @@ SprayTool::SprayTool() , pickinversevalue(false) , pickfill(false) , pickstroke(false) - , visible(false) + , overtransparent(true) + , overnotransparent(true) , offset(0) { } @@ -259,7 +260,8 @@ void SprayTool::setup() { sp_event_context_read(this, "pickinversevalue"); sp_event_context_read(this, "pickfill"); sp_event_context_read(this, "pickstroke"); - sp_event_context_read(this, "visible"); + sp_event_context_read(this, "overnotransparent"); + sp_event_context_read(this, "overtransparent"); sp_event_context_read(this, "nooverlap"); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -312,8 +314,10 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) { this->pickfill = val.getBool(); } else if (path == "pickstroke") { this->pickstroke = val.getBool(); - } else if (path == "visible") { - this->visible = val.getBool(); + } else if (path == "overnotransparent") { + this->overnotransparent = val.getBool(); + } else if (path == "overtransparent") { + this->overtransparent = val.getBool(); } else if (path == "nooverlap") { this->nooverlap = val.getBool(); } @@ -440,7 +444,8 @@ static bool fit_item(SPDesktop *desktop, bool pickinversevalue, bool pickfill, bool pickstroke, - bool visible, + bool overnotransparent, + bool overtransparent, bool nooverlap, double offset, SPCSSAttr *css, @@ -485,7 +490,10 @@ static bool fit_item(SPDesktop *desktop, ink_cairo_surface_average_color(s, R, G, B, A); cairo_surface_destroy(s); guint32 rgba = SP_RGBA32_F_COMPOSE(R, G, B, A); - if(nooverlap && visible && (A==0 || A < 1e-6)){ + if(nooverlap && !overtransparent && (A==0 || A < 1e-6)){ + return false; + } + if(nooverlap && !overnotransparent && A>0){ return false; } size = std::min(width_transformed,height_transformed); @@ -525,14 +533,14 @@ static bool fit_item(SPDesktop *desktop, std::abs(bbox_top - bbox_top_main) > std::abs(offset_min))){ return false; } - } else if(picker || visible){ + } else if(picker || !overtransparent || !overnotransparent){ item_down->setHidden(true); item_down->updateRepr(); } } } } - if(picker || visible){ + if(picker || !overtransparent || !overnotransparent){ if(!nooverlap){ doc->ensureUpToDate(); } @@ -555,7 +563,10 @@ static bool fit_item(SPDesktop *desktop, g = 1; b = 1; } - if(visible && (a == 0 || a < 1e-6)){ + if(!overtransparent && (a == 0 || a < 1e-6)){ + return false; + } + if(!overnotransparent && a >0){ return false; } @@ -649,7 +660,8 @@ static bool fit_item(SPDesktop *desktop, pickinversevalue, pickfill, pickstroke, - visible, + overnotransparent, + overtransparent, nooverlap, offset, css, @@ -699,7 +711,7 @@ static bool fit_item(SPDesktop *desktop, sp_repr_css_set_property(css, "stroke", color_string); } } - if(!nooverlap && (picker || visible)){ + if(!nooverlap && (picker || !overtransparent || !overnotransparent)){ for (std::vector::const_iterator k=items_down.begin(); k!=items_down.end(); k++) { SPItem *item_hidden = *k; item_hidden->setHidden(false); @@ -732,7 +744,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, bool pickinversevalue, bool pickfill, bool pickstroke, - bool visible, + bool overnotransparent, + bool overtransparent, double offset, bool usepressurescale, double pressure) @@ -773,8 +786,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(nooverlap || picker || visible){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversevalue, pickfill, pickstroke, visible, nooverlap, offset, css, false)){ + if(nooverlap || picker || !overtransparent || !overnotransparent){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversevalue, pickfill, pickstroke, overnotransparent, overtransparent, nooverlap, offset, css, false)){ return false; } } @@ -880,8 +893,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(nooverlap || picker || visible){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversevalue, pickfill, pickstroke, visible, nooverlap, offset, css, false)){ + if(nooverlap || picker || !overtransparent || !overnotransparent){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversevalue, pickfill, pickstroke, overnotransparent, overtransparent, nooverlap, offset, css, false)){ return false; } } @@ -959,7 +972,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for(std::vector::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, tc->nooverlap, tc->picker, tc->pickinversevalue, tc->pickfill, tc->pickstroke, tc->visible, tc->offset, tc->usepressurescale, get_pressure(tc))) { + 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->nooverlap, tc->picker, tc->pickinversevalue, tc->pickfill, tc->pickstroke, tc->overnotransparent, tc->overtransparent, tc->offset, tc->usepressurescale, get_pressure(tc))) { did = true; } } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index ca0c20375..ba4e75f70 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -94,7 +94,8 @@ public: bool pickinversevalue; bool pickfill; bool pickstroke; - bool visible; + bool overtransparent; + bool overnotransparent; double offset; sigc::connection style_set_connection; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 5e0d81964..fe69b5050 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -186,13 +186,21 @@ static void sp_toggle_pressure_scale( GtkToggleAction* act, gpointer data) sp_stb_sensitivize( tbl ); } -static void sp_toggle_visible( GtkToggleAction* act, gpointer data) +static void sp_toggle_over_no_transparent( GtkToggleAction* act, gpointer data) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/visible", active); + prefs->setBool("/tools/spray/overnotransparent", active); } +static void sp_toggle_over_transparent( GtkToggleAction* act, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/overtransparent", active); +} + + static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -472,17 +480,30 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_stroke), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } - - /* Visible */ + + /* Over Transparent */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayOverTransparentAction", + _("Apply over transparent areas"), + _("Apply over transparent areas"), + INKSCAPE_ICON("object-hidden"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overtransparent", true) ); + g_object_set_data( holder, "overtransparent", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_over_transparent), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Over No Transparent */ { - InkToggleAction* act = ink_toggle_action_new( "SprayOverVisibleAction", - _("Apply only over non transparent areas"), - _("Apply only over non transparent areas"), + InkToggleAction* act = ink_toggle_action_new( "SprayOverNoTransparentAction", + _("Apply over no transparent areas"), + _("Apply over no transparent areas"), INKSCAPE_ICON("object-visible"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/visible", false) ); - g_object_set_data( holder, "visible", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_visible), holder) ; + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overnotransparent", true) ); + g_object_set_data( holder, "overnotransparent", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_over_no_transparent), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index cdb9e0d20..b9051dd50 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -321,7 +321,8 @@ static gchar const * ui_descr = " " " " " " - " " + " " + " " " " " " " " -- cgit v1.2.3 From de44c6059f00e773cef5c22534e12a1adc50b3a4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 11 Nov 2015 01:02:03 +0100 Subject: Improvements to the over visible/invisible to minimize the colisions, sprayed items fit on background whith overlap visible or invisible areas Add option in picker mode to compute the center/or average area of sprayed item Now reverse work without adbanced trace dialog inverting the color. By this all buttons have a utility in advanced and in normal mode (bzr r14454) --- src/ui/tools/spray-tool.cpp | 115 ++++++++++++++++++++++++++++++++++-------- src/ui/tools/spray-tool.h | 1 + src/widgets/spray-toolbar.cpp | 28 ++++++++-- src/widgets/toolbox.cpp | 7 +-- 4 files changed, 125 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 99cb78936..1ec7815c5 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -175,6 +175,7 @@ SprayTool::SprayTool() , dilate_area(NULL) , nooverlap(false) , picker(false) + , pickcenter(true) , pickinversevalue(false) , pickfill(false) , pickstroke(false) @@ -257,6 +258,7 @@ void SprayTool::setup() { sp_event_context_read(this, "Scale"); sp_event_context_read(this, "offset"); sp_event_context_read(this, "picker"); + sp_event_context_read(this, "pickcenter"); sp_event_context_read(this, "pickinversevalue"); sp_event_context_read(this, "pickfill"); sp_event_context_read(this, "pickstroke"); @@ -308,6 +310,8 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) { this->offset = CLAMP(val.getDouble(), -1000.0, 1000.0); } else if (path == "picker") { this->picker = val.getBool(); + } else if (path == "pickcenter") { + this->pickcenter = val.getBool(); } else if (path == "pickinversevalue") { this->pickinversevalue = val.getBool(); } else if (path == "pickfill") { @@ -432,6 +436,33 @@ double randomize01(double val, double rand) 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); + return SP_RGBA32_F_COMPOSE(R, G, B, A); +} + +bool isTrans(Geom::Point N){ + gint32 rgba = getPickerData(Geom::IntRect::from_xywh(floor(N[Geom::X]), floor(N[Geom::Y]), 1, 1)); + return SP_RGBA32_A_F(rgba)==0 || SP_RGBA32_A_F(rgba) < 1e-6; +} + +bool overTrans(Geom::Point A, Geom::Point B, Geom::Point C, Geom::Point D){ + return isTrans(A) || isTrans(B) || isTrans(C) || isTrans(D); +} + +static void showHidden(std::vector items_down){ + for (std::vector::const_iterator k=items_down.begin(); k!=items_down.end(); k++) { + SPItem *item_hidden = *k; + item_hidden->setHidden(false); + item_hidden->updateRepr(); + } +} + static bool fit_item(SPDesktop *desktop, SPItem *item, Geom::OptRect bbox, @@ -441,6 +472,7 @@ static bool fit_item(SPDesktop *desktop, double &_scale, double scale, bool picker, + bool pickcenter, bool pickinversevalue, bool pickfill, bool pickstroke, @@ -479,21 +511,32 @@ static bool fit_item(SPDesktop *desktop, 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::Rect rect_sprayed(mid_point, mid_point); + rect_sprayed.expandBy(width_transformed/2.0, height_transformed/2.0); Geom::IntRect area = Geom::IntRect::from_xywh(floor(mid_point[Geom::X]), floor(mid_point[Geom::Y]), 1, 1); - double R = 0, G = 0, B = 0, A = 0; - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); - 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); - guint32 rgba = SP_RGBA32_F_COMPOSE(R, G, B, A); - if(nooverlap && !overtransparent && (A==0 || A < 1e-6)){ + if (!rect_sprayed.hasZeroArea() && (!pickcenter || (overtransparent && !overnotransparent))) { + area = rect_sprayed.roundOutwards(); + } + guint32 rgba = getPickerData(area); + if(!overtransparent && overnotransparent){ + Geom::Point lt = desktop->d2w(Geom::Point(floor(bbox_left_main),floor(bbox_top_main))); + Geom::Point rt = desktop->d2w(Geom::Point(floor(bbox_right_main),floor(bbox_top_main))); + Geom::Point rb = desktop->d2w(Geom::Point(floor(bbox_right_main),floor(bbox_bottom_main))); + Geom::Point lb = desktop->d2w(Geom::Point(floor(bbox_left_main),floor(bbox_bottom_main))); + if(overTrans(lt, rt, rb, lb)){ + return false; + } + } + if(nooverlap && !overtransparent && (SP_RGBA32_A_F(rgba)==0 || SP_RGBA32_A_F(rgba) < 1e-6)){ return false; } - if(nooverlap && !overnotransparent && A>0){ + if(nooverlap && !overnotransparent && SP_RGBA32_A_F(rgba)>0){ return false; } size = std::min(width_transformed,height_transformed); @@ -533,16 +576,29 @@ static bool fit_item(SPDesktop *desktop, std::abs(bbox_top - bbox_top_main) > std::abs(offset_min))){ return false; } - } else if(picker || !overtransparent || !overnotransparent){ + } else if(picker || overtransparent || overnotransparent){ item_down->setHidden(true); item_down->updateRepr(); } } } } - if(picker || !overtransparent || !overnotransparent){ + if(picker || overtransparent || overnotransparent){ if(!nooverlap){ doc->ensureUpToDate(); + rgba = getPickerData(area); + } + if(!overtransparent && overnotransparent){ + Geom::Point lt = desktop->d2w(Geom::Point(floor(bbox_left_main),floor(bbox_top_main))); + Geom::Point rt = desktop->d2w(Geom::Point(floor(bbox_right_main),floor(bbox_top_main))); + Geom::Point rb = desktop->d2w(Geom::Point(floor(bbox_right_main),floor(bbox_bottom_main))); + Geom::Point lb = desktop->d2w(Geom::Point(floor(bbox_left_main),floor(bbox_bottom_main))); + if(overTrans(lt, rt, rb, lb)){ + if(!nooverlap && (picker || overtransparent || overnotransparent)){ + showHidden(items_down); + } + return false; + } } int pick = prefs->getInt("/dialogs/clonetiler/pick"); bool pick_to_presence = prefs->getBool("/dialogs/clonetiler/pick_to_presence", false); @@ -564,9 +620,15 @@ static bool fit_item(SPDesktop *desktop, b = 1; } if(!overtransparent && (a == 0 || a < 1e-6)){ + if(!nooverlap && (picker || overtransparent || overnotransparent)){ + showHidden(items_down); + } return false; } - if(!overnotransparent && a >0){ + if(!overnotransparent && a > 0){ + if(!nooverlap && (picker || overtransparent || overnotransparent)){ + showHidden(items_down); + } return false; } @@ -646,6 +708,9 @@ static bool fit_item(SPDesktop *desktop, _scale = val; } if(_scale == 0.0) { + if(!nooverlap && (picker || overtransparent || overnotransparent)){ + showHidden(items_down); + } return false; } if(!fit_item(desktop, @@ -657,6 +722,7 @@ static bool fit_item(SPDesktop *desktop, _scale, scale, picker, + pickcenter, pickinversevalue, pickfill, pickstroke, @@ -666,6 +732,9 @@ static bool fit_item(SPDesktop *desktop, offset, css, true)){ + if(!nooverlap && (picker || overtransparent || overnotransparent)){ + showHidden(items_down); + } return false; } } @@ -699,10 +768,19 @@ static bool fit_item(SPDesktop *desktop, } } if (opacity < 1e-6) { // invisibly transparent, skip + if(!nooverlap && (picker || overtransparent || overnotransparent)){ + showHidden(items_down); + } return false; } } if(!trace){ + if (pickinversevalue) { + r = 1 - r; + g = 1 - g; + b = 1 - b; + } + rgba = SP_RGBA32_F_COMPOSE(r, g, b, a); sp_svg_write_color(color_string, sizeof(color_string), rgba); if(pickfill){ sp_repr_css_set_property(css, "fill", color_string); @@ -711,12 +789,8 @@ static bool fit_item(SPDesktop *desktop, sp_repr_css_set_property(css, "stroke", color_string); } } - if(!nooverlap && (picker || !overtransparent || !overnotransparent)){ - for (std::vector::const_iterator k=items_down.begin(); k!=items_down.end(); k++) { - SPItem *item_hidden = *k; - item_hidden->setHidden(false); - item_hidden->updateRepr(); - } + if(!nooverlap && (picker || overtransparent || overnotransparent)){ + showHidden(items_down); } } return true; @@ -741,6 +815,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, gint _distrib, bool nooverlap, bool picker, + bool pickcenter, bool pickinversevalue, bool pickfill, bool pickstroke, @@ -787,7 +862,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(nooverlap || picker || !overtransparent || !overnotransparent){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversevalue, pickfill, pickstroke, overnotransparent, overtransparent, nooverlap, offset, css, false)){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickcenter, pickinversevalue, pickfill, pickstroke, overnotransparent, overtransparent, nooverlap, offset, css, false)){ return false; } } @@ -894,7 +969,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(nooverlap || picker || !overtransparent || !overnotransparent){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickinversevalue, pickfill, pickstroke, overnotransparent, overtransparent, nooverlap, offset, css, false)){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickcenter, pickinversevalue, pickfill, pickstroke, overnotransparent, overtransparent, nooverlap, offset, css, false)){ return false; } } @@ -972,7 +1047,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for(std::vector::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, tc->nooverlap, tc->picker, tc->pickinversevalue, tc->pickfill, tc->pickstroke, tc->overnotransparent, tc->overtransparent, tc->offset, tc->usepressurescale, get_pressure(tc))) { + 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->nooverlap, tc->picker, tc->pickcenter, tc->pickinversevalue, tc->pickfill, tc->pickstroke, tc->overnotransparent, tc->overtransparent, tc->offset, tc->usepressurescale, get_pressure(tc))) { did = true; } } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index ba4e75f70..066ced00e 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -91,6 +91,7 @@ public: SPCanvasItem *dilate_area; bool nooverlap; bool picker; + bool pickcenter; bool pickinversevalue; bool pickfill; bool pickstroke; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index fe69b5050..a9a038c0e 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -72,6 +72,7 @@ static void sp_stb_sensitivize( GObject *tbl ) GtkAction *pickfill = GTK_ACTION( g_object_get_data(tbl, "pickfill") ); GtkAction *pickstroke = GTK_ACTION( g_object_get_data(tbl, "pickstroke") ); GtkAction *pickinversevalue = GTK_ACTION( g_object_get_data(tbl, "pickinversevalue") ); + GtkAction *pickcenter = GTK_ACTION( g_object_get_data(tbl, "pickcenter") ); gtk_adjustment_set_value( adj_offset, 100.0 ); if (gtk_toggle_action_get_active(nooverlap)) { gtk_action_set_sensitive( offset, TRUE ); @@ -88,10 +89,12 @@ static void sp_stb_sensitivize( GObject *tbl ) gtk_action_set_sensitive( pickfill, TRUE ); gtk_action_set_sensitive( pickstroke, TRUE ); gtk_action_set_sensitive( pickinversevalue, TRUE ); + gtk_action_set_sensitive( pickcenter, TRUE ); } else { gtk_action_set_sensitive( pickfill, FALSE ); gtk_action_set_sensitive( pickstroke, FALSE ); gtk_action_set_sensitive( pickinversevalue, FALSE ); + gtk_action_set_sensitive( pickcenter, FALSE ); } } @@ -218,6 +221,13 @@ static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) sp_stb_sensitivize(tbl); } +static void sp_toggle_pick_center( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/pickcenter", active); +} + static void sp_toggle_pick_fill( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -428,7 +438,6 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } - /* Picker */ { InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction", @@ -441,12 +450,25 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_picker), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } + + /* Pick from center */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPickCenterAction", + _("Pick from center instead average area."), + _("Pick from center instead average area."), + INKSCAPE_ICON("snap-bounding-box-center"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickcenter", true) ); + g_object_set_data( holder, "pickcenter", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_center), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } /* Inverse Value Size */ { InkToggleAction* act = ink_toggle_action_new( "SprayOverPickInverseValueAction", - _("Inversed pick value retaining color"), - _("Inversed pick value retaining color"), + _("Inversed pick value, retaining color in advanced trace mode"), + _("Inversed pick value, retaining color in advanced trace mode"), INKSCAPE_ICON("object-tweak-shrink"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickinversevalue", false) ); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index b9051dd50..0aaba39f9 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -327,10 +327,11 @@ static gchar const * ui_descr = " " " " " " - " " " " " " - + " " + " " + " " " " @@ -369,7 +370,7 @@ static gchar const * ui_descr = " " " " " " - " " + " " " " " " -- cgit v1.2.3 From 75f6b25acdf6f51f5772e55d2150076b539b6e67 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 11 Nov 2015 09:34:01 +0100 Subject: Add option to spray tool to no overlap between colors (bzr r14455) --- src/ui/tools/spray-tool.cpp | 59 +++++++++++++++++++++++++------------------ src/ui/tools/spray-tool.h | 1 + src/widgets/spray-toolbar.cpp | 26 ++++++++++++++++--- src/widgets/toolbox.cpp | 8 +++--- 4 files changed, 62 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 1ec7815c5..1c9656a38 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -179,6 +179,7 @@ SprayTool::SprayTool() , pickinversevalue(false) , pickfill(false) , pickstroke(false) + , picknooverlap(false) , overtransparent(true) , overnotransparent(true) , offset(0) @@ -262,6 +263,7 @@ void SprayTool::setup() { sp_event_context_read(this, "pickinversevalue"); sp_event_context_read(this, "pickfill"); sp_event_context_read(this, "pickstroke"); + sp_event_context_read(this, "picknooverlap"); sp_event_context_read(this, "overnotransparent"); sp_event_context_read(this, "overtransparent"); sp_event_context_read(this, "nooverlap"); @@ -318,6 +320,8 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) { this->pickfill = val.getBool(); } else if (path == "pickstroke") { this->pickstroke = val.getBool(); + } else if (path == "picknooverlap") { + this->picknooverlap = val.getBool(); } else if (path == "overnotransparent") { this->overnotransparent = val.getBool(); } else if (path == "overtransparent") { @@ -451,12 +455,18 @@ bool isTrans(Geom::Point N){ return SP_RGBA32_A_F(rgba)==0 || SP_RGBA32_A_F(rgba) < 1e-6; } -bool overTrans(Geom::Point A, Geom::Point B, Geom::Point C, Geom::Point D){ - return isTrans(A) || isTrans(B) || isTrans(C) || isTrans(D); +bool overTrans(std::vector points){ + for (std::vector::const_iterator k=points.begin(); k!=points.end(); ++k) { + Geom::Point point = *k; + if(isTrans(point)){ + return true; + } + } + return false; } static void showHidden(std::vector items_down){ - for (std::vector::const_iterator k=items_down.begin(); k!=items_down.end(); k++) { + for (std::vector::const_iterator k=items_down.begin(); k!=items_down.end(); ++k) { SPItem *item_hidden = *k; item_hidden->setHidden(false); item_hidden->updateRepr(); @@ -476,6 +486,7 @@ static bool fit_item(SPDesktop *desktop, bool pickinversevalue, bool pickfill, bool pickstroke, + bool picknooverlap, bool overnotransparent, bool overtransparent, bool nooverlap, @@ -511,28 +522,24 @@ static bool fit_item(SPDesktop *desktop, 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::Rect rect_sprayed(mid_point, mid_point); rect_sprayed.expandBy(width_transformed/2.0, height_transformed/2.0); Geom::IntRect area = Geom::IntRect::from_xywh(floor(mid_point[Geom::X]), floor(mid_point[Geom::Y]), 1, 1); - if (!rect_sprayed.hasZeroArea() && (!pickcenter || (overtransparent && !overnotransparent))) { - area = rect_sprayed.roundOutwards(); - } - guint32 rgba = getPickerData(area); - if(!overtransparent && overnotransparent){ - Geom::Point lt = desktop->d2w(Geom::Point(floor(bbox_left_main),floor(bbox_top_main))); - Geom::Point rt = desktop->d2w(Geom::Point(floor(bbox_right_main),floor(bbox_top_main))); - Geom::Point rb = desktop->d2w(Geom::Point(floor(bbox_right_main),floor(bbox_bottom_main))); - Geom::Point lb = desktop->d2w(Geom::Point(floor(bbox_left_main),floor(bbox_bottom_main))); - if(overTrans(lt, rt, rb, lb)){ + guint32 rgba; + if(picknooverlap && !rect_sprayed.hasZeroArea()){ + if(getPickerData(area) != getPickerData(rect_sprayed.roundOutwards())){ return false; } } + if (!rect_sprayed.hasZeroArea() && !pickcenter) { + rgba = getPickerData(rect_sprayed.roundOutwards()); + } else { + rgba = getPickerData(area); + } if(nooverlap && !overtransparent && (SP_RGBA32_A_F(rgba)==0 || SP_RGBA32_A_F(rgba) < 1e-6)){ return false; } @@ -586,14 +593,14 @@ static bool fit_item(SPDesktop *desktop, if(picker || overtransparent || overnotransparent){ if(!nooverlap){ doc->ensureUpToDate(); - rgba = getPickerData(area); + if (!rect_sprayed.hasZeroArea() && !pickcenter) { + rgba = getPickerData(rect_sprayed.roundOutwards()); + } else { + rgba = getPickerData(area); + } } - if(!overtransparent && overnotransparent){ - Geom::Point lt = desktop->d2w(Geom::Point(floor(bbox_left_main),floor(bbox_top_main))); - Geom::Point rt = desktop->d2w(Geom::Point(floor(bbox_right_main),floor(bbox_top_main))); - Geom::Point rb = desktop->d2w(Geom::Point(floor(bbox_right_main),floor(bbox_bottom_main))); - Geom::Point lb = desktop->d2w(Geom::Point(floor(bbox_left_main),floor(bbox_bottom_main))); - if(overTrans(lt, rt, rb, lb)){ + if(picknooverlap && !rect_sprayed.hasZeroArea()){ + if(getPickerData(area) != getPickerData(rect_sprayed.roundOutwards())){ if(!nooverlap && (picker || overtransparent || overnotransparent)){ showHidden(items_down); } @@ -726,6 +733,7 @@ static bool fit_item(SPDesktop *desktop, pickinversevalue, pickfill, pickstroke, + picknooverlap, overnotransparent, overtransparent, nooverlap, @@ -819,6 +827,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, bool pickinversevalue, bool pickfill, bool pickstroke, + bool picknooverlap, bool overnotransparent, bool overtransparent, double offset, @@ -862,7 +871,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(nooverlap || picker || !overtransparent || !overnotransparent){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickcenter, pickinversevalue, pickfill, pickstroke, overnotransparent, overtransparent, nooverlap, offset, css, false)){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickcenter, pickinversevalue, pickfill, pickstroke, picknooverlap, overnotransparent, overtransparent, nooverlap, offset, css, false)){ return false; } } @@ -969,7 +978,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(nooverlap || picker || !overtransparent || !overnotransparent){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickcenter, pickinversevalue, pickfill, pickstroke, overnotransparent, overtransparent, nooverlap, offset, css, false)){ + if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickcenter, pickinversevalue, pickfill, pickstroke, picknooverlap, overnotransparent, overtransparent, nooverlap, offset, css, false)){ return false; } } @@ -1047,7 +1056,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for(std::vector::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, tc->nooverlap, tc->picker, tc->pickcenter, tc->pickinversevalue, tc->pickfill, tc->pickstroke, tc->overnotransparent, tc->overtransparent, tc->offset, tc->usepressurescale, get_pressure(tc))) { + 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->nooverlap, tc->picker, tc->pickcenter, tc->pickinversevalue, tc->pickfill, tc->pickstroke, tc->picknooverlap, tc->overnotransparent, tc->overtransparent, tc->offset, tc->usepressurescale, get_pressure(tc))) { did = true; } } diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index 066ced00e..377893f0d 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -95,6 +95,7 @@ public: bool pickinversevalue; bool pickfill; bool pickstroke; + bool picknooverlap; bool overtransparent; bool overnotransparent; double offset; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index a9a038c0e..34f728ce8 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -235,6 +235,13 @@ static void sp_toggle_pick_fill( GtkToggleAction* act, gpointer data ) prefs->setBool("/tools/spray/pickfill", active); } +static void sp_toggle_pick_no_overlap( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/picknooverlap", active); +} + static void sp_toggle_pick_inverse_value( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -466,7 +473,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Inverse Value Size */ { - InkToggleAction* act = ink_toggle_action_new( "SprayOverPickInverseValueAction", + InkToggleAction* act = ink_toggle_action_new( "SprayPickInverseValueAction", _("Inversed pick value, retaining color in advanced trace mode"), _("Inversed pick value, retaining color in advanced trace mode"), INKSCAPE_ICON("object-tweak-shrink"), @@ -479,7 +486,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Pick Fill */ { - InkToggleAction* act = ink_toggle_action_new( "SprayOverPickFillAction", + InkToggleAction* act = ink_toggle_action_new( "SprayPickFillAction", _("Apply picked color to fill"), _("Apply picked color to fill"), INKSCAPE_ICON("paint-solid"), @@ -492,7 +499,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Pick Stroke */ { - InkToggleAction* act = ink_toggle_action_new( "SprayOverPickStrokeAction", + InkToggleAction* act = ink_toggle_action_new( "SprayPickStrokeAction", _("Apply picked color to stroke"), _("Apply picked color to stroke"), INKSCAPE_ICON("no-marker"), @@ -503,6 +510,19 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } + /* Pick No Overlap */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPickNoOverlapAction", + _("No overlap between colors"), + _("No overlap between colors"), + INKSCAPE_ICON("symbol-bigger"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picknooverlap", false) ); + g_object_set_data( holder, "picknooverlap", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_no_overlap), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + /* Over Transparent */ { InkToggleAction* act = ink_toggle_action_new( "SprayOverTransparentAction", diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 0aaba39f9..3e79e038a 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -323,15 +323,15 @@ static gchar const * ui_descr = " " " " " " + " " " " " " " " " " - " " - " " - " " + " " + " " + " " " " - " " " " -- cgit v1.2.3 From e015bb069e1722492e5d677b92ce4a5d089cb2fa Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 11 Nov 2015 09:36:54 +0100 Subject: Remove unused functions (bzr r14456) --- src/ui/tools/spray-tool.cpp | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 1c9656a38..9fde142e5 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -450,21 +450,6 @@ guint32 getPickerData(Geom::IntRect area){ return SP_RGBA32_F_COMPOSE(R, G, B, A); } -bool isTrans(Geom::Point N){ - gint32 rgba = getPickerData(Geom::IntRect::from_xywh(floor(N[Geom::X]), floor(N[Geom::Y]), 1, 1)); - return SP_RGBA32_A_F(rgba)==0 || SP_RGBA32_A_F(rgba) < 1e-6; -} - -bool overTrans(std::vector points){ - for (std::vector::const_iterator k=points.begin(); k!=points.end(); ++k) { - Geom::Point point = *k; - if(isTrans(point)){ - return true; - } - } - return false; -} - static void showHidden(std::vector items_down){ for (std::vector::const_iterator k=items_down.begin(); k!=items_down.end(); ++k) { SPItem *item_hidden = *k; -- cgit v1.2.3 From b5c716ade5ee3e23f9c56c6b7a0227acf2118f36 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 11 Nov 2015 15:35:50 +0100 Subject: Improve offseting calculation Improve no picoverlap feature (bzr r14457) --- src/ui/tools/spray-tool.cpp | 88 +++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 9fde142e5..0f8404b8e 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -447,6 +447,12 @@ guint32 getPickerData(Geom::IntRect area){ 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); } @@ -457,7 +463,7 @@ static void showHidden(std::vector items_down){ item_hidden->updateRepr(); } } - +//todo: maybe move same parameter to preferences static bool fit_item(SPDesktop *desktop, SPItem *item, Geom::OptRect bbox, @@ -482,18 +488,21 @@ static bool fit_item(SPDesktop *desktop, SPDocument *doc = item->document; double width = bbox->width(); double height = bbox->height(); - double size = std::min(width,height); - double offset_min = (offset * size)/100.0 - (size); - if(offset_min < 0 ){ - offset_min = 0; + 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; } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool pick_to_size = prefs->getBool("/dialogs/clonetiler/pick_to_size"); - bool trace = prefs->getBool("/dialogs/clonetiler/dotrace"); - if(picker && pick_to_size && !trace_scale && trace){ + bool do_trace = prefs->getBool("/dialogs/clonetiler/dotrace"); + if(picker && pick_to_size && !trace_scale && do_trace){ _scale = 0.1; } - Geom::OptRect bbox_procesed = Geom::Rect(Geom::Point(bbox->left() - offset_min, bbox->top() - offset_min),Geom::Point(bbox->right() + offset_min, bbox->bottom() + offset_min)); + 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::Point(bbox_procesed->right(), bbox_procesed->top())); @@ -507,35 +516,39 @@ static bool fit_item(SPDesktop *desktop, 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::Rect rect_sprayed(mid_point, mid_point); - rect_sprayed.expandBy(width_transformed/2.0, height_transformed/2.0); Geom::IntRect area = Geom::IntRect::from_xywh(floor(mid_point[Geom::X]), floor(mid_point[Geom::Y]), 1, 1); - guint32 rgba; - if(picknooverlap && !rect_sprayed.hasZeroArea()){ - if(getPickerData(area) != getPickerData(rect_sprayed.roundOutwards())){ + 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(picknooverlap){ + if(rgba != rgba2){ return false; } } - if (!rect_sprayed.hasZeroArea() && !pickcenter) { - rgba = getPickerData(rect_sprayed.roundOutwards()); - } else { - rgba = getPickerData(area); + if(!pickcenter){ + rgba = rgba2; } - if(nooverlap && !overtransparent && (SP_RGBA32_A_F(rgba)==0 || SP_RGBA32_A_F(rgba) < 1e-6)){ + if(!overtransparent && (SP_RGBA32_A_F(rgba) == 0 || SP_RGBA32_A_F(rgba) < 1e-6)){ return false; } - if(nooverlap && !overnotransparent && SP_RGBA32_A_F(rgba)>0){ + if(!overnotransparent && SP_RGBA32_A_F(rgba) > 0){ return false; } - size = std::min(width_transformed,height_transformed); if(offset < 100 ){ - offset_min = ((99.0 - offset) * size)/100.0 - size; + offset_width = ((99.0 - offset) * width_transformed)/100.0 - width_transformed; + offset_height = ((99.0 - offset) * height_transformed)/100.0 - height_transformed; } else { - offset_min = 0; + offset_width = 0; + offset_height = 0; } std::vector items_down = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *bbox_procesed); Inkscape::Selection *selection = desktop->getSelection(); @@ -564,8 +577,11 @@ static bool fit_item(SPDesktop *desktop, strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 )) { if(nooverlap){ - if(!(offset_min < 0 && std::abs(bbox_left - bbox_left_main) > std::abs(offset_min) && - std::abs(bbox_top - bbox_top_main) > std::abs(offset_min))){ + 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(!nooverlap && (picker || overtransparent || overnotransparent)){ + showHidden(items_down); + } return false; } } else if(picker || overtransparent || overnotransparent){ @@ -578,20 +594,22 @@ static bool fit_item(SPDesktop *desktop, if(picker || overtransparent || overnotransparent){ if(!nooverlap){ doc->ensureUpToDate(); - if (!rect_sprayed.hasZeroArea() && !pickcenter) { - rgba = getPickerData(rect_sprayed.roundOutwards()); - } else { - rgba = getPickerData(area); + rgba = getPickerData(area); + if (!rect_sprayed.hasZeroArea()) { + rgba2 = getPickerData(rect_sprayed.roundOutwards()); } } - if(picknooverlap && !rect_sprayed.hasZeroArea()){ - if(getPickerData(area) != getPickerData(rect_sprayed.roundOutwards())){ + if(picknooverlap){ + if(rgba != rgba2){ if(!nooverlap && (picker || overtransparent || overnotransparent)){ showHidden(items_down); } return false; } } + if(!pickcenter){ + rgba = rgba2; + } int pick = prefs->getInt("/dialogs/clonetiler/pick"); bool pick_to_presence = prefs->getBool("/dialogs/clonetiler/pick_to_presence", false); bool pick_to_color = prefs->getBool("/dialogs/clonetiler/pick_to_color"); @@ -605,12 +623,6 @@ static bool fit_item(SPDesktop *desktop, float g = SP_RGBA32_G_F(rgba); float b = SP_RGBA32_B_F(rgba); float a = SP_RGBA32_A_F(rgba); - //this can fix the bug #1511998 if confirmed - if( a == 0 || a < 1e-6){ - r = 1; - g = 1; - b = 1; - } if(!overtransparent && (a == 0 || a < 1e-6)){ if(!nooverlap && (picker || overtransparent || overnotransparent)){ showHidden(items_down); @@ -624,7 +636,7 @@ static bool fit_item(SPDesktop *desktop, return false; } - if(picker && trace){ + if(picker && do_trace){ float hsl[3]; sp_color_rgb_to_hsl_floatv (hsl, r, g, b); @@ -767,7 +779,7 @@ static bool fit_item(SPDesktop *desktop, return false; } } - if(!trace){ + if(!do_trace){ if (pickinversevalue) { r = 1 - r; g = 1 - g; -- cgit v1.2.3 From 5be1dd71bf1bf0bb5559c3a5cac3cafba44bd960 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 11 Nov 2015 19:28:19 +0100 Subject: Refactor of code, minor bugs fixed. (bzr r14458) --- src/ui/tools/spray-tool.cpp | 385 +++++++++++++++++++++++++++++------------- src/ui/tools/spray-tool.h | 26 ++- src/widgets/spray-toolbar.cpp | 86 +++++----- 3 files changed, 324 insertions(+), 173 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 0f8404b8e..10a10f49f 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -173,16 +173,25 @@ SprayTool::SprayTool() , is_dilating(false) , has_dilated(false) , dilate_area(NULL) - , nooverlap(false) + , no_overlap(false) , picker(false) - , pickcenter(true) - , pickinversevalue(false) - , pickfill(false) - , pickstroke(false) - , picknooverlap(false) - , overtransparent(true) - , overnotransparent(true) + , 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) { } @@ -259,14 +268,14 @@ void SprayTool::setup() { sp_event_context_read(this, "Scale"); sp_event_context_read(this, "offset"); sp_event_context_read(this, "picker"); - sp_event_context_read(this, "pickcenter"); - sp_event_context_read(this, "pickinversevalue"); - sp_event_context_read(this, "pickfill"); - sp_event_context_read(this, "pickstroke"); - sp_event_context_read(this, "picknooverlap"); - sp_event_context_read(this, "overnotransparent"); - sp_event_context_read(this, "overtransparent"); - sp_event_context_read(this, "nooverlap"); + 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"); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/tools/spray/selcue")) { @@ -277,6 +286,19 @@ void SprayTool::setup() { } } +void SprayTool::setCloneTilerPrefs() { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + 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) { Glib::ustring path = val.getEntryName(); @@ -309,25 +331,25 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) { } else if (path == "ratio") { this->ratio = CLAMP(val.getDouble(), 0.0, 0.9); } else if (path == "offset") { - this->offset = CLAMP(val.getDouble(), -1000.0, 1000.0); + 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(); - } else if (path == "pickcenter") { - this->pickcenter = val.getBool(); - } else if (path == "pickinversevalue") { - this->pickinversevalue = val.getBool(); - } else if (path == "pickfill") { - this->pickfill = val.getBool(); - } else if (path == "pickstroke") { - this->pickstroke = val.getBool(); - } else if (path == "picknooverlap") { - this->picknooverlap = val.getBool(); - } else if (path == "overnotransparent") { - this->overnotransparent = val.getBool(); - } else if (path == "overtransparent") { - this->overtransparent = val.getBool(); - } else if (path == "nooverlap") { - this->nooverlap = val.getBool(); + this->picker = val.getBool(false); } } @@ -473,17 +495,26 @@ static bool fit_item(SPDesktop *desktop, double &_scale, double scale, bool picker, - bool pickcenter, - bool pickinversevalue, - bool pickfill, - bool pickstroke, - bool picknooverlap, - bool overnotransparent, - bool overtransparent, - bool nooverlap, + 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) + 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(); @@ -496,9 +527,6 @@ static bool fit_item(SPDesktop *desktop, if(offset_height < 0 ){ offset_height = 0; } - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool pick_to_size = prefs->getBool("/dialogs/clonetiler/pick_to_size"); - bool do_trace = prefs->getBool("/dialogs/clonetiler/dotrace"); if(picker && pick_to_size && !trace_scale && do_trace){ _scale = 0.1; } @@ -529,18 +557,18 @@ static bool fit_item(SPDesktop *desktop, if (!rect_sprayed.hasZeroArea()) { rgba2 = getPickerData(rect_sprayed.roundOutwards()); } - if(picknooverlap){ + if(pick_no_overlap){ if(rgba != rgba2){ return false; } } - if(!pickcenter){ + if(!pick_center){ rgba = rgba2; } - if(!overtransparent && (SP_RGBA32_A_F(rgba) == 0 || SP_RGBA32_A_F(rgba) < 1e-6)){ + if(!over_transparent && (SP_RGBA32_A_F(rgba) == 0 || SP_RGBA32_A_F(rgba) < 1e-6)){ return false; } - if(!overnotransparent && SP_RGBA32_A_F(rgba) > 0){ + if(!over_no_transparent && SP_RGBA32_A_F(rgba) > 0){ return false; } if(offset < 100 ){ @@ -576,61 +604,54 @@ static bool fit_item(SPDesktop *desktop, (item_down->getAttribute("inkscape:spray-origin") && strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 )) { - if(nooverlap){ + 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(!nooverlap && (picker || overtransparent || overnotransparent)){ + if(!no_overlap && (picker || over_transparent || over_no_transparent)){ showHidden(items_down); } return false; } - } else if(picker || overtransparent || overnotransparent){ + } else if(picker || over_transparent || over_no_transparent){ item_down->setHidden(true); item_down->updateRepr(); } } } } - if(picker || overtransparent || overnotransparent){ - if(!nooverlap){ + 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(picknooverlap){ + if(pick_no_overlap){ if(rgba != rgba2){ - if(!nooverlap && (picker || overtransparent || overnotransparent)){ + if(!no_overlap && (picker || over_transparent || over_no_transparent)){ showHidden(items_down); } return false; } } - if(!pickcenter){ + if(!pick_center){ rgba = rgba2; } - int pick = prefs->getInt("/dialogs/clonetiler/pick"); - bool pick_to_presence = prefs->getBool("/dialogs/clonetiler/pick_to_presence", false); - bool pick_to_color = prefs->getBool("/dialogs/clonetiler/pick_to_color"); - bool pick_to_opacity = prefs->getBool("/dialogs/clonetiler/pick_to_opacity"); - double rand_picked = 0.01 * prefs->getDoubleLimited("/dialogs/clonetiler/rand_picked", 0, 0, 100); - bool invert_picked = prefs->getBool("/dialogs/clonetiler/invert_picked"); - double gamma_picked = prefs->getDoubleLimited("/dialogs/clonetiler/gamma_picked", 0, -10, 10); 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(!overtransparent && (a == 0 || a < 1e-6)){ - if(!nooverlap && (picker || overtransparent || overnotransparent)){ + if(!over_transparent && (a == 0 || a < 1e-6)){ + if(!no_overlap && (picker || over_transparent || over_no_transparent)){ showHidden(items_down); } return false; } - if(!overnotransparent && a > 0){ - if(!nooverlap && (picker || overtransparent || overnotransparent)){ + if(!over_no_transparent && a > 0){ + if(!no_overlap && (picker || over_transparent || over_no_transparent)){ showHidden(items_down); } return false; @@ -706,47 +727,58 @@ static bool fit_item(SPDesktop *desktop, rgba = SP_RGBA32_F_COMPOSE(r, g, b, a); if (pick_to_size) { if(!trace_scale){ - if(pickinversevalue) { + if(pick_inverse_value) { _scale = 1.0 - val; } else { _scale = val; } if(_scale == 0.0) { - if(!nooverlap && (picker || overtransparent || overnotransparent)){ + if(!no_overlap && (picker || over_transparent || over_no_transparent)){ + showHidden(items_down); + } + return false; + } + if(!fit_item(desktop + , item + , bbox + , move + , center + , 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(!fit_item(desktop, - item, - bbox, - move, - center, - angle, - _scale, - scale, - picker, - pickcenter, - pickinversevalue, - pickfill, - pickstroke, - picknooverlap, - overnotransparent, - overtransparent, - nooverlap, - offset, - css, - true)){ - if(!nooverlap && (picker || overtransparent || overnotransparent)){ - showHidden(items_down); - } - return false; - } } } if (pick_to_opacity) { - if(pickinversevalue) { + if(pick_inverse_value) { opacity *= 1.0 - val; } else { opacity *= val; @@ -765,36 +797,43 @@ static bool fit_item(SPDesktop *desktop, } if (pick_to_color) { sp_svg_write_color(color_string, sizeof(color_string), rgba); - if(pickfill){ + if(pick_fill){ sp_repr_css_set_property(css, "fill", color_string); } - if(pickstroke){ + if(pick_stroke){ sp_repr_css_set_property(css, "stroke", color_string); } } if (opacity < 1e-6) { // invisibly transparent, skip - if(!nooverlap && (picker || overtransparent || overnotransparent)){ + if(!no_overlap && (picker || over_transparent || over_no_transparent)){ showHidden(items_down); } return false; } } if(!do_trace){ - if (pickinversevalue) { - r = 1 - r; - g = 1 - g; - b = 1 - b; + 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_G_F(rgba); + } else { + r = SP_RGBA32_R_F(rgba); + g = SP_RGBA32_G_F(rgba); + b = SP_RGBA32_G_F(rgba); } rgba = SP_RGBA32_F_COMPOSE(r, g, b, a); sp_svg_write_color(color_string, sizeof(color_string), rgba); - if(pickfill){ + if(pick_fill){ sp_repr_css_set_property(css, "fill", color_string); } - if(pickstroke){ + if(pick_stroke){ sp_repr_css_set_property(css, "stroke", color_string); } } - if(!nooverlap && (picker || overtransparent || overnotransparent)){ + if(!no_overlap && (picker || over_transparent || over_no_transparent)){ showHidden(items_down); } } @@ -818,18 +857,27 @@ static bool sp_spray_recursive(SPDesktop *desktop, double tilt, double rotation_variation, gint _distrib, - bool nooverlap, + bool no_overlap, bool picker, - bool pickcenter, - bool pickinversevalue, - bool pickfill, - bool pickstroke, - bool picknooverlap, - bool overnotransparent, - bool overtransparent, + 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) + 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; @@ -867,8 +915,36 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(nooverlap || picker || !overtransparent || !overnotransparent){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickcenter, pickinversevalue, pickfill, pickstroke, picknooverlap, overnotransparent, overtransparent, nooverlap, offset, css, false)){ + if(no_overlap || picker || !over_transparent || !over_no_transparent){ + if(!fit_item(desktop + , item + , a + , move + , center + , 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; } } @@ -974,8 +1050,37 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(nooverlap || picker || !overtransparent || !overnotransparent){ - if(!fit_item(desktop, item, a, move, center, angle, _scale, scale, picker, pickcenter, pickinversevalue, pickfill, pickstroke, picknooverlap, overnotransparent, overtransparent, nooverlap, offset, css, false)){ + if(no_overlap || picker || !over_transparent || !over_no_transparent){ + if(!fit_item(desktop + , item + , a + , move + , center + , 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; } } @@ -1053,7 +1158,43 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for(std::vector::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, tc->nooverlap, tc->picker, tc->pickcenter, tc->pickinversevalue, tc->pickfill, tc->pickstroke, tc->picknooverlap, tc->overnotransparent, tc->overtransparent, tc->offset, tc->usepressurescale, get_pressure(tc))) { + 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; } } @@ -1100,7 +1241,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 377893f0d..438318bf4 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -89,22 +89,32 @@ public: bool has_dilated; Geom::Point last_push; SPCanvasItem *dilate_area; - bool nooverlap; + bool no_overlap; bool picker; - bool pickcenter; - bool pickinversevalue; - bool pickfill; - bool pickstroke; - bool picknooverlap; - bool overtransparent; - bool overnotransparent; + 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/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 34f728ce8..1ef0ca9f1 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -66,15 +66,15 @@ static void sp_stb_sensitivize( GObject *tbl ) GtkAction* spray_scale = GTK_ACTION( g_object_get_data(tbl, "spray_scale") ); GtkAdjustment *adj_offset = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(offset) ); GtkAdjustment *adj_scale = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(spray_scale) ); - GtkToggleAction *nooverlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "nooverlap") ); + GtkToggleAction *no_overlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "no_overlap") ); GtkToggleAction *picker = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "picker") ); GtkToggleAction *usepressurescale = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "usepressurescale") ); - GtkAction *pickfill = GTK_ACTION( g_object_get_data(tbl, "pickfill") ); - GtkAction *pickstroke = GTK_ACTION( g_object_get_data(tbl, "pickstroke") ); - GtkAction *pickinversevalue = GTK_ACTION( g_object_get_data(tbl, "pickinversevalue") ); - GtkAction *pickcenter = GTK_ACTION( g_object_get_data(tbl, "pickcenter") ); + GtkAction *pick_fill = GTK_ACTION( g_object_get_data(tbl, "pick_fill") ); + GtkAction *pick_stroke = GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ); + GtkAction *pick_inverse_value = GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ); + GtkAction *pick_center = GTK_ACTION( g_object_get_data(tbl, "pick_center") ); gtk_adjustment_set_value( adj_offset, 100.0 ); - if (gtk_toggle_action_get_active(nooverlap)) { + if (gtk_toggle_action_get_active(no_overlap)) { gtk_action_set_sensitive( offset, TRUE ); } else { gtk_action_set_sensitive( offset, FALSE ); @@ -86,15 +86,15 @@ static void sp_stb_sensitivize( GObject *tbl ) gtk_action_set_sensitive( spray_scale, TRUE ); } if(gtk_toggle_action_get_active(picker)){ - gtk_action_set_sensitive( pickfill, TRUE ); - gtk_action_set_sensitive( pickstroke, TRUE ); - gtk_action_set_sensitive( pickinversevalue, TRUE ); - gtk_action_set_sensitive( pickcenter, TRUE ); + gtk_action_set_sensitive( pick_fill, TRUE ); + gtk_action_set_sensitive( pick_stroke, TRUE ); + gtk_action_set_sensitive( pick_inverse_value, TRUE ); + gtk_action_set_sensitive( pick_center, TRUE ); } else { - gtk_action_set_sensitive( pickfill, FALSE ); - gtk_action_set_sensitive( pickstroke, FALSE ); - gtk_action_set_sensitive( pickinversevalue, FALSE ); - gtk_action_set_sensitive( pickcenter, FALSE ); + gtk_action_set_sensitive( pick_fill, FALSE ); + gtk_action_set_sensitive( pick_stroke, FALSE ); + gtk_action_set_sensitive( pick_inverse_value, FALSE ); + gtk_action_set_sensitive( pick_center, FALSE ); } } @@ -168,11 +168,11 @@ static void sp_spray_offset_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ gtk_adjustment_get_value(adj)); } -static void sp_toggle_nooverlap( GtkToggleAction* act, gpointer data) +static void sp_toggle_no_overlap( GtkToggleAction* act, gpointer data) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/nooverlap", active); + prefs->setBool("/tools/spray/no_overlap", active); GObject *tbl = G_OBJECT(data); sp_stb_sensitivize(tbl); } @@ -193,14 +193,14 @@ static void sp_toggle_over_no_transparent( GtkToggleAction* act, gpointer data) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/overnotransparent", active); + prefs->setBool("/tools/spray/over_no_transparent", active); } static void sp_toggle_over_transparent( GtkToggleAction* act, gpointer data) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/overtransparent", active); + prefs->setBool("/tools/spray/over_transparent", active); } @@ -225,35 +225,35 @@ static void sp_toggle_pick_center( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/pickcenter", active); + prefs->setBool("/tools/spray/pick_center", active); } static void sp_toggle_pick_fill( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/pickfill", active); + prefs->setBool("/tools/spray/pick_fill", active); } -static void sp_toggle_pick_no_overlap( GtkToggleAction* act, gpointer data ) +static void sp_toggle_pick_stroke( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/picknooverlap", active); + prefs->setBool("/tools/spray/pick_stroke", active); } -static void sp_toggle_pick_inverse_value( GtkToggleAction* act, gpointer data ) +static void sp_toggle_pick_no_overlap( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/pickinversevalue", active); + prefs->setBool("/tools/spray/pick_no_overlap", active); } -static void sp_toggle_pick_stroke( GtkToggleAction* act, gpointer data ) +static void sp_toggle_pick_inverse_value( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/pickstroke", active); + prefs->setBool("/tools/spray/pick_inverse_value", active); } void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) @@ -465,8 +465,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj _("Pick from center instead average area."), INKSCAPE_ICON("snap-bounding-box-center"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickcenter", true) ); - g_object_set_data( holder, "pickcenter", act ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_center", true) ); + g_object_set_data( holder, "pick_center", act ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_center), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } @@ -478,8 +478,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj _("Inversed pick value, retaining color in advanced trace mode"), INKSCAPE_ICON("object-tweak-shrink"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickinversevalue", false) ); - g_object_set_data( holder, "pickinversevalue", act ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_inverse_value", false) ); + g_object_set_data( holder, "pick_inverse_value", act ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_inverse_value), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } @@ -491,8 +491,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj _("Apply picked color to fill"), INKSCAPE_ICON("paint-solid"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickfill", false) ); - g_object_set_data( holder, "pickfill", act ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_fill", false) ); + g_object_set_data( holder, "pick_fill", act ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_fill), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } @@ -504,8 +504,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj _("Apply picked color to stroke"), INKSCAPE_ICON("no-marker"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pickstroke", false) ); - g_object_set_data( holder, "pickstroke", act ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_stroke", false) ); + g_object_set_data( holder, "pick_stroke", act ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_stroke), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } @@ -517,8 +517,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj _("No overlap between colors"), INKSCAPE_ICON("symbol-bigger"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picknooverlap", false) ); - g_object_set_data( holder, "picknooverlap", act ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_no_overlap", false) ); + g_object_set_data( holder, "pick_no_overlap", act ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_no_overlap), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } @@ -530,8 +530,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj _("Apply over transparent areas"), INKSCAPE_ICON("object-hidden"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overtransparent", true) ); - g_object_set_data( holder, "overtransparent", act ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/over_transparent", true) ); + g_object_set_data( holder, "over_transparent", act ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_over_transparent), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } @@ -543,8 +543,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj _("Apply over no transparent areas"), INKSCAPE_ICON("object-visible"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/overnotransparent", true) ); - g_object_set_data( holder, "overnotransparent", act ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/over_no_transparent", true) ); + g_object_set_data( holder, "over_no_transparent", act ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_over_no_transparent), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } @@ -556,9 +556,9 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj _("Prevent overlapping objects"), INKSCAPE_ICON("distribute-randomize"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/nooverlap", false) ); - g_object_set_data( holder, "nooverlap", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_nooverlap), holder) ; + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/no_overlap", false) ); + g_object_set_data( holder, "no_overlap", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_no_overlap), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } -- cgit v1.2.3 From 1bdb2511c92fd5390527aa51a9aa45de01421d2b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 11 Nov 2015 20:50:35 +0100 Subject: Add erase mode to spray. Bugfixes. (bzr r14459) --- src/ui/tools/spray-tool.cpp | 39 +++++++++++++++++++++++++++------------ src/ui/tools/spray-tool.h | 3 ++- src/widgets/spray-toolbar.cpp | 42 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 65 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 10a10f49f..84b0ad431 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -252,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"); @@ -276,14 +285,6 @@ void SprayTool::setup() { sp_event_context_read(this, "over_no_transparent"); sp_event_context_read(this, "over_transparent"); sp_event_context_read(this, "no_overlap"); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (prefs->getBool("/tools/spray/selcue")) { - this->enableSelectionCue(); - } - if (prefs->getBool("/tools/spray/gradientdrag")) { - this->enableGrDrag(); - } } void SprayTool::setCloneTilerPrefs() { @@ -491,6 +492,7 @@ static bool fit_item(SPDesktop *desktop, Geom::OptRect bbox, Geom::Point &move, Geom::Point center, + gint mode, double angle, double &_scale, double scale, @@ -604,7 +606,11 @@ static bool fit_item(SPDesktop *desktop, (item_down->getAttribute("inkscape:spray-origin") && strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 )) { - if(no_overlap){ + if(mode == SPRAY_MODE_ERASER){ + if(strcmp(item_down_sharp, spray_origin) != 0 ){ + item_down->deleteObject(); + } + }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)){ @@ -619,6 +625,12 @@ static bool fit_item(SPDesktop *desktop, } } } + if(mode == SPRAY_MODE_ERASER){ + if(!no_overlap && (picker || over_transparent || over_no_transparent)){ + showHidden(items_down); + } + return false; + } if(picker || over_transparent || over_no_transparent){ if(!no_overlap){ doc->ensureUpToDate(); @@ -743,6 +755,7 @@ static bool fit_item(SPDesktop *desktop, , bbox , move , center + , mode , angle , _scale , scale @@ -818,11 +831,11 @@ static bool fit_item(SPDesktop *desktop, if (pick_inverse_value) { r = 1 - SP_RGBA32_R_F(rgba); g = 1 - SP_RGBA32_G_F(rgba); - b = 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_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); @@ -900,7 +913,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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) { if(_fid <= population) @@ -921,6 +934,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, , a , move , center + , mode , angle , _scale , scale @@ -1056,6 +1070,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, , a , move , center + , mode , angle , _scale , scale diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index 438318bf4..c81110b37 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -47,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, }; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 1ef0ca9f1..8866cf11e 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -68,13 +68,14 @@ static void sp_stb_sensitivize( GObject *tbl ) GtkAdjustment *adj_scale = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(spray_scale) ); GtkToggleAction *no_overlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "no_overlap") ); GtkToggleAction *picker = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "picker") ); + GtkAction* picker_action = GTK_ACTION( g_object_get_data(tbl, "picker") ); GtkToggleAction *usepressurescale = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "usepressurescale") ); GtkAction *pick_fill = GTK_ACTION( g_object_get_data(tbl, "pick_fill") ); GtkAction *pick_stroke = GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ); GtkAction *pick_inverse_value = GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ); GtkAction *pick_center = GTK_ACTION( g_object_get_data(tbl, "pick_center") ); gtk_adjustment_set_value( adj_offset, 100.0 ); - if (gtk_toggle_action_get_active(no_overlap)) { + if (gtk_toggle_action_get_active(no_overlap) && gtk_action_get_sensitive(picker_action)) { gtk_action_set_sensitive( offset, TRUE ); } else { gtk_action_set_sensitive( offset, FALSE ); @@ -85,7 +86,7 @@ static void sp_stb_sensitivize( GObject *tbl ) } else { gtk_action_set_sensitive( spray_scale, TRUE ); } - if(gtk_toggle_action_get_active(picker)){ + if(gtk_toggle_action_get_active(picker) && gtk_action_get_sensitive(picker_action)){ gtk_action_set_sensitive( pick_fill, TRUE ); gtk_action_set_sensitive( pick_stroke, TRUE ); gtk_action_set_sensitive( pick_inverse_value, TRUE ); @@ -98,6 +99,21 @@ static void sp_stb_sensitivize( GObject *tbl ) } } +static void sp_spray_erase_sensitivize( GObject *tbl, bool sensitive){ + gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "rotate") ), sensitive ); + gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "no_overlap") ), sensitive ); + gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "over_no_transparent") ), sensitive ); + gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "over_transparent") ), sensitive ); + gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "pick_no_overlap") ), sensitive ); + gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ), sensitive ); + gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "pick_fill") ), sensitive ); + gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ), sensitive ); + gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "pick_center") ), sensitive ); + gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "picker") ), sensitive ); + gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "offset") ), sensitive ); + sp_stb_sensitivize( tbl ); +} + Inkscape::UI::Dialog::CloneTiler *get_clone_tiler_panel(SPDesktop *desktop) { if (Inkscape::UI::Dialog::PanelDialogBase *panel_dialog = @@ -133,11 +149,16 @@ static void sp_spray_standard_deviation_value_changed( GtkAdjustment *adj, GObje gtk_adjustment_get_value(adj)); } -static void sp_spray_mode_changed( EgeSelectOneAction *act, GObject * /*tbl*/ ) +static void sp_spray_mode_changed( EgeSelectOneAction *act, GObject * tbl ) { int mode = ege_select_one_action_get_active( act ); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setInt("/tools/spray/mode", mode); + if(mode != 3){ + sp_spray_erase_sensitivize(tbl, true); + } else { + sp_spray_erase_sensitivize(tbl, false); + } } static void sp_spray_population_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) @@ -210,7 +231,7 @@ static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) gboolean active = gtk_toggle_action_get_active(act); prefs->setBool("/tools/spray/picker", active); if(active == true){ - prefs->setBool("/dialogs/clonetiler/dotrace", true); + prefs->setBool("/dialogs/clonetiler/dotrace", false); SPDesktop *dt = SP_ACTIVE_DESKTOP; if (Inkscape::UI::Dialog::CloneTiler *ct = get_clone_tiler_panel(dt)){ dt->_dlg_mgr->showDialog("CloneTiler"); @@ -323,7 +344,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Mode */ { - GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); + GtkListStore* model = gtk_list_store_new( 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); GtkTreeIter iter; gtk_list_store_append( model, &iter ); @@ -339,6 +360,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj 1, _("Spray clones of the initial selection"), 2, INKSCAPE_ICON("spray-mode-clone"), -1 ); + #ifdef ENABLE_SPRAY_MODE_SINGLE_PATH gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, @@ -347,6 +369,14 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj 2, INKSCAPE_ICON("spray-mode-union"), -1 ); #endif + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("Delete sprayed items"), + 1, _("Delete sprayed items from selection"), + 2, INKSCAPE_ICON("draw-eraser"), + -1 ); + EgeSelectOneAction* act = ege_select_one_action_new( "SprayModeAction", _("Mode"), (""), NULL, GTK_TREE_MODEL(model) ); g_object_set( act, "short_label", _("Mode:"), NULL ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); @@ -575,7 +605,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_object_set_data( holder, "offset", eact ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); } - sp_stb_sensitivize(holder); + sp_spray_erase_sensitivize(holder, prefs->getInt("/tools/spray/mode") != 3); } -- cgit v1.2.3 From 5c63ccc3f259311d078f77c8262459bb54677884 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 12 Nov 2015 15:34:33 +0100 Subject: Fix a warn on launch (bzr r14460) --- src/widgets/spray-toolbar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 8866cf11e..db1f9526a 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -100,7 +100,6 @@ static void sp_stb_sensitivize( GObject *tbl ) } static void sp_spray_erase_sensitivize( GObject *tbl, bool sensitive){ - gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "rotate") ), sensitive ); gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "no_overlap") ), sensitive ); gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "over_no_transparent") ), sensitive ); gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "over_transparent") ), sensitive ); @@ -111,6 +110,7 @@ static void sp_spray_erase_sensitivize( GObject *tbl, bool sensitive){ gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "pick_center") ), sensitive ); gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "picker") ), sensitive ); gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "offset") ), sensitive ); + gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "spray_rotation") ), sensitive ); sp_stb_sensitivize( tbl ); } -- cgit v1.2.3 From 56215c1d1b93e249c0a4cddddc67868dc4f3dd56 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 12 Nov 2015 16:05:46 +0100 Subject: Fix crashes in erase mode of spray (bzr r14461) --- src/ui/tools/spray-tool.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 84b0ad431..0d3405dbd 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -586,6 +586,7 @@ static bool fit_item(SPDesktop *desktop, return false; } std::vector const items_selected(selection->itemList()); + std::vector items_down_erased; for (std::vector::const_iterator i=items_down.begin(); i!=items_down.end(); i++) { SPItem *item_down = *i; Geom::OptRect bbox_down = item_down->documentVisualBounds(); @@ -594,6 +595,7 @@ static bool fit_item(SPDesktop *desktop, 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::const_iterator j=items_selected.begin(); j!=items_selected.end(); j++) { SPItem *item_selected = *j; gchar const * spray_origin; @@ -607,8 +609,10 @@ static bool fit_item(SPDesktop *desktop, strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 )) { if(mode == SPRAY_MODE_ERASER){ - if(strcmp(item_down_sharp, spray_origin) != 0 ){ + 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) && @@ -627,7 +631,7 @@ static bool fit_item(SPDesktop *desktop, } if(mode == SPRAY_MODE_ERASER){ if(!no_overlap && (picker || over_transparent || over_no_transparent)){ - showHidden(items_down); + showHidden(items_down_erased); } return false; } -- cgit v1.2.3 From ec3c0a24bb14d96bfcef72cdd72326fce2790eff Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Thu, 12 Nov 2015 23:44:26 +0000 Subject: Fix CMake build (bzr r14449.1.6) --- src/trace/CMakeLists.txt | 3 +++ src/ui/CMakeLists.txt | 15 +++++++++++---- src/widgets/CMakeLists.txt | 11 +++++++++-- 3 files changed, 23 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/trace/CMakeLists.txt b/src/trace/CMakeLists.txt index 776d96158..12cf495f6 100644 --- a/src/trace/CMakeLists.txt +++ b/src/trace/CMakeLists.txt @@ -1,3 +1,4 @@ +if (${HAVE_POTRACE}) set(trace_SRC filterset.cpp @@ -25,3 +26,5 @@ set(trace_SRC # add_inkscape_lib(trace_LIB "${trace_SRC}") add_inkscape_source("${trace_SRC}") + +endif() diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 58af7d935..46b0af6bb 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -34,7 +34,6 @@ set(ui_SRC tools/dropper-tool.cpp tools/dynamic-base.cpp tools/eraser-tool.cpp - tools/flood-tool.cpp tools/freehand-base.cpp tools/gradient-tool.cpp tools/lpe-tool.cpp @@ -107,7 +106,6 @@ set(ui_SRC dialog/template-widget.cpp dialog/text-edit.cpp dialog/tile.cpp - dialog/tracedialog.cpp dialog/transformation.cpp dialog/undo-history.cpp dialog/xml-tree.cpp @@ -248,7 +246,6 @@ set(ui_SRC dialog/template-widget.h dialog/text-edit.h dialog/tile.h - dialog/tracedialog.h dialog/transformation.h dialog/undo-history.h dialog/xml-tree.h @@ -276,7 +273,6 @@ set(ui_SRC tools/dropper-tool.h tools/dynamic-base.h tools/eraser-tool.h - tools/flood-tool.h tools/freehand-base.h tools/gradient-tool.h tools/lpe-tool.h @@ -364,3 +360,14 @@ endif() # add_inkscape_lib(ui_LIB "${ui_SRC}") add_inkscape_source("${ui_SRC}") + +set ( ui_flood_and_trace_SRC + tools/flood-tool.h + tools/flood-tool.cpp + dialog/tracedialog.cpp + dialog/tracedialog.h +) + +if ("${HAVE_POTRACE}") + add_inkscape_source("${ui_flood_and_trace_SRC}") +endif() diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index a3e9e14d0..c38bde5cf 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -11,7 +11,6 @@ set(widgets_SRC measure-toolbar.cpp mesh-toolbar.cpp node-toolbar.cpp - paintbucket-toolbar.cpp pencil-toolbar.cpp rect-toolbar.cpp spiral-toolbar.cpp @@ -67,7 +66,6 @@ set(widgets_SRC measure-toolbar.h mesh-toolbar.h node-toolbar.h - paintbucket-toolbar.h pencil-toolbar.h rect-toolbar.h spiral-toolbar.h @@ -114,3 +112,12 @@ set(widgets_SRC # add_inkscape_lib(widgets_LIB "${widgets_SRC}") add_inkscape_source("${widgets_SRC}") + +set ( widgets_paintbucket_SRC + paintbucket-toolbar.cpp + paintbucket-toolbar.h +) + +if ("${HAVE_POTRACE}") + add_inkscape_source("${widgets_paintbucket_SRC}") +endif() -- cgit v1.2.3 From 7d77133cec471ae1e3e40937ebb637876f1c9a47 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 13 Nov 2015 12:54:14 +0100 Subject: Fixed a bug on Spray Friendly when SPLPEITEM has clones. POinted by Ivan Louette (bzr r14422.3.5) --- src/live_effects/lpe-roughen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 6c2ec0227..00f7b8012 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -98,7 +98,7 @@ LPERoughen::~LPERoughen() {} void LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem) { - if(spray_tool_friendly && seed == 0){ + if(spray_tool_friendly && seed == 0 && SP_OBJECT(lpeitem)->getId()){ std::string id_item(SP_OBJECT(lpeitem)->getId()); long seed = static_cast(boost::hash_value(id_item)); global_randomize.param_set_value(global_randomize.get_value(), seed); -- cgit v1.2.3 From d136162e0abe6b045ac791b8eb0e16ee51b3f7cc Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Nov 2015 15:35:25 +0100 Subject: Replace leading by more useful x-height. Use OS/2 font metrics when available. Use otmMacAscent/otmMacDescent rather than otmAscent/otmDescent. Actually both should be available as they have different purposes... (bzr r14430.1.5) --- src/libnrtype/FontInstance.cpp | 66 ++++++++++++++++++++++++++++++------ src/libnrtype/Layout-TNG-Compute.cpp | 6 ++-- src/libnrtype/Layout-TNG.h | 9 ++--- src/libnrtype/TextWrapper.cpp | 4 +-- src/libnrtype/one-box.h | 2 +- 5 files changed, 66 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index 6b2e030d1..5853d5217 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -21,6 +21,7 @@ #include FT_BBOX_H #include FT_TRUETYPE_TAGS_H #include FT_TRUETYPE_TABLES_H +#include FT_GLYPH_H #include #include <2geom/pathvector.h> #include <2geom/path-sink.h> @@ -507,7 +508,7 @@ void font_instance::LoadGlyph(int glyph_id) } } -bool font_instance::FontMetrics(double &ascent,double &descent,double &leading) +bool font_instance::FontMetrics(double &ascent,double &descent,double &xheight) { if ( pFont == NULL ) { return false; @@ -516,34 +517,77 @@ bool font_instance::FontMetrics(double &ascent,double &descent,double &leading) if ( theFace == NULL ) { return false; } + + // CSS2 recommends using the OS/2 values sTypoAscender and sTypoDescender + // for the ascender and descender values: + // http://www.w3.org/TR/CSS2/visudet.html#sTypoAscender + // The typographic ascender and descender are taken from the + // otmMacAscent and otmMacDescent values: + // http://microsoft.public.win32.programmer.gdi.narkive.com/LV6k4BDh/msdn-documentation-outlinetextmetrics-clarification + // The otmAscent and otmDescent values are the maxiumum ascent and maxiumum + // descent of all the glyphs in a font. + #ifdef USE_PANGO_WIN32 OUTLINETEXTMETRIC otm; if ( !GetOutlineTextMetrics(parent->hScreenDC,sizeof(otm),&otm) ) { return false; } + double scale=1.0/parent->fontSize; - ascent=fabs(otm.otmAscent*scale); - descent=fabs(otm.otmDescent*scale); - leading=fabs(otm.otmLineGap*scale); + ascent=fabs(otm.otmMacAscent*scale); + descent=fabs(otm.otmMacDescent*scale); + xheight=fabs(otm.otmXHeight*scale); + // May not be necessary... but if OS/2 table is missing or not version 2 or higher, + // xheight might be set to 0. + if( xheight = 0.0 ) xheight = ascent/2.0; //otmSubscriptSize, otmSubscriptOffset, otmSuperscriptSize, otmSuperscriptOffset, #else if ( theFace->units_per_EM == 0 ) { return false; // bitmap font } - ascent=fabs(((double)theFace->ascender)/((double)theFace->units_per_EM)); - descent=fabs(((double)theFace->descender)/((double)theFace->units_per_EM)); - leading=fabs(((double)theFace->height)/((double)theFace->units_per_EM)); - leading-=ascent+descent; + + TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table( theFace, FT_SFNT_OS2 ); + if( os2 ) { + ascent =fabs(((double)os2->sTypoAscender)/((double)theFace->units_per_EM)); + descent=fabs(((double)os2->sTypoDescender)/((double)theFace->units_per_EM)); + } else { + ascent =fabs(((double)theFace->ascender)/((double)theFace->units_per_EM)); + descent=fabs(((double)theFace->descender)/((double)theFace->units_per_EM)); + } + + // We must find x-height ourselves! First try OS/2 table. + if( os2 && os2->version >= 0x0002 && os2->version != 0xffffu ) { + // Only os/2 version 2 and above have sxHeight, 0xffff marks "old Mac fonts" without table + xheight=fabs(((double)os2->sxHeight)/((double)theFace->units_per_EM)); + } else { + // Measure 'x' height in font. Recommended option by XSL standard if no sxHeight. + FT_UInt index = FT_Get_Char_Index( theFace, 'x' ); + if( index != 0 ) { + FT_Load_Glyph( theFace, index, FT_LOAD_NO_SCALE ); + xheight = (fabs)(((double)theFace->glyph->metrics.height/(double)theFace->units_per_EM)); + } else { + // No 'x' in font! + xheight = ascent/2.0; + } + } #endif - // CSS dictates em size is ascent + descent + // CSS dictates em size is ascent + descent.... but this doesn't seem to be used in practice. + // The em size is what the font reports... double em = ascent + descent; if( em <= 0 ) { - return false; // Pathological + return false; // Pathological } ascent /= em; descent /= em; - leading /= em; + xheight /= em; + + // gchar* font_name = pango_font_description_to_string( descr ); + // std::cout << "Font: " << (font_name ? font_name : ("Null")) << std::endl; + // g_free( font_name ); + // std::cout << " ascent: " << ascent << " descent: " << descent + // << " x-height: " << xheight << "\n" << std::endl; + return true; } diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 8f7f6bca0..6b5697b10 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -1121,7 +1121,7 @@ void Layout::Calculator::_computeFontLineHeight(font_instance *font, double font *line_height_multiplier = 1.0; } else { - font->FontMetrics(font_metrics->ascent, font_metrics->descent, font_metrics->leading); + font->FontMetrics(font_metrics->ascent, font_metrics->descent, font_metrics->xheight); } *font_metrics *= font_size; @@ -1819,13 +1819,13 @@ void Layout::_calculateCursorShapeForEmpty() FontMetrics line_height; if (font) { const_cast(font)->FontSlope(caret_slope_run, caret_slope_rise); - font->FontMetrics(line_height.ascent, line_height.descent, line_height.leading); + font->FontMetrics(line_height.ascent, line_height.descent, line_height.xheight); line_height *= font_size; font->Unref(); } else { line_height.ascent = font_size * 0.85; // random guesses line_height.descent = font_size * 0.15; - line_height.leading = 0.0; + line_height.xheight = 0.0; } double caret_slope = atan2(caret_slope_run, caret_slope_rise); _empty_cursor_shape.height = font_size / cos(caret_slope); diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 6875fa14a..c2895e05f 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -610,7 +610,7 @@ public: /** * Keep track of font metrics. Two use cases: - * 1. Keep track of ascent and descent of an individual font. + * 1. Keep track of ascent, descent, and x-height of an individual font. * 2. Keep track of effective ascent and descent that includes half-leading. * * Note: Leading refers to the "external" leading which is added (subtracted) due to @@ -626,16 +626,16 @@ public: double ascent; double descent; - double leading; // Not used... to be removed (requires change to font->FontMetrics() + double xheight; // CSS 2.1 dictates that font-size is based on em-size which is defined as ascent + descent inline double emSize() const {return ascent + descent;} // Alternatively name function for use 2. inline double lineSize() const { return ascent + descent; } - inline void setZero() {ascent = descent = 0.0;} + inline void setZero() {ascent = descent = xheight = 0.0;} // For scaling for 'font-size'. - inline FontMetrics& operator*=(double x) {ascent *= x; descent *= x; return *this;} + inline FontMetrics& operator*=(double x) {ascent *= x; descent *= x; xheight *= x; return *this;} /// Save the larger values of ascent and descent between this and other. Needed for laying /// out a line with mixed font-sizes, fonts, or line spacings. @@ -646,6 +646,7 @@ public: inline double getAscent() const {return ascent; } inline double getDescent() const {return descent; } + inline double getXheight() const {return xheight; } }; /// see _enum_converter() diff --git a/src/libnrtype/TextWrapper.cpp b/src/libnrtype/TextWrapper.cpp index 380e9ba3f..124f3f7b4 100644 --- a/src/libnrtype/TextWrapper.cpp +++ b/src/libnrtype/TextWrapper.cpp @@ -862,7 +862,7 @@ void text_wrapper::MeasureBoxes(void) for (int i = 0; i < nbBox; i++) { boxes[i].ascent = 0; boxes[i].descent = 0; - boxes[i].leading = 0; + boxes[i].xheight = 0; boxes[i].width = 0; PangoFont *curPF = glyph_text[boxes[i].g_st].font; @@ -870,7 +870,7 @@ void text_wrapper::MeasureBoxes(void) PangoFontDescription *pfd = pango_font_describe(curPF); font_instance *curF = f_src->Face(pfd); if ( curF ) { - curF->FontMetrics(boxes[i].ascent, boxes[i].descent, boxes[i].leading); + curF->FontMetrics(boxes[i].ascent, boxes[i].descent, boxes[i].xheight); curF->Unref(); } pango_font_description_free(pfd); diff --git a/src/libnrtype/one-box.h b/src/libnrtype/one-box.h index c868cf23f..c3b36a3ce 100644 --- a/src/libnrtype/one-box.h +++ b/src/libnrtype/one-box.h @@ -9,7 +9,7 @@ // this time for sp-typeset struct one_box { int g_st, g_en; ///< First and last glyph of this word. - double ascent, descent, leading; + double ascent, descent, xheight; double width; bool word_start, word_end; }; -- cgit v1.2.3 From bbb9eba40d9bd611af330c40897378adcfd60001 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 13 Nov 2015 15:55:42 +0100 Subject: Fix a bug on bspline, duplicating end nodes (bzr r14462) --- src/live_effects/lpe-bspline.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 731b5d645..7e92e767d 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -206,6 +206,18 @@ void sp_bspline_do_effect(SPCurve *curve, double helper_size) Geom::D2 sbasis_helper; Geom::CubicBezier const *cubic = NULL; curve_n->moveto(curve_it1->initialPoint()); + if (path_it->closed()) { + const Geom::Curve &closingline = path_it->back_closed(); + // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } while (curve_it1 != curve_endit) { SPCurve *in = new SPCurve(); in->moveto(curve_it1->initialPoint()); @@ -361,6 +373,18 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) Geom::D2 sbasis_out; Geom::CubicBezier const *cubic = NULL; curve_n->moveto(curve_it1->initialPoint()); + if (path_it->closed()) { + const Geom::Curve &closingline = path_it->back_closed(); + // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } while (curve_it1 != curve_endit) { SPCurve *in = new SPCurve(); in->moveto(curve_it1->initialPoint()); -- cgit v1.2.3 From e8ec23b80082d4c1c20675c83f5a6fad18c3392d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 13 Nov 2015 16:11:51 +0100 Subject: Fix bug end node, start calculate size based in number of nodes and lenght (bzr r14422.3.6) --- src/live_effects/lpe-roughen.cpp | 67 +++++++++++++++++++++++++++++++++++++++- src/live_effects/lpe-roughen.h | 1 + 2 files changed, 67 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 00f7b8012..6b18cf14e 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -65,7 +65,7 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) true), fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment length"), "fixed_displacement", &wr, this, false), - spray_tool_friendly(_("Spray Tool friendly"), _("For use with spray tool"), + spray_tool_friendly(_("Spray Tool friendly"), _("For use with spray tool in copy mode"), "spray_tool_friendly", &wr, this, false) { registerParameter(&method); @@ -96,6 +96,59 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) LPERoughen::~LPERoughen() {} +void LPERoughen::doOnApply(SPLPEItem const* lpeitem) +{ + SPLPEItem* item = const_cast(lpeitem); + //calculamos el tamaƱo mas optimo para el roughen en función del nĆŗmero de nodos y la distancia del trazado +} + +static void +sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) +{ + std::vector const item_list = sp_item_group_item_list(group); + + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { + SPObject *subitem = *iter; + + SPGroup *subGroup = dynamic_cast(subitem); + if (subGroup) { + sp_group_perform_patheffect(subGroup, topgroup, write); + } else { + SPShape *subShape = dynamic_cast(subitem); + if (subShape) { + SPCurve * c = NULL; + + SPPath *subPath = dynamic_cast(subShape); + if (subPath) { + c = subPath->get_original_curve(); + } else { + c = subShape->getCurve(); + } + + // only run LPEs when the shape has a curve defined + if (c) { + c->transform(i2anc_affine(subitem, topgroup)); + topgroup->performPathEffect(c); + c->transform(i2anc_affine(subitem, topgroup).inverse()); + subShape->setCurve(c, TRUE); + + if (write) { + Inkscape::XML::Node *repr = subitem->getRepr(); + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); +#ifdef GROUP_VERBOSE + g_message("sp_group_perform_patheffect writes 'd' attribute"); +#endif + g_free(str); + } + + c->unref(); + } + } + } + } +} + void LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem) { if(spray_tool_friendly && seed == 0 && SP_OBJECT(lpeitem)->getId()){ @@ -228,6 +281,18 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::Point prev(0, 0); Geom::Point last_move(0, 0); nCurve->moveto(curve_it1->initialPoint()); + if (path_it->closed()) { + const Geom::Curve &closingline = path_it->back_closed(); + // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } while (curve_it1 != curve_endit) { Geom::CubicBezier const *cubic = NULL; cubic = dynamic_cast(&*curve_it1); diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index 6224c09fa..b12bd08af 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -45,6 +45,7 @@ public: virtual void doEffect(SPCurve *curve); virtual double sign(double randNumber); + virtual void doOnApply(SPLPEItem const* lpeitem); virtual Geom::Point randomize(double max_lenght, bool is_node = false); virtual Geom::Point randomize(double lenght, Geom::Point start, Geom::Point end); virtual void doBeforeEffect(SPLPEItem const * lpeitem); -- cgit v1.2.3 From 7c7b311cb7ff307a4e865341c3b78ec669e73fc7 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Fri, 13 Nov 2015 18:53:22 +0100 Subject: static code analysis (bzr r14463) --- src/gradient-chemistry.cpp | 4 ++-- src/gradient-drag.cpp | 6 +++--- src/graphlayout.cpp | 2 +- src/object-snapper.cpp | 2 +- src/path-chemistry.cpp | 12 ++++++------ src/selcue.cpp | 6 +++--- src/sp-clippath.cpp | 2 +- src/sp-mask.cpp | 2 +- src/sp-pattern.cpp | 6 +++--- src/ui/dialog/filter-effects-dialog.cpp | 6 +++--- src/ui/dialog/find.cpp | 16 ++++++++-------- src/ui/dialog/grid-arrange-tab.cpp | 6 +++--- src/ui/dialog/objects.cpp | 2 +- src/ui/dialog/polar-arrange-tab.cpp | 2 +- src/ui/tools/connector-tool.cpp | 2 +- src/ui/tools/gradient-tool.cpp | 4 ++-- src/ui/tools/spray-tool.cpp | 8 ++++---- src/ui/tools/tweak-tool.cpp | 2 +- src/widgets/fill-style.cpp | 6 +++--- src/widgets/spiral-toolbar.cpp | 4 ++-- 20 files changed, 50 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 409e9f0e6..886bf484d 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -1571,7 +1571,7 @@ void sp_gradient_invert_selected_gradients(SPDesktop *desktop, Inkscape::PaintTa Inkscape::Selection *selection = desktop->getSelection(); const std::vector list=selection->itemList(); - for (std::vector::const_iterator i = list.begin(); i != list.end(); i++) { + for (std::vector::const_iterator i = list.begin(); i != list.end(); ++i) { sp_item_gradient_invert_vector_color(*i, fill_or_stroke); } @@ -1596,7 +1596,7 @@ void sp_gradient_reverse_selected_gradients(SPDesktop *desktop) drag->selected_reverse_vector(); } else { // If no drag or no dragger selected, act on selection (both fill and stroke gradients) const std::vector list=selection->itemList(); - for (std::vector::const_iterator i = list.begin(); i != list.end(); i++) { + for (std::vector::const_iterator i = list.begin(); i != list.end(); ++i) { sp_item_gradient_reverse_vector(*i, Inkscape::FOR_FILL); sp_item_gradient_reverse_vector(*i, Inkscape::FOR_STROKE); } diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index b5a988729..f94ffb838 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -2083,7 +2083,7 @@ void GrDrag::updateDraggers() g_return_if_fail(this->selection != NULL); std::vector list = this->selection->itemList(); - for (std::vector::const_iterator i = list.begin(); i != list.end(); i++) { + for (std::vector::const_iterator i = list.begin(); i != list.end(); ++i) { SPItem *item = *i; SPStyle *style = item->style; @@ -2152,7 +2152,7 @@ void GrDrag::updateLines() g_return_if_fail(this->selection != NULL); std::vector list = this->selection->itemList(); - for (std::vector::const_iterator i = list.begin(); i != list.end(); i++) { + for (std::vector::const_iterator i = list.begin(); i != list.end(); ++i) { SPItem *item = *i; SPStyle *style = item->style; @@ -2296,7 +2296,7 @@ void GrDrag::updateLevels() g_return_if_fail (this->selection != NULL); std::vector list = this->selection->itemList(); - for (std::vector::const_iterator i = list.begin(); i != list.end(); i++) { + for (std::vector::const_iterator i = list.begin(); i != list.end(); ++i) { SPItem *item = *i; Geom::OptRect rect = item->desktopVisualBounds(); if (rect) { diff --git a/src/graphlayout.cpp b/src/graphlayout.cpp index 40994347c..9b67ba0b5 100644 --- a/src/graphlayout.cpp +++ b/src/graphlayout.cpp @@ -89,7 +89,7 @@ struct CheckProgress : TestConvergence { * not connectors in filtered */ void filterConnectors(std::vector const &items, list &filtered) { - for(std::vector::const_iterator i = items.begin();i !=items.end(); i++){ + for(std::vector::const_iterator i = items.begin();i !=items.end(); ++i){ SPItem *item = *i; if(!isConnector(item)) { filtered.push_back(item); diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 7302f9de6..5b7874c61 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -239,7 +239,7 @@ void Inkscape::ObjectSnapper::_collectNodes(SnapSourceType const &t, bool old_pref2 = _snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_ROTATION_CENTER); if (old_pref2) { std::vector rotationSource=_snapmanager->getRotationCenterSource(); - for ( std::vector::const_iterator itemlist = rotationSource.begin(); itemlist != rotationSource.end(); itemlist++) { + for ( std::vector::const_iterator itemlist = rotationSource.begin(); itemlist != rotationSource.end(); ++itemlist) { if ((*i).item == *itemlist) { // don't snap to this item's rotation center _snapmanager->snapprefs.setTargetSnappable(SNAPTARGET_ROTATION_CENTER, false); diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index c71465782..7b52ac2e1 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -71,14 +71,14 @@ sp_selected_path_combine(SPDesktop *desktop) items = sp_degroup_list (items); // descend into any groups in selection std::vector to_paths; - for (std::vector::const_reverse_iterator i = items.rbegin(); i != items.rend(); i++) { + for (std::vector::const_reverse_iterator i = items.rbegin(); i != items.rend(); ++i) { if (!dynamic_cast(*i) && !dynamic_cast(*i)) { to_paths.push_back(*i); } } std::vector converted; bool did = sp_item_list_to_curves(to_paths, items, converted); - for (std::vector::const_iterator i = converted.begin(); i != converted.end(); i++) + for (std::vector::const_iterator i = converted.begin(); i != converted.end(); ++i) items.push_back((SPItem*)doc->getObjectByRepr(*i)); items = sp_degroup_list (items); // converting to path may have added more groups, descend again @@ -101,7 +101,7 @@ sp_selected_path_combine(SPDesktop *desktop) selection->clear(); } - for (std::vector::const_reverse_iterator i = items.rbegin(); i != items.rend(); i++){ + for (std::vector::const_reverse_iterator i = items.rbegin(); i != items.rend(); ++i){ SPItem *item = *i; SPPath *path = dynamic_cast(item); @@ -204,7 +204,7 @@ sp_selected_path_break_apart(SPDesktop *desktop) bool did = false; std::vector itemlist(selection->itemList()); - for (std::vector::const_iterator i = itemlist.begin(); i != itemlist.end(); i++){ + for (std::vector::const_iterator i = itemlist.begin(); i != itemlist.end(); ++i){ SPItem *item = *i; @@ -354,7 +354,7 @@ bool sp_item_list_to_curves(const std::vector &items, std::vector& selected, std::vector &to_select, bool skip_all_lpeitems) { bool did = false; - for (std::vector::const_iterator i = items.begin(); i != items.end(); i++){ + for (std::vector::const_iterator i = items.begin(); i != items.end(); ++i){ SPItem *item = *i; g_assert(item != NULL); SPDocument *document = item->document; @@ -621,7 +621,7 @@ sp_selected_path_reverse(SPDesktop *desktop) bool did = false; desktop->messageStack()->flash(Inkscape::IMMEDIATE_MESSAGE, _("Reversing paths...")); - for (std::vector::const_iterator i = items.begin(); i != items.end(); i++){ + for (std::vector::const_iterator i = items.begin(); i != items.end(); ++i){ SPPath *path = dynamic_cast(*i); if (!path) { diff --git a/src/selcue.cpp b/src/selcue.cpp index c73219b7d..297b9fffc 100644 --- a/src/selcue.cpp +++ b/src/selcue.cpp @@ -104,7 +104,7 @@ void Inkscape::SelCue::_updateItemBboxes(gint mode, int prefs_bbox) int bcount = 0; std::vector ll=_selection->itemList(); - for (std::vector::const_iterator l = ll.begin(); l != ll.end(); l++) { + for (std::vector::const_iterator l = ll.begin(); l != ll.end(); ++l) { SPItem *item = *l; SPCanvasItem* box = _item_bboxes[bcount ++]; @@ -147,7 +147,7 @@ void Inkscape::SelCue::_newItemBboxes() int prefs_bbox = prefs->getBool("/tools/bounding_box"); std::vector ll=_selection->itemList(); - for (std::vector::const_iterator l = ll.begin(); l != ll.end(); l++) { + for (std::vector::const_iterator l = ll.begin(); l != ll.end(); ++l) { SPItem *item = *l; Geom::OptRect const b = (prefs_bbox == 0) ? @@ -202,7 +202,7 @@ void Inkscape::SelCue::_newTextBaselines() _text_baselines.clear(); std::vector ll = _selection->itemList(); - for (std::vector::const_iterator l=ll.begin();l!=ll.end();l++) { + for (std::vector::const_iterator l=ll.begin();l!=ll.end();++l) { SPItem *item = *l; SPCanvasItem* baseline_point = NULL; diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp index d66508eae..0c07d1b3d 100644 --- a/src/sp-clippath.cpp +++ b/src/sp-clippath.cpp @@ -308,7 +308,7 @@ const gchar *SPClipPath::create (std::vector &reprs, SPDoc const gchar *id = repr->attribute("id"); SPObject *clip_path_object = document->getObjectById(id); - for (std::vector::const_iterator it = reprs.begin(); it != reprs.end(); it++) { + for (std::vector::const_iterator it = reprs.begin(); it != reprs.end(); ++it) { Inkscape::XML::Node *node = (*it); SPItem *item = SP_ITEM(clip_path_object->appendChildRepr(node)); diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp index f8fb7aff4..5f7a2ec26 100644 --- a/src/sp-mask.cpp +++ b/src/sp-mask.cpp @@ -221,7 +221,7 @@ sp_mask_create (std::vector &reprs, SPDocument *document, const gchar *mask_id = repr->attribute("id"); SPObject *mask_object = document->getObjectById(mask_id); - for (std::vector::const_iterator it = reprs.begin(); it != reprs.end(); it++) { + for (std::vector::const_iterator it = reprs.begin(); it != reprs.end(); ++it) { Inkscape::XML::Node *node = (*it); SPItem *item = SP_ITEM(mask_object->appendChildRepr(node)); diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 755d3d162..dd351a8d5 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -244,7 +244,7 @@ void SPPattern::update(SPCtx *ctx, unsigned int flags) std::list l; _getChildren(l); - for (SPObjectIterator it = l.begin(); it != l.end(); it++) { + for (SPObjectIterator it = l.begin(); it != l.end(); ++it) { SPObject *child = *it; sp_object_ref(child, NULL); @@ -270,7 +270,7 @@ void SPPattern::modified(unsigned int flags) std::list l; _getChildren(l); - for (SPObjectIterator it = l.begin(); it != l.end(); it++) { + for (SPObjectIterator it = l.begin(); it != l.end(); ++it) { SPObject *child = *it; sp_object_ref(child, NULL); @@ -398,7 +398,7 @@ const gchar *SPPattern::produce(const std::vector &reprs, const gchar *pat_id = repr->attribute("id"); SPObject *pat_object = document->getObjectById(pat_id); - for (NodePtrIterator i = reprs.begin(); i != reprs.end(); i++) { + for (NodePtrIterator i = reprs.begin(); i != reprs.end(); ++i) { Inkscape::XML::Node *node = *i; SPItem *copy = SP_ITEM(pat_object->appendChildRepr(node)); 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 used; std::vector itemlist=sel->itemList(); - for(std::vector::const_iterator i=itemlist.begin(); itemlist.end() != i; i++) { + for(std::vector::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 itemlist=sel->itemList(); - for(std::vector::const_iterator i=itemlist.begin(); itemlist.end() != i; i++) { + for(std::vector::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 x,y; std::vector all = get_all_items(x, _desktop->currentRoot(), _desktop, false, false, true, y); - for(std::vector::const_iterator i=all.begin(); all.end() != i; i++) { + for(std::vector::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 Find::filter_fields (std::vector &l, bool exact, b std::vector out; if (check_searchin_text.get_active()) { - for(std::vector::const_reverse_iterator i=in.rbegin(); in.rend() != i; i++) { + for(std::vector::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) { SPObject *obj = *i; SPItem *item = dynamic_cast(obj); g_assert(item != NULL); @@ -584,7 +584,7 @@ std::vector Find::filter_fields (std::vector &l, bool exact, b bool attrvalue = check_attributevalue.get_active(); if (ids) { - for(std::vector::const_reverse_iterator i=in.rbegin(); in.rend() != i; i++) { + for(std::vector::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) { SPObject *obj = *i; SPItem *item = dynamic_cast(obj); if (item_id_match(item, text, exact, casematch)) { @@ -600,7 +600,7 @@ std::vector Find::filter_fields (std::vector &l, bool exact, b if (style) { - for(std::vector::const_reverse_iterator i=in.rbegin(); in.rend() != i; i++) { + for(std::vector::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) { SPObject *obj = *i; SPItem *item = dynamic_cast(obj); g_assert(item != NULL); @@ -617,7 +617,7 @@ std::vector Find::filter_fields (std::vector &l, bool exact, b if (attrname) { - for(std::vector::const_reverse_iterator i=in.rbegin(); in.rend() != i; i++) { + for(std::vector::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) { SPObject *obj = *i; SPItem *item = dynamic_cast(obj); g_assert(item != NULL); @@ -634,7 +634,7 @@ std::vector Find::filter_fields (std::vector &l, bool exact, b if (attrvalue) { - for(std::vector::const_reverse_iterator i=in.rbegin(); in.rend() != i; i++) { + for(std::vector::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) { SPObject *obj = *i; SPItem *item = dynamic_cast(obj); g_assert(item != NULL); @@ -651,7 +651,7 @@ std::vector Find::filter_fields (std::vector &l, bool exact, b if (font) { - for(std::vector::const_reverse_iterator i=in.rbegin(); in.rend() != i; i++) { + for(std::vector::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) { SPObject *obj = *i; SPItem *item = dynamic_cast(obj); g_assert(item != NULL); @@ -718,7 +718,7 @@ bool Find::item_type_match (SPItem *item) std::vector Find::filter_types (std::vector &l) { std::vector n; - for(std::vector::const_reverse_iterator i=l.rbegin(); l.rend() != i; i++) { + for(std::vector::const_reverse_iterator i=l.rbegin(); l.rend() != i; ++i) { SPObject *obj = *i; SPItem *item = dynamic_cast(obj); g_assert(item != NULL); @@ -762,7 +762,7 @@ std::vector &Find::all_items (SPObject *r, std::vector &l, boo std::vector &Find::all_selection_items (Inkscape::Selection *s, std::vector &l, SPObject *ancestor, bool hidden, bool locked) { std::vector itemlist=s->itemList(); - for(std::vector::const_reverse_iterator i=itemlist.rbegin(); itemlist.rend() != i; i++) { + for(std::vector::const_reverse_iterator i=itemlist.rbegin(); itemlist.rend() != i; ++i) { SPObject *obj = *i; SPItem *item = dynamic_cast(obj); g_assert(item != NULL); 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 items = selection ? selection->itemList() : std::vector(); - for(std::vector::const_iterator i = items.begin();i!=items.end();i++){ + for(std::vector::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 sizes(sorted); - for (std::vector::const_iterator i = sizes.begin();i!=sizes.end();i++) { + for (std::vector::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::iterator it = sorted.begin(); - for (row_cnt=0; ((it != sorted.end()) && (row_cntunselect_all(); SPItem *item = NULL; std::vector const items = sel->itemList(); - for(std::vector::const_iterator i=items.begin(); i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin(); i!=items.end(); ++i){ item = *i; if (setOpacity) { diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp index a93cebee8..5ec1285c1 100644 --- a/src/ui/dialog/polar-arrange-tab.cpp +++ b/src/ui/dialog/polar-arrange-tab.cpp @@ -373,7 +373,7 @@ void PolarArrangeTab::arrange() Geom::Point realCenter = Geom::Point(cx, cy) * transformation; int i = 0; - for(std::vector::const_iterator it=tmp.begin();it!=tmp.end();it++) + for(std::vector::const_iterator it=tmp.begin();it!=tmp.end(); ++it) { SPItem *item = *it; 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 l = selection->itemList(); - for(std::vector::const_iterator i=l.begin();i!=l.end();i++) { + for(std::vector::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/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 items=selection->itemList(); - for (std::vector::const_iterator i = items.begin();i!=items.end();i++) { + for (std::vector::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 itemlist = selection->itemList(); - for (std::vector::const_iterator i = itemlist.begin();i!=itemlist.end();i++) { + for (std::vector::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/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 0d3405dbd..e9b319bbb 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -999,7 +999,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, int i=1; std::vector items=selection->itemList(); - for(std::vector::const_iterator it=items.begin();it!=items.end();it++){ + for(std::vector::const_iterator it=items.begin();it!=items.end(); ++it){ SPItem *item1 = *it; if (i == 1) { parent_item = item1; @@ -1168,13 +1168,13 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point { std::vector const items(selection->itemList()); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end(); ++i){ SPItem *item = *i; g_assert(item != NULL); sp_object_ref(item); } - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end(); ++i){ SPItem *item = *i; g_assert(item != NULL); if (sp_spray_recursive(desktop @@ -1218,7 +1218,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point } } - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end(); ++i){ SPItem *item = *i; g_assert(item != NULL); sp_object_unref(item); 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 items=selection->itemList(); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end(); ++i){ SPItem *item = *i; if (is_color_mode (tc->mode)) { diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp index fa5eabab4..a57c891e5 100644 --- a/src/widgets/fill-style.cpp +++ b/src/widgets/fill-style.cpp @@ -570,7 +570,7 @@ void FillNStroke::updateFromPaint() } } - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end(); ++i){ //FIXME: see above if (kind == FILL) { sp_repr_css_change_recursive((*i)->getRepr(), css, "style"); @@ -596,7 +596,7 @@ void FillNStroke::updateFromPaint() // We have changed from another gradient type, or modified spread/units within // this gradient type. vector = sp_gradient_ensure_vector_normalized(vector); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end(); ++i){ //FIXME: see above if (kind == FILL) { sp_repr_css_change_recursive((*i)->getRepr(), css, "style"); @@ -642,7 +642,7 @@ void FillNStroke::updateFromPaint() // cannot just call sp_desktop_set_style, because we don't want to touch those // objects who already have the same root pattern but through a different href // chain. FIXME: move this to a sp_item_set_pattern - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end(); ++i){ Inkscape::XML::Node *selrepr = (*i)->getRepr(); if ( (kind == STROKE) && !selrepr) { continue; diff --git a/src/widgets/spiral-toolbar.cpp b/src/widgets/spiral-toolbar.cpp index 751a60f06..7e7398091 100644 --- a/src/widgets/spiral-toolbar.cpp +++ b/src/widgets/spiral-toolbar.cpp @@ -80,7 +80,7 @@ static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustr bool modmade = false; std::vector itemlist=desktop->getSelection()->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ SPItem *item = *i; if (SP_IS_SPIRAL(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -196,7 +196,7 @@ static void sp_spiral_toolbox_selection_changed(Inkscape::Selection *selection, purge_repr_listener( tbl, tbl ); std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ SPItem *item = *i; if (SP_IS_SPIRAL(item)) { n_selected++; -- cgit v1.2.3 From 15a2f231bec816e134b98ca4de248be499225132 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Fri, 13 Nov 2015 18:54:23 +0100 Subject: static code analysis (bzr r14464) --- src/persp3d.cpp | 8 ++++---- src/sp-mask.h | 8 ++++---- src/widgets/text-toolbar.cpp | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/persp3d.cpp b/src/persp3d.cpp index dc0975d12..a48481145 100644 --- a/src/persp3d.cpp +++ b/src/persp3d.cpp @@ -36,10 +36,10 @@ static int global_counter = 0; /* Constructor/destructor for the internal class */ -Persp3DImpl::Persp3DImpl() { - tmat = Proj::TransfMat3x4 (); - document = NULL; - +Persp3DImpl::Persp3DImpl() : + tmat (Proj::TransfMat3x4 ()), + document (NULL) +{ my_counter = global_counter++; } diff --git a/src/sp-mask.h b/src/sp-mask.h index 74bd4d66e..19786b1fd 100644 --- a/src/sp-mask.h +++ b/src/sp-mask.h @@ -86,10 +86,10 @@ protected: Inkscape::XML::Node * const owner_repr = owner->getRepr(); //XML Tree being used directly here while it shouldn't be... Inkscape::XML::Node * const obj_repr = obj->getRepr(); - char const * owner_name = NULL; - char const * owner_mask = NULL; - char const * obj_name = NULL; - char const * obj_id = NULL; + char const * owner_name = ""; + char const * owner_mask = ""; + char const * obj_name = ""; + char const * obj_id = ""; if (owner_repr != NULL) { owner_name = owner_repr->name(); owner_mask = owner_repr->attribute("mask"); diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 7b22e4af7..c49fbccaa 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -155,7 +155,7 @@ static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GOb act->active = 0; // New family is always at top of list. } - std::pair ui = fontlister->set_font_family( act->active ); + fontlister->set_font_family( act->active ); // active text set in sp_text_toolbox_selection_changed() SPCSSAttr *css = sp_repr_css_attr_new (); @@ -373,7 +373,7 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) // move the x of all texts to preserve the same bbox Inkscape::Selection *selection = desktop->getSelection(); std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT(*i)) { SPItem *item = *i; @@ -526,7 +526,7 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) Inkscape::Selection *selection = desktop->getSelection(); bool modmade = false; std::vector itemlist=selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT (*i)) { (*i)->getRepr()->setAttribute("sodipodi:linespacing", sp_repr_css_property (css, "line-height", NULL)); modmade = true; @@ -871,7 +871,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Find out if we have flowed text now so we can use it several places gboolean isFlow = false; std::vector itemlist=SP_ACTIVE_DESKTOP->getSelection()->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ // const gchar* id = reinterpret_cast(items->data)->getId(); // std::cout << " " << id << std::endl; if( SP_IS_FLOWTEXT(*i)) { @@ -1165,7 +1165,7 @@ static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*p SPDocument *document = desktop->getDocument(); std::vector x,y; std::vector allList = get_all_items(x, document->getRoot(), desktop, false, false, true, y); - for(std::vector::const_reverse_iterator i=allList.rbegin();i!=allList.rend();i++){ + for(std::vector::const_reverse_iterator i=allList.rbegin();i!=allList.rend(); ++i){ SPItem *item = *i; SPStyle *style = item->style; -- cgit v1.2.3 From b833d034eeaa8bc144f6bdb2edd300056ed67b34 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 13 Nov 2015 19:29:13 +0100 Subject: Fix a compile problem (bzr r14422.3.7) --- src/live_effects/lpe-roughen.cpp | 46 ---------------------------------------- 1 file changed, 46 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 6b18cf14e..2be3bae31 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -98,56 +98,10 @@ LPERoughen::~LPERoughen() {} void LPERoughen::doOnApply(SPLPEItem const* lpeitem) { - SPLPEItem* item = const_cast(lpeitem); //calculamos el tamaƱo mas optimo para el roughen en función del nĆŗmero de nodos y la distancia del trazado } -static void -sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) -{ - std::vector const item_list = sp_item_group_item_list(group); - - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { - SPObject *subitem = *iter; - - SPGroup *subGroup = dynamic_cast(subitem); - if (subGroup) { - sp_group_perform_patheffect(subGroup, topgroup, write); - } else { - SPShape *subShape = dynamic_cast(subitem); - if (subShape) { - SPCurve * c = NULL; - - SPPath *subPath = dynamic_cast(subShape); - if (subPath) { - c = subPath->get_original_curve(); - } else { - c = subShape->getCurve(); - } - - // only run LPEs when the shape has a curve defined - if (c) { - c->transform(i2anc_affine(subitem, topgroup)); - topgroup->performPathEffect(c); - c->transform(i2anc_affine(subitem, topgroup).inverse()); - subShape->setCurve(c, TRUE); - if (write) { - Inkscape::XML::Node *repr = subitem->getRepr(); - gchar *str = sp_svg_write_path(c->get_pathvector()); - repr->setAttribute("d", str); -#ifdef GROUP_VERBOSE - g_message("sp_group_perform_patheffect writes 'd' attribute"); -#endif - g_free(str); - } - - c->unref(); - } - } - } - } -} void LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem) { -- cgit v1.2.3 From b07fe706e7b9f583c21af31e841373fadf1d6a82 Mon Sep 17 00:00:00 2001 From: Alexandre Prokoudine Date: Sat, 14 Nov 2015 13:48:27 +0300 Subject: Some sane defaults for spray offset, subject to further tweaking (bzr r14467) --- src/widgets/spray-toolbar.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index db1f9526a..1774ba418 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -594,13 +594,15 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Offset */ { + gchar const* labels[] = {_("(minimum offset)"), 0, 0, 0, _("(default)"), 0, 0, _("(maximum offset)")}; + gdouble values[] = {0, 25, 50, 75, 100, 150, 200, 1000}; EgeAdjustmentAction *eact = create_adjustment_action( "SprayToolOffsetAction", _("Offset %"), _("Offset %:"), _("Increase to segregate objects more (value in percent)"), "/tools/spray/offset", 100, GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0, 10000, 1, 4, - 0, 0, 0, + 0, 1000, 1, 4, + labels, values, G_N_ELEMENTS(labels), sp_spray_offset_value_changed, NULL, 0 , 0); g_object_set_data( holder, "offset", eact ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); -- cgit v1.2.3 From d8637ea8e848bd9727c14c584c59a9f61d1930c8 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 14 Nov 2015 14:17:29 +0100 Subject: Fix erase mode in no overlap mode, pointed by Ivan Louette (bzr r14469) --- src/ui/tools/spray-tool.cpp | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index e9b319bbb..7de2a0b04 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -559,21 +559,27 @@ static bool fit_item(SPDesktop *desktop, if (!rect_sprayed.hasZeroArea()) { rgba2 = getPickerData(rect_sprayed.roundOutwards()); } - if(pick_no_overlap){ - if(rgba != rgba2){ - return false; + if(pick_no_overlap) { + if(rgba != rgba2) { + if(mode != SPRAY_MODE_ERASER) { + return false; + } } } - if(!pick_center){ + if(!pick_center) { rgba = rgba2; } - if(!over_transparent && (SP_RGBA32_A_F(rgba) == 0 || SP_RGBA32_A_F(rgba) < 1e-6)){ - return false; + 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){ - return false; + if(!over_no_transparent && SP_RGBA32_A_F(rgba) > 0) { + if(mode != SPRAY_MODE_ERASER) { + return false; + } } - if(offset < 100 ){ + 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 { @@ -608,13 +614,13 @@ static bool fit_item(SPDesktop *desktop, (item_down->getAttribute("inkscape:spray-origin") && strcmp(item_down->getAttribute("inkscape:spray-origin"),spray_origin) == 0 )) { - if(mode == SPRAY_MODE_ERASER){ + 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){ + } 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)){ @@ -622,7 +628,7 @@ static bool fit_item(SPDesktop *desktop, } return false; } - } else if(picker || over_transparent || over_no_transparent){ + } else if(picker || over_transparent || over_no_transparent) { item_down->setHidden(true); item_down->updateRepr(); } -- cgit v1.2.3 From 151126ef45cb00bab461181388a433e751a27bc3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 14 Nov 2015 18:32:14 +0100 Subject: adding default width (bzr r14422.3.8) --- src/live_effects/lpe-roughen.cpp | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 2be3bae31..87046ef4a 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -20,6 +20,7 @@ #include "live_effects/parameter/parameter.h" #include #include "helper/geom.h" +#include "sp-item-group.h" #include #include @@ -42,6 +43,35 @@ static const Util::EnumData HandlesMethodData[HM_END] = { static const Util::EnumDataConverter HMConverter(HandlesMethodData, HM_END); +static void +sp_get_better_default_size(SPItem *item, double &value) +{ + if (SP_IS_GROUP(item)) { + std::vector const item_list = sp_item_group_item_list(SP_GROUP(item)); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { + SPItem *subitem = *iter; + value += sp_get_better_default_size(subitem, value); + } + if(item_list.size() > 0){ + value /= item_list.size(); + } + } else { + SPShape *shape = dynamic_cast(item); + if (shape) { + SPCurve * c = NULL; + SPPath *path = dynamic_cast(shape); + if (path) { + c = path->get_original_curve(); + } else { + c = shape->getCurve(); + } + if (c) { + value = Geom::length(paths_to_pw(c->get_pathvector()))/(c->get_segment_count () * 3); + } + } + } +} + LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) : Effect(lpeobject), // initialise your parameters here: @@ -98,11 +128,13 @@ LPERoughen::~LPERoughen() {} void LPERoughen::doOnApply(SPLPEItem const* lpeitem) { - //calculamos el tamaƱo mas optimo para el roughen en función del nĆŗmero de nodos y la distancia del trazado + SPLPEItem * splpeitem = const_cast(lpeitem); + double initial = 0; + sp_get_better_default_size(SP_ITEM(splpeitem), initial); + displace_x.param_set_value(initial, displace_x.defseed); + displace_y.param_set_value(initial, displace_y.defseed); } - - void LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem) { if(spray_tool_friendly && seed == 0 && SP_OBJECT(lpeitem)->getId()){ -- cgit v1.2.3 From 7c89ed9dc03fb5f83eac25823c54edd91c123f7f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 14 Nov 2015 19:21:59 +0100 Subject: Fixing compile problem (bzr r14422.3.10) --- src/live_effects/lpe-roughen.cpp | 58 ++++++++++++++++++------------------- src/live_effects/parameter/random.h | 2 +- 2 files changed, 30 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 87046ef4a..0d0debd24 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -43,35 +43,6 @@ static const Util::EnumData HandlesMethodData[HM_END] = { static const Util::EnumDataConverter HMConverter(HandlesMethodData, HM_END); -static void -sp_get_better_default_size(SPItem *item, double &value) -{ - if (SP_IS_GROUP(item)) { - std::vector const item_list = sp_item_group_item_list(SP_GROUP(item)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { - SPItem *subitem = *iter; - value += sp_get_better_default_size(subitem, value); - } - if(item_list.size() > 0){ - value /= item_list.size(); - } - } else { - SPShape *shape = dynamic_cast(item); - if (shape) { - SPCurve * c = NULL; - SPPath *path = dynamic_cast(shape); - if (path) { - c = path->get_original_curve(); - } else { - c = shape->getCurve(); - } - if (c) { - value = Geom::length(paths_to_pw(c->get_pathvector()))/(c->get_segment_count () * 3); - } - } - } -} - LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) : Effect(lpeobject), // initialise your parameters here: @@ -126,6 +97,35 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) LPERoughen::~LPERoughen() {} +static void +sp_get_better_default_size(SPItem *item, double &value) +{ + if (SP_IS_GROUP(item)) { + std::vector const item_list = sp_item_group_item_list(SP_GROUP(item)); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { + SPItem *subitem = *iter; + sp_get_better_default_size(subitem, value); + } + if(item_list.size() > 0){ + value /= item_list.size(); + } + } else { + SPShape *shape = dynamic_cast(item); + if (shape) { + SPCurve * c = NULL; + SPPath *path = dynamic_cast(shape); + if (path) { + c = path->get_original_curve(); + } else { + c = shape->getCurve(); + } + if (c) { + value += Geom::length(paths_to_pw(c->get_pathvector()))/(c->get_segment_count () * 3); + } + } + } +} + void LPERoughen::doOnApply(SPLPEItem const* lpeitem) { SPLPEItem * splpeitem = const_cast(lpeitem); diff --git a/src/live_effects/parameter/random.h b/src/live_effects/parameter/random.h index ca4440336..52e3cc0a6 100644 --- a/src/live_effects/parameter/random.h +++ b/src/live_effects/parameter/random.h @@ -43,11 +43,11 @@ public: operator gdouble(); inline gdouble get_value() { return value; } ; + long defseed; protected: long startseed; long seed; - long defseed; gdouble value; gdouble min; -- cgit v1.2.3 From 43a821aaa9b8749b9c373925c8334efa77d9c34e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 15 Nov 2015 02:20:30 +0100 Subject: max_smooth_angle working, now deleted after because dont think a good improvement in realtion of UX complication (bzr r14422.3.11) --- src/live_effects/lpe-roughen.cpp | 224 ++++++++++++++++++++------------------- 1 file changed, 117 insertions(+), 107 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 0d0debd24..5253c0b85 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -120,7 +120,7 @@ sp_get_better_default_size(SPItem *item, double &value) c = shape->getCurve(); } if (c) { - value += Geom::length(paths_to_pw(c->get_pathvector()))/(c->get_segment_count () * 3); + value += Geom::length(paths_to_pw(c->get_pathvector()))/(c->get_segment_count () * 6); } } } @@ -240,10 +240,11 @@ Geom::Point LPERoughen::randomize(double max_lenght, bool is_node) Geom::Point LPERoughen::randomize(double lenght, Geom::Point start, Geom::Point end) { - int angle = 0; + double angle = 0; if((int)max_smooth_angle != 0){ angle = sign(Geom::deg_to_rad(rand() % (int)max_smooth_angle)); } + std::cout << angle << "anggggle\n"; Geom::Ray ray(start, end); if(!fixed_displacement ){ lenght = Geom::distance(start, end); @@ -283,10 +284,11 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::CubicBezier const *cubic = NULL; cubic = dynamic_cast(&*curve_it1); if (cubic) { - nCurve->curveto((*cubic)[1], (*cubic)[2], curve_it1->finalPoint()); + nCurve->curveto((*cubic)[1] + last_move, (*cubic)[2], curve_it1->finalPoint()); } else { nCurve->lineto(curve_it1->finalPoint()); } + last_move = Geom::Point(0, 0); double length = curve_it1->length(0.001); std::size_t splits = 0; if (method == DM_SEGMENTS) { @@ -396,7 +398,68 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point point_b2 = point_b3; } } - if(handles == HM_RETRACT){ + if(handles == HM_SMOOTH){ + if(cubic) { + std::pair div = cubic->subdivide(t); + std::vector seg1 = div.first.controlPoints(), + seg2 = div.second.controlPoints(); + point_b1 = randomize(max_lenght, seg1[3] + point_a3, seg2[1] + point_a3); + point_b2 = seg2[2]; + point_b3 = seg2[3] + point_b3; + point_a3 = seg1[3] + point_a3; + Geom::Ray ray(prev,A->initialPoint()); + point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); + if(prev == Geom::Point(0,0)){ + point_a1 = randomize(max_lenght); + } + if(last){ + Geom::Path b2(point_b3); + b2.appendNew(point_a3); + double dist = Geom::distance(b2.pointAt(1.0/3.0), point_b3); + ray.setPoints(point_b3, b2.pointAt(1.0/3.0)); + point_b2 = point_b3 + Geom::Point::polar(ray.angle(), dist); + point_b2 = randomize(max_lenght, point_b3, point_b2); + } + ray.setPoints(point_b1, point_a3); + point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); + if(last){ + prev = point_b2; + } else { + prev = point_a2; + } + out->moveto(seg1[0]); + out->curveto(point_a1,point_a2,point_a3); + out->curveto(point_b1, point_b2, point_b3); + } else { + point_b1 = randomize(max_lenght, A->pointAt(t) + point_a3, A->pointAt(t + (t / 3))); + point_b2 = A->pointAt(t +((t / 3) * 2)); + point_b3 = A->finalPoint() + point_b3; + point_a3 = A->pointAt(t) + point_a3; + Geom::Ray ray(prev,A->initialPoint()); + point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); + if(prev == Geom::Point(0,0)){ + point_a1 = randomize(max_lenght); + } + if(last){ + Geom::Path b2(point_b3); + b2.appendNew(point_a3); + double dist = Geom::distance(b2.pointAt(1.0/3.0), point_b3); + ray.setPoints(point_b3, b2.pointAt(1.0/3.0)); + point_b2 = point_b3 + Geom::Point::polar(ray.angle(), dist); + point_b2 = randomize(max_lenght, point_b3, point_b2); + } + ray.setPoints(point_b1, point_a3); + point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); + if(last){ + prev = point_b2; + } else { + prev = point_a2; + } + out->moveto(A->initialPoint()); + out->curveto(point_a1,point_a2,point_a3); + out->curveto(point_b1, point_b2, point_b3); + } + } else if(handles == HM_RETRACT){ out->moveto(A->initialPoint()); out->lineto(A->pointAt(t) + point_a3); if(cubic && !last){ @@ -406,71 +469,12 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point } else { out->lineto(A->finalPoint() + point_b3); } - } else if(handles == HM_SMOOTH && cubic) { - std::pair div = cubic->subdivide(t); - std::vector seg1 = div.first.controlPoints(), - seg2 = div.second.controlPoints(); - point_b1 = randomize(max_lenght, seg1[3] + point_a3, seg2[1] + point_a3); - point_b2 = seg2[2]; - point_b3 = seg2[3] + point_b3; - point_a3 = seg1[3] + point_a3; - Geom::Ray ray(prev,A->initialPoint()); - point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); - if(prev == Geom::Point(0,0)){ - point_a1 = randomize(max_lenght); - } - if(last){ - Geom::Path b2(point_b3); - b2.appendNew(point_a3); - double dist = Geom::distance(b2.pointAt(1.0/3.0), point_b3); - ray.setPoints(point_b3, b2.pointAt(1.0/3.0)); - point_b2 = point_b3 + Geom::Point::polar(ray.angle(), dist); - point_b2 = randomize(max_lenght, point_b3, point_b2); - } - ray.setPoints(point_b1, point_a3); - point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); - if(last){ - prev = point_b2; - } else { - prev = point_a2; - } - out->moveto(seg1[0]); - out->curveto(point_a1,point_a2,point_a3); - out->curveto(point_b1, point_b2, point_b3); - } else if(handles == HM_SMOOTH && !cubic) { - point_b1 = randomize(max_lenght, A->pointAt(t) + point_a3, A->pointAt(t + (t / 3))); - point_b2 = A->pointAt(t +((t / 3) * 2)); - point_b3 = A->finalPoint() + point_b3; - point_a3 = A->pointAt(t) + point_a3; - Geom::Ray ray(prev,A->initialPoint()); - point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); - if(prev == Geom::Point(0,0)){ - point_a1 = randomize(max_lenght); - } - if(last){ - Geom::Path b2(point_b3); - b2.appendNew(point_a3); - double dist = Geom::distance(b2.pointAt(1.0/3.0), point_b3); - ray.setPoints(point_b3, b2.pointAt(1.0/3.0)); - point_b2 = point_b3 + Geom::Point::polar(ray.angle(), dist); - point_b2 = randomize(max_lenght, point_b3, point_b2); - } - ray.setPoints(point_b1, point_a3); - point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); - if(last){ - prev = point_b2; - } else { - prev = point_a2; - } - out->moveto(A->initialPoint()); - out->curveto(point_a1,point_a2,point_a3); - out->curveto(point_b1, point_b2, point_b3); - } else if (cubic) { - std::pair div = cubic->subdivide(t); - std::vector seg1 = div.first.controlPoints(), - seg2 = div.second.controlPoints(); - out->moveto(seg1[0]); - if(handles == HM_ALONG_NODES){ + } else if(handles == HM_ALONG_NODES){ + if (cubic) { + std::pair div = cubic->subdivide(t); + std::vector seg1 = div.first.controlPoints(), + seg2 = div.second.controlPoints(); + out->moveto(seg1[0]); out->curveto(seg1[1] + last_move, seg1[2] + point_a3, seg1[3] + point_a3); last_move = point_a3; if(last){ @@ -478,17 +482,23 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point } out->curveto(seg2[1] + point_a3, seg2[2] + point_b3, seg2[3] + point_b3); } else { + out->moveto(A->initialPoint()); + out->lineto(A->pointAt(t) + point_a3); + out->lineto(A->finalPoint() + point_b3); + } + } else if(handles == HM_RAND) { + if (cubic) { + std::pair div = cubic->subdivide(t); + std::vector seg1 = div.first.controlPoints(), + seg2 = div.second.controlPoints(); + out->moveto(seg1[0]); out->curveto(seg1[1] + point_a1, seg1[2] + point_a2 + point_a3, seg1[3] + point_a3); out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); + } else { + out->moveto(A->initialPoint()); + out->lineto(A->pointAt(t) + point_a3); + out->lineto(A->finalPoint() + point_b3); } - } else if (handles == HM_RAND) { - out->moveto(A->initialPoint()); - out->curveto(A->pointAt(t / 3) + point_a1, A->pointAt((t / 3) * 2) + point_a2 + point_a3, A->pointAt(t) + point_a3); - out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); - } else { - out->moveto(A->initialPoint()); - out->lineto(A->pointAt(t) + point_a3); - out->lineto(A->finalPoint() + point_b3); } return out; } @@ -508,46 +518,46 @@ SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev, Geom::Poin point_a1 = randomize(max_lenght); point_a2 = randomize(max_lenght); } - if(handles == HM_RETRACT){ - out->moveto(A->initialPoint()); - out->lineto(A->finalPoint() + point_a3); - } else if(handles == HM_SMOOTH && cubic) { - Geom::Ray ray(prev,A->initialPoint()); - point_a1 = Geom::Point::polar(ray.angle(), max_lenght); - if(prev == Geom::Point(0,0)){ - point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); - } - ray.setPoints((*cubic)[3] + point_a3, (*cubic)[2] + point_a3); - point_a2 = randomize(max_lenght, ray.angle()); - prev = (*cubic)[2] + point_a2; - out->moveto((*cubic)[0]); - out->curveto((*cubic)[0] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); - } else if(handles == HM_SMOOTH && !cubic) { - Geom::Ray ray(prev,A->initialPoint()); - point_a1 = Geom::Point::polar(ray.angle(), max_lenght); - if(prev==Geom::Point(0,0)){ - point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); + if(handles == HM_SMOOTH) { + if (cubic) { + Geom::Ray ray(prev,A->initialPoint()); + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + if(prev == Geom::Point(0,0)){ + point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); + } + ray.setPoints((*cubic)[3] + point_a3, (*cubic)[2] + point_a3); + point_a2 = randomize(max_lenght, ray.angle()); + prev = (*cubic)[2] + point_a2; + out->moveto((*cubic)[0]); + out->curveto((*cubic)[0] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); + } else { + Geom::Ray ray(prev,A->initialPoint()); + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + if(prev==Geom::Point(0,0)){ + point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); + } + ray.setPoints(A->finalPoint() + point_a3, A->pointAt((1.0/3.0) * 2) + point_a3); + point_a2 = randomize(max_lenght, ray.angle()); + prev = A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3; + out->moveto(A->initialPoint()); + out->curveto(A->initialPoint() + point_a1, A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3, A->finalPoint() + point_a3); } - ray.setPoints(A->finalPoint() + point_a3, A->pointAt((1.0/3.0) * 2) + point_a3); - point_a2 = randomize(max_lenght, ray.angle()); - prev = A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3; + } else if(handles == HM_RETRACT){ out->moveto(A->initialPoint()); - out->curveto(A->initialPoint() + point_a1, A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3, A->finalPoint() + point_a3); - } else if (cubic) { - out->moveto((*cubic)[0]); - if(handles == HM_ALONG_NODES){ + out->lineto(A->finalPoint() + point_a3); + } else if (handles == HM_ALONG_NODES) { + if(cubic){ + out->moveto((*cubic)[0]); out->curveto((*cubic)[1] + last_move, (*cubic)[2] + point_a3, (*cubic)[3] + point_a3); last_move = point_a3; } else { - out->curveto((*cubic)[1] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); + out->moveto(A->initialPoint()); + out->lineto(A->finalPoint() + point_a3); } } else if (handles == HM_RAND) { out->moveto(A->initialPoint()); out->curveto(A->pointAt(0.3333) + point_a1, A->pointAt(0.6666) + point_a2 + point_a3, A->finalPoint() + point_a3); - } else { - out->moveto(A->initialPoint()); - out->lineto(A->finalPoint() + point_a3); } return out; } -- cgit v1.2.3 From 3a2f830fc5c0c0f3901e64277e6871b9615d283b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 15 Nov 2015 03:47:20 +0100 Subject: End fixing roughen (bzr r14422.3.12) --- src/live_effects/lpe-roughen.cpp | 64 +++++++++++++++++-------------------- src/live_effects/lpe-roughen.h | 2 -- src/live_effects/parameter/random.h | 2 +- 3 files changed, 30 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 5253c0b85..310f791a1 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -60,8 +60,6 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) "global_randomize", &wr, this, 1.), handles(_("Handles"), _("Handles options"), "handles", HMConverter, &wr, this, HM_ALONG_NODES), - max_smooth_angle(_("Max. smooth handle angle"), _("Max. smooth handle angle"), - "max_smooth_angle", &wr, this, 20), shift_nodes(_("Shift nodes"), _("Shift nodes"), "shift_nodes", &wr, this, true), fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment length"), @@ -76,7 +74,6 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) registerParameter(&displace_y); registerParameter(&global_randomize); registerParameter(&handles); - registerParameter(&max_smooth_angle); registerParameter(&shift_nodes); registerParameter(&fixed_displacement); registerParameter(&spray_tool_friendly); @@ -89,9 +86,6 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) segments.param_set_range(1, Geom::infinity()); segments.param_set_increments(1, 1); segments.param_set_digits(0); - max_smooth_angle.param_set_range(0, 359); - max_smooth_angle.param_set_increments(1, 1); - max_smooth_angle.param_set_digits(0); seed = 0; } @@ -131,8 +125,8 @@ void LPERoughen::doOnApply(SPLPEItem const* lpeitem) SPLPEItem * splpeitem = const_cast(lpeitem); double initial = 0; sp_get_better_default_size(SP_ITEM(splpeitem), initial); - displace_x.param_set_value(initial, displace_x.defseed); - displace_y.param_set_value(initial, displace_y.defseed); + displace_x.param_set_value(initial, 0); + displace_y.param_set_value(initial, 0); } void LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem) @@ -238,20 +232,6 @@ Geom::Point LPERoughen::randomize(double max_lenght, bool is_node) return output; } -Geom::Point LPERoughen::randomize(double lenght, Geom::Point start, Geom::Point end) -{ - double angle = 0; - if((int)max_smooth_angle != 0){ - angle = sign(Geom::deg_to_rad(rand() % (int)max_smooth_angle)); - } - std::cout << angle << "anggggle\n"; - Geom::Ray ray(start, end); - if(!fixed_displacement ){ - lenght = Geom::distance(start, end); - } - return Geom::Point::polar(ray.angle() + angle , lenght) + start; -} - void LPERoughen::doEffect(SPCurve *curve) { Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); @@ -403,11 +383,16 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); - point_b1 = randomize(max_lenght, seg1[3] + point_a3, seg2[1] + point_a3); + Geom::Ray ray(seg1[3] + point_a3, seg2[1] + point_a3); + double lenght = max_lenght; + if(!fixed_displacement ){ + lenght = Geom::distance(seg1[3] + point_a3, seg2[1] + point_a3); + } + point_b1 = seg1[3] + point_a3 + Geom::Point::polar(ray.angle() , lenght); point_b2 = seg2[2]; point_b3 = seg2[3] + point_b3; point_a3 = seg1[3] + point_a3; - Geom::Ray ray(prev,A->initialPoint()); + ray.setPoints(prev,A->initialPoint()); point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); @@ -415,10 +400,12 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point if(last){ Geom::Path b2(point_b3); b2.appendNew(point_a3); - double dist = Geom::distance(b2.pointAt(1.0/3.0), point_b3); - ray.setPoints(point_b3, b2.pointAt(1.0/3.0)); - point_b2 = point_b3 + Geom::Point::polar(ray.angle(), dist); - point_b2 = randomize(max_lenght, point_b3, point_b2); + lenght = max_lenght; + ray.setPoints(point_b3, point_b2); + if(!fixed_displacement ){ + lenght = Geom::distance(b2.pointAt(1.0/3.0), point_b3); + } + point_b2 = point_b3 + Geom::Point::polar(ray.angle() , lenght); } ray.setPoints(point_b1, point_a3); point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); @@ -431,11 +418,16 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point out->curveto(point_a1,point_a2,point_a3); out->curveto(point_b1, point_b2, point_b3); } else { - point_b1 = randomize(max_lenght, A->pointAt(t) + point_a3, A->pointAt(t + (t / 3))); + Geom::Ray ray(A->pointAt(t) + point_a3, A->pointAt(t + (t / 3))); + double lenght = max_lenght; + if(!fixed_displacement ){ + lenght = Geom::distance(A->pointAt(t) + point_a3, A->pointAt(t + (t / 3))); + } + point_b1 = A->pointAt(t) + point_a3 + Geom::Point::polar(ray.angle() , lenght); point_b2 = A->pointAt(t +((t / 3) * 2)); point_b3 = A->finalPoint() + point_b3; point_a3 = A->pointAt(t) + point_a3; - Geom::Ray ray(prev,A->initialPoint()); + ray.setPoints(prev,A->initialPoint()); point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); @@ -443,10 +435,12 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point if(last){ Geom::Path b2(point_b3); b2.appendNew(point_a3); - double dist = Geom::distance(b2.pointAt(1.0/3.0), point_b3); - ray.setPoints(point_b3, b2.pointAt(1.0/3.0)); - point_b2 = point_b3 + Geom::Point::polar(ray.angle(), dist); - point_b2 = randomize(max_lenght, point_b3, point_b2); + lenght = max_lenght; + ray.setPoints(point_b3, point_b2); + if(!fixed_displacement ){ + lenght = Geom::distance(b2.pointAt(1.0/3.0), point_b3); + } + point_b2 = point_b3 + Geom::Point::polar(ray.angle() , lenght); } ray.setPoints(point_b1, point_a3); point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); @@ -512,7 +506,7 @@ SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev, Geom::Poin Geom::Point point_a2(0, 0); Geom::Point point_a3(0, 0); if (shift_nodes) { - point_a3 = randomize(max_lenght); + point_a3 = randomize(max_lenght, true); } if (handles == HM_RAND || handles == HM_SMOOTH) { point_a1 = randomize(max_lenght); diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index b12bd08af..7e6a19d5a 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -47,7 +47,6 @@ public: virtual double sign(double randNumber); virtual void doOnApply(SPLPEItem const* lpeitem); virtual Geom::Point randomize(double max_lenght, bool is_node = false); - virtual Geom::Point randomize(double lenght, Geom::Point start, Geom::Point end); virtual void doBeforeEffect(SPLPEItem const * lpeitem); virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move, double t, bool last); virtual SPCurve *jitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move); @@ -62,7 +61,6 @@ private: RandomParam displace_y; RandomParam global_randomize; EnumParam handles; - ScalarParam max_smooth_angle; BoolParam shift_nodes; BoolParam fixed_displacement; BoolParam spray_tool_friendly; diff --git a/src/live_effects/parameter/random.h b/src/live_effects/parameter/random.h index 52e3cc0a6..ca4440336 100644 --- a/src/live_effects/parameter/random.h +++ b/src/live_effects/parameter/random.h @@ -43,11 +43,11 @@ public: operator gdouble(); inline gdouble get_value() { return value; } ; - long defseed; protected: long startseed; long seed; + long defseed; gdouble value; gdouble min; -- cgit v1.2.3 From 9ccc911c0f27339694b7210d7f6829b528e96fe2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 15 Nov 2015 03:57:03 +0100 Subject: Fix a typo (bzr r14422.3.14) --- src/widgets/spray-toolbar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/spray-toolbar.h b/src/widgets/spray-toolbar.h index d1d5c7b4c..30d8233ca 100644 --- a/src/widgets/spray-toolbar.h +++ b/src/widgets/spray-toolbar.h @@ -21,7 +21,7 @@ * * Copyright (C) 2004 David Turner * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors + * Copyright (C) 1999-2015 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information -- cgit v1.2.3 From 2e52e187d8d3ef5cb99d2ab64c297969e5f0c931 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Mon, 16 Nov 2015 21:54:28 +0100 Subject: static code analysis (bzr r14474) --- src/ui/tools/spray-tool.cpp | 6 ++---- src/widgets/fill-style.cpp | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 7de2a0b04..71cad5c0d 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -593,16 +593,14 @@ static bool fit_item(SPDesktop *desktop, } std::vector const items_selected(selection->itemList()); std::vector items_down_erased; - for (std::vector::const_iterator i=items_down.begin(); i!=items_down.end(); i++) { + for (std::vector::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::const_iterator j=items_selected.begin(); j!=items_selected.end(); j++) { + for (std::vector::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")){ diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp index a57c891e5..a96776894 100644 --- a/src/widgets/fill-style.cpp +++ b/src/widgets/fill-style.cpp @@ -68,7 +68,7 @@ namespace Inkscape { class FillNStroke : public Gtk::VBox { public: - FillNStroke( FillOrStroke kind ); + FillNStroke( FillOrStroke k ); ~FillNStroke(); void setFillrule( SPPaintSelector::FillRule mode ); @@ -125,9 +125,9 @@ Gtk::Widget *Inkscape::Widgets::createStyleWidget( FillOrStroke kind ) return filler; } -FillNStroke::FillNStroke( FillOrStroke kind ) : +FillNStroke::FillNStroke( FillOrStroke k ) : Gtk::VBox(), - kind(kind), + kind(k), desktop(0), psel(0), lastDrag(0), -- cgit v1.2.3 From 71048dcd8efdf44f04dd7052081c564030bc042f Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Mon, 16 Nov 2015 23:03:08 +0100 Subject: null pointer dereference fix (bzr r14474.1.1) --- src/ui/interface.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 9a4e1d773..0f719b40f 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -846,13 +846,11 @@ static void sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, I #endif } } else if (menu_pntr->attribute("check") != NULL) { - SPAction *action = NULL; if (verb->get_code() != SP_VERB_NONE) { - action = verb->get_action(Inkscape::ActionContext(view)); - } - sp_ui_menu_append_check_item_from_verb(GTK_MENU(menu), view, action->name, action->tip, NULL, + SPAction *action = verb->get_action(Inkscape::ActionContext(view)); + sp_ui_menu_append_check_item_from_verb(GTK_MENU(menu), view, action->name, action->tip, NULL, checkitem_toggled, checkitem_update, verb); - + } } else { sp_ui_menu_append_item_from_verb(GTK_MENU(menu), verb, view); group = NULL; -- cgit v1.2.3 From 8bd87961810251cac534f8f308a4b91e5d21afe0 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Mon, 16 Nov 2015 23:57:28 +0100 Subject: removes warnings when compiling with c++11 using uniqueptr instead of autoptr (bzr r14475) --- src/2geom/curve.cpp | 4 ++++ src/2geom/elliptical-arc.cpp | 4 ++++ src/live_effects/lpe-interpolate_points.cpp | 5 ++++- src/ui/control-manager.h | 6 ++++-- src/ui/dialog/filter-effects-dialog.h | 8 ++++++++ 5 files changed, 24 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/2geom/curve.cpp b/src/2geom/curve.cpp index b45228514..24c8be9f8 100644 --- a/src/2geom/curve.cpp +++ b/src/2geom/curve.cpp @@ -108,7 +108,11 @@ std::vector Curve::intersectSelf(Coord eps) const // Monotonic segments cannot have self-intersections. // Thus, we can split the curve at roots and intersect the portions. std::vector splits; +#if __cplusplus <= 199711L std::auto_ptr deriv(derivative()); +#else + std::unique_ptr deriv(derivative()); +#endif splits = deriv->roots(0, X); if (splits.empty()) { return result; diff --git a/src/2geom/elliptical-arc.cpp b/src/2geom/elliptical-arc.cpp index 25a78b4ad..77d3d788d 100644 --- a/src/2geom/elliptical-arc.cpp +++ b/src/2geom/elliptical-arc.cpp @@ -354,7 +354,11 @@ EllipticalArc::pointAndDerivatives(Coord t, unsigned int n) const std::vector result; result.reserve(nn); double angle = angleAt(t); +#if __cplusplus <= 199711L std::auto_ptr ea( static_cast(duplicate()) ); +#else + std::unique_ptr ea( static_cast(duplicate()) ); +#endif ea->_ellipse.setCenter(0, 0); unsigned int m = std::min(nn, 4u); for ( unsigned int i = 0; i < m; ++i ) diff --git a/src/live_effects/lpe-interpolate_points.cpp b/src/live_effects/lpe-interpolate_points.cpp index 4ac139752..cf70832ee 100644 --- a/src/live_effects/lpe-interpolate_points.cpp +++ b/src/live_effects/lpe-interpolate_points.cpp @@ -52,8 +52,11 @@ Geom::PathVector LPEInterpolatePoints::doEffect_path (Geom::PathVector const & path_in) { Geom::PathVector path_out; - +#if __cplusplus <= 199711L std::auto_ptr interpolator( Geom::Interpolate::Interpolator::create(static_cast(interpolator_type.get_value())) ); +#else + std::unique_ptr interpolator( Geom::Interpolate::Interpolator::create(static_cast(interpolator_type.get_value())) ); +#endif for(Geom::PathVector::const_iterator path_it = path_in.begin(); path_it != path_in.end(); ++path_it) { if (path_it->empty()) diff --git a/src/ui/control-manager.h b/src/ui/control-manager.h index 05a53f6a0..964ad0a29 100644 --- a/src/ui/control-manager.h +++ b/src/ui/control-manager.h @@ -74,9 +74,11 @@ public: private: ControlManager(); - +#if __cplusplus <= 199711L std::auto_ptr _impl; - +#else + std::unique_ptr _impl; +#endif friend class ControlManagerImpl; }; diff --git a/src/ui/dialog/filter-effects-dialog.h b/src/ui/dialog/filter-effects-dialog.h index a067cd70c..283abb5b0 100644 --- a/src/ui/dialog/filter-effects-dialog.h +++ b/src/ui/dialog/filter-effects-dialog.h @@ -127,7 +127,11 @@ private: Gtk::Button _add; Glib::RefPtr _menu; sigc::signal _signal_filter_changed; +#if __cplusplus <= 199711L std::auto_ptr _observer; +#else + std::unique_ptr _observer; +#endif }; class PrimitiveColumns : public Gtk::TreeModel::ColumnRecord @@ -243,7 +247,11 @@ private: sigc::connection _scroll_connection; int _autoscroll_y; int _autoscroll_x; +#if __cplusplus <= 199711L std::auto_ptr _observer; +#else + std::unique_ptr _observer; +#endif int _input_type_width; int _input_type_height; }; -- cgit v1.2.3 From 97fd7f4c6b6532fd70149726c61c98605dda4067 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 18 Nov 2015 10:06:09 +0100 Subject: Read/write 'dominant-baseline' property. (bzr r14430.1.6) --- src/style-enums.h | 33 ++++++++++++++++++++++++++++++--- src/style.cpp | 9 ++++++--- src/style.h | 2 ++ 3 files changed, 38 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/style-enums.h b/src/style-enums.h index c9a558e0f..06207852c 100644 --- a/src/style-enums.h +++ b/src/style-enums.h @@ -191,10 +191,24 @@ enum SPWhiteSpace { SP_CSS_WHITE_SPACE_PRELINE }; +// Not complete list +enum SPCSSBaseline { + SP_CSS_BASELINE_AUTO, + SP_CSS_BASELINE_ALPHABETIC, + SP_CSS_BASELINE_IDEOGRAPHIC, + SP_CSS_BASELINE_HANGING, + SP_CSS_BASELINE_MATHEMATICAL, + SP_CSS_BASELINE_CENTRAL, + SP_CSS_BASELINE_MIDDLE, + SP_CSS_BASELINE_TEXT_BEFORE_EDGE, + SP_CSS_BASELINE_TEXT_AFTER_EDGE, + SP_CSS_BASELINE_SIZE // Size of enum, keep last. +}; + enum SPCSSBaselineShift { - SP_CSS_BASELINE_SHIFT_BASELINE, - SP_CSS_BASELINE_SHIFT_SUB, - SP_CSS_BASELINE_SHIFT_SUPER + SP_CSS_BASELINE_SHIFT_BASELINE, + SP_CSS_BASELINE_SHIFT_SUB, + SP_CSS_BASELINE_SHIFT_SUPER }; enum SPVisibility { @@ -520,6 +534,19 @@ static SPStyleEnum const enum_text_orientation[] = { {NULL, -1} }; +static SPStyleEnum const enum_baseline[] = { + {"auto", SP_CSS_BASELINE_AUTO}, // Default + {"alphabetic", SP_CSS_BASELINE_ALPHABETIC}, + {"ideographic", SP_CSS_BASELINE_IDEOGRAPHIC}, + {"hanging", SP_CSS_BASELINE_HANGING}, + {"mathematical", SP_CSS_BASELINE_MATHEMATICAL}, + {"central", SP_CSS_BASELINE_CENTRAL}, + {"middle", SP_CSS_BASELINE_MIDDLE}, + {"text-before-edge", SP_CSS_BASELINE_TEXT_BEFORE_EDGE}, + {"text-after-edge", SP_CSS_BASELINE_TEXT_AFTER_EDGE}, + {NULL, -1} +}; + static SPStyleEnum const enum_baseline_shift[] = { {"baseline", SP_CSS_BASELINE_SHIFT_BASELINE}, {"sub", SP_CSS_BASELINE_SHIFT_SUB}, diff --git a/src/style.cpp b/src/style.cpp index 369127792..0bad376a4 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -138,6 +138,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : direction( "direction", enum_direction, SP_CSS_DIRECTION_LTR ), writing_mode( "writing-mode", enum_writing_mode, SP_CSS_WRITING_MODE_LR_TB ), text_orientation( "text-orientation",enum_text_orientation,SP_CSS_TEXT_ORIENTATION_MIXED ), + dominant_baseline("dominant-baseline",enum_baseline, SP_CSS_BASELINE_AUTO ), baseline_shift(), text_anchor( "text-anchor", enum_text_anchor, SP_CSS_TEXT_ANCHOR_START ), white_space( "white-space", enum_white_space, SP_CSS_WHITE_SPACE_NORMAL ), @@ -321,6 +322,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &writing_mode ); _properties.push_back( &direction ); _properties.push_back( &text_orientation ); + _properties.push_back( &dominant_baseline ); _properties.push_back( &baseline_shift ); _properties.push_back( &text_anchor ); _properties.push_back( &white_space ); @@ -415,6 +417,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( direction.name, reinterpret_cast(&SPStyle::direction ) ) ); // _propmap.insert( std::make_pair( writing_mode.name, reinterpret_cast(&SPStyle::writing_mode ) ) ); // _propmap.insert( std::make_pair( text_orientation.name, reinterpret_cast(&SPStyle::text_orientation ) ) ); + // _propmap.insert( std::make_pair( dominant_baseline.name, reinterpret_cast(&SPStyle::dominant_baseline ) ) ); // _propmap.insert( std::make_pair( baseline_shift.name, reinterpret_cast(&SPStyle::baseline_shift ) ) ); // _propmap.insert( std::make_pair( text_anchor.name, reinterpret_cast(&SPStyle::text_anchor ) ) ); // _propmap.insert( std::make_pair( white_space.name, reinterpret_cast(&SPStyle::white_space ) ) ); @@ -796,6 +799,9 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { case SP_PROP_SHAPE_PADDING: shape_padding.readIfUnset( val ); break; + case SP_PROP_DOMINANT_BASELINE: + dominant_baseline.readIfUnset( val ); + break; case SP_PROP_BASELINE_SHIFT: baseline_shift.readIfUnset( val ); break; @@ -805,9 +811,6 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { case SP_PROP_ALIGNMENT_BASELINE: g_warning("Unimplemented style property SP_PROP_ALIGNMENT_BASELINE: value: %s", val); break; - case SP_PROP_DOMINANT_BASELINE: - g_warning("Unimplemented style property SP_PROP_DOMINANT_BASELINE: value: %s", val); - break; case SP_PROP_GLYPH_ORIENTATION_HORIZONTAL: g_warning("Unimplemented style property SP_PROP_ORIENTATION_HORIZONTAL: value: %s", val); break; diff --git a/src/style.h b/src/style.h index 3948b876c..0e8e34145 100644 --- a/src/style.h +++ b/src/style.h @@ -148,6 +148,8 @@ public: SPIEnum writing_mode; /** Text orientation (CSS Writing Modes 3) */ SPIEnum text_orientation; + /** Dominant baseline (svg1.1) */ + SPIEnum dominant_baseline; /** Baseline shift (svg1.1 10.9.2) */ SPIBaselineShift baseline_shift; -- cgit v1.2.3 From 81760f171e6b7bce537fd94cae3e3e1a6d82e886 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 18 Nov 2015 10:34:55 +0100 Subject: Find font metrics when font is initialized. Fill baseline table. Separately track typographic ascent/descent and maximum ascent/descent. (bzr r14430.1.7) --- src/libnrtype/FontInstance.cpp | 267 ++++++++++++++++++++++++++++++----------- src/libnrtype/font-instance.h | 33 ++++- 2 files changed, 222 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index 5853d5217..4578efe8f 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -184,6 +184,20 @@ font_instance::font_instance(void) : theFace(0) { //printf("font instance born\n"); + _ascent = _ascent_max = 0.8; + _descent = _descent_max = 0.2; + _xheight = 0.5; + + // Default baseline values, alphabetic is reference + _baselines[ SP_CSS_BASELINE_AUTO ] = 0.0; + _baselines[ SP_CSS_BASELINE_ALPHABETIC ] = 0.0; + _baselines[ SP_CSS_BASELINE_IDEOGRAPHIC ] = -_descent; + _baselines[ SP_CSS_BASELINE_HANGING ] = 0.8 * _ascent; + _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = 0.8 * _xheight; + _baselines[ SP_CSS_BASELINE_CENTRAL ] = 0.5; + _baselines[ SP_CSS_BASELINE_MIDDLE ] = 0.5 * _xheight; + _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] = -_descent; + _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] = _ascent; } font_instance::~font_instance(void) @@ -260,6 +274,7 @@ void font_instance::InitTheFace() FT_Select_Charmap(theFace,ft_encoding_unicode) && FT_Select_Charmap(theFace,ft_encoding_symbol); } #endif + FindFontMetrics(); } } @@ -518,83 +533,16 @@ bool font_instance::FontMetrics(double &ascent,double &descent,double &xheight) return false; } - // CSS2 recommends using the OS/2 values sTypoAscender and sTypoDescender - // for the ascender and descender values: - // http://www.w3.org/TR/CSS2/visudet.html#sTypoAscender - // The typographic ascender and descender are taken from the - // otmMacAscent and otmMacDescent values: - // http://microsoft.public.win32.programmer.gdi.narkive.com/LV6k4BDh/msdn-documentation-outlinetextmetrics-clarification - // The otmAscent and otmDescent values are the maxiumum ascent and maxiumum - // descent of all the glyphs in a font. - -#ifdef USE_PANGO_WIN32 - OUTLINETEXTMETRIC otm; - if ( !GetOutlineTextMetrics(parent->hScreenDC,sizeof(otm),&otm) ) { - return false; - } - - double scale=1.0/parent->fontSize; - ascent=fabs(otm.otmMacAscent*scale); - descent=fabs(otm.otmMacDescent*scale); - xheight=fabs(otm.otmXHeight*scale); - // May not be necessary... but if OS/2 table is missing or not version 2 or higher, - // xheight might be set to 0. - if( xheight = 0.0 ) xheight = ascent/2.0; - //otmSubscriptSize, otmSubscriptOffset, otmSuperscriptSize, otmSuperscriptOffset, -#else - if ( theFace->units_per_EM == 0 ) { - return false; // bitmap font - } - - TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table( theFace, FT_SFNT_OS2 ); - if( os2 ) { - ascent =fabs(((double)os2->sTypoAscender)/((double)theFace->units_per_EM)); - descent=fabs(((double)os2->sTypoDescender)/((double)theFace->units_per_EM)); - } else { - ascent =fabs(((double)theFace->ascender)/((double)theFace->units_per_EM)); - descent=fabs(((double)theFace->descender)/((double)theFace->units_per_EM)); - } - - // We must find x-height ourselves! First try OS/2 table. - if( os2 && os2->version >= 0x0002 && os2->version != 0xffffu ) { - // Only os/2 version 2 and above have sxHeight, 0xffff marks "old Mac fonts" without table - xheight=fabs(((double)os2->sxHeight)/((double)theFace->units_per_EM)); - } else { - // Measure 'x' height in font. Recommended option by XSL standard if no sxHeight. - FT_UInt index = FT_Get_Char_Index( theFace, 'x' ); - if( index != 0 ) { - FT_Load_Glyph( theFace, index, FT_LOAD_NO_SCALE ); - xheight = (fabs)(((double)theFace->glyph->metrics.height/(double)theFace->units_per_EM)); - } else { - // No 'x' in font! - xheight = ascent/2.0; - } - } -#endif - - // CSS dictates em size is ascent + descent.... but this doesn't seem to be used in practice. - // The em size is what the font reports... - double em = ascent + descent; - if( em <= 0 ) { - return false; // Pathological - } - ascent /= em; - descent /= em; - xheight /= em; - - // gchar* font_name = pango_font_description_to_string( descr ); - // std::cout << "Font: " << (font_name ? font_name : ("Null")) << std::endl; - // g_free( font_name ); - // std::cout << " ascent: " << ascent << " descent: " << descent - // << " x-height: " << xheight << "\n" << std::endl; + ascent = _ascent; + descent = _descent; + xheight = _xheight; return true; } -bool font_instance::FontDecoration( - double &underline_position, double &underline_thickness, - double &linethrough_position, double &linethrough_thickness -){ +bool font_instance::FontDecoration( double &underline_position, double &underline_thickness, + double &linethrough_position, double &linethrough_thickness) +{ if ( pFont == NULL ) { return false; } @@ -721,6 +669,179 @@ double font_instance::Advance(int glyph_id,bool vertical) return 0; } +// Internal function to find baselines +void font_instance::FindFontMetrics() { + + // CSS2 recommends using the OS/2 values sTypoAscender and sTypoDescender for the Typographic + // ascender and descender values: + // http://www.w3.org/TR/CSS2/visudet.html#sTypoAscender + // On Windows, the typographic ascender and descender are taken from the otmMacAscent and + // otmMacDescent values: + // http://microsoft.public.win32.programmer.gdi.narkive.com/LV6k4BDh/msdn-documentation-outlinetextmetrics-clarification + // The otmAscent and otmDescent values are the maxiumum ascent and maxiumum descent of all the + // glyphs in a font. + if ( theFace ) { + +#ifdef USE_PANGO_WIN32 + + if ( GetOutlineTextMetrics(parent->hScreenDC,sizeof(otm),&otm) ) { + double scale=1.0/parent->fontSize; + _ascent = fabs(otm.otmMacAscent * scale); + _descent = fabs(otm.otmMacDescent * scale); + _xheight = fabs(otm.otmXHeight * scale); + _ascent_max = fabs(otm.otmAscent * scale); + _descent_max = fabs(otm.otmDescent * scale); + + // In CSS em size is ascent + descent... which should be 1. If not, + // adjust so it is. + double em = _ascent + _descent; + if( em > 0 ) { + _ascent /= em; + _descent /= em; + } + + // May not be necessary but if OS/2 table missing or not version 2 or higher, + // xheight might be zero. + if( _xheight == 0.0 ) { + _xheight = 0.5; + } + + // Baselines defined relative to alphabetic. + _baselines[ SP_CSS_BASELINE_IDEOGRAPHIC ] = -_descent; // Recommendation + _baselines[ SP_CSS_BASELINE_HANGING ] = 0.8 * _ascent; // Guess + _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = 0.8 * _xheight; // Guess + _baselines[ SP_CSS_BASELINE_CENTRAL ] = 0.5; // Definition + _baselines[ SP_CSS_BASELINE_MIDDLE ] = 0.5 * _xheight; // Definition + _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] = -_descent; // Definition + _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] = _ascent; // Definition + + + MAT2 identity = {{0,1},{0,0},{0,0},{0,1}}; + GLYPHMETRICS metrics; + int retval; + + // Better math baseline: + // Try center of minus sign + retval = GetGlyphOutline (parent->hScreenDC, 0x2212, GGO_NATIVE | GGO_UNHINTED, &metrics, 0, NULL, &identity); + // If no minus sign, try hyphen + if( retval <= 0 ) + retval = GetGlyphOutline (parent->hScreenDC, '-', GGO_NATIVE | GGO_UNHINTED, &metrics, 0, NULL, &identity); + + if( retval > 0 ) { + double math = (metrics.gmptGlyphOrigin.y + 0.5 * metrics.gmBlackBoxY) * scale; + _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = math; + } + + // Find hanging baseline... assume it is at top of 'म'. + retval = GetGlyphOutline (parent->hScreenDC, 0x092E, GGO_NATIVE | GGO_UNHINTED, &metrics, 0, NULL, &identity); + if( retval > 0 ) { + double hanging = metrics.gmptGlyphOrigin.y * scale; + _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = hanging; + } + } + +#else + + if ( theFace->units_per_EM != 0 ) { // If zero then it's a bitmap font. + + TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table( theFace, FT_SFNT_OS2 ); + if( os2 ) { + _ascent = fabs(((double)os2->sTypoAscender) / ((double)theFace->units_per_EM)); + _descent = fabs(((double)os2->sTypoDescender)/ ((double)theFace->units_per_EM)); + } else { + _ascent = fabs(((double)theFace->ascender) / ((double)theFace->units_per_EM)); + _descent = fabs(((double)theFace->descender) / ((double)theFace->units_per_EM)); + } + _ascent_max = fabs(((double)theFace->ascender) / ((double)theFace->units_per_EM)); + _descent_max = fabs(((double)theFace->descender) / ((double)theFace->units_per_EM)); + + // In CSS em size is ascent + descent... which should be 1. If not, + // adjust so it is. + double em = _ascent + _descent; + if( em > 0 ) { + _ascent /= em; + _descent /= em; + } + + // x-height + if( os2 && os2->version >= 0x0002 && os2->version != 0xffffu ) { + // Only os/2 version 2 and above have sxHeight, 0xffff marks "old Mac fonts" without table + _xheight = fabs(((double)os2->sxHeight) / ((double)theFace->units_per_EM)); + } else { + // Measure 'x' height in font. Recommended option by XSL standard if no sxHeight. + FT_UInt index = FT_Get_Char_Index( theFace, 'x' ); + if( index != 0 ) { + FT_Load_Glyph( theFace, index, FT_LOAD_NO_SCALE ); + _xheight = (fabs)(((double)theFace->glyph->metrics.height/(double)theFace->units_per_EM)); + } else { + // No 'x' in font! + _xheight = 0.5; + } + } + + // Baselines defined relative to alphabetic. + _baselines[ SP_CSS_BASELINE_IDEOGRAPHIC ] = -_descent; // Recommendation + _baselines[ SP_CSS_BASELINE_HANGING ] = 0.8 * _ascent; // Guess + _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = 0.8 * _xheight; // Guess + _baselines[ SP_CSS_BASELINE_CENTRAL ] = 0.5; // Definition + _baselines[ SP_CSS_BASELINE_MIDDLE ] = 0.5 * _xheight; // Definition + _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] = -_descent; // Definition + _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] = _ascent; // Definition + + // Better math baseline: + // Try center of minus sign + FT_UInt index = FT_Get_Char_Index( theFace, 0x2212 ); //'āˆ’' + // If no minus sign, try hyphen + if( index == 0 ) + index = FT_Get_Char_Index( theFace, '-' ); + + if( index != 0 ) { + FT_Load_Glyph( theFace, index, FT_LOAD_NO_SCALE ); + FT_Glyph aglyph; + FT_Get_Glyph( theFace->glyph, &aglyph ); + FT_BBox acbox; + FT_Glyph_Get_CBox( aglyph, FT_GLYPH_BBOX_UNSCALED, &acbox ); + double math = (acbox.yMin + acbox.yMax)/2.0/(double)theFace->units_per_EM; + _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = math; + std::cout << "Math baseline: - bbox: y_min: " << acbox.yMin + << " y_max: " << acbox.yMax + << " math: " << math << std::endl; + } + + // Find hanging baseline... assume it is at top of 'म'. + index = FT_Get_Char_Index( theFace, 0x092E ); // 'म' + if( index != 0 ) { + FT_Load_Glyph( theFace, index, FT_LOAD_NO_SCALE ); + FT_Glyph aglyph; + FT_Get_Glyph( theFace->glyph, &aglyph ); + FT_BBox acbox; + FT_Glyph_Get_CBox( aglyph, FT_GLYPH_BBOX_UNSCALED, &acbox ); + double hanging = (double)acbox.yMax/(double)theFace->units_per_EM; + _baselines[ SP_CSS_BASELINE_HANGING ] = hanging; + std::cout << "Hanging baseline: प: " << hanging << std::endl; + } + } +#endif + const gchar *family = pango_font_description_get_family(descr); + std::cout << "Font: " << (family?family:"null") << std::endl; + std::cout << " ascent: " << _ascent << std::endl; + std::cout << " descent: " << _descent << std::endl; + std::cout << " x-height: " << _xheight << std::endl; + std::cout << " max ascent: " << _ascent_max << std::endl; + std::cout << " max descent: " << _descent_max << std::endl; + std::cout << " Baselines:" << std::endl; + std::cout << " alphabetic: " << _baselines[ SP_CSS_BASELINE_ALPHABETIC ] << std::endl; + std::cout << " ideographic: " << _baselines[ SP_CSS_BASELINE_IDEOGRAPHIC ] << std::endl; + std::cout << " hanging: " << _baselines[ SP_CSS_BASELINE_HANGING ] << std::endl; + std::cout << " math: " << _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] << std::endl; + std::cout << " central: " << _baselines[ SP_CSS_BASELINE_CENTRAL ] << std::endl; + std::cout << " middle: " << _baselines[ SP_CSS_BASELINE_MIDDLE ] << std::endl; + std::cout << " text_before: " << _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] << std::endl; + std::cout << " text_after: " << _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] << std::endl; + } +} + + /* Local Variables: mode:c++ diff --git a/src/libnrtype/font-instance.h b/src/libnrtype/font-instance.h index 5a71e353b..2fac7c19b 100644 --- a/src/libnrtype/font-instance.h +++ b/src/libnrtype/font-instance.h @@ -57,19 +57,31 @@ public: // nota: all coordinates returned by these functions are on a [0..1] scale; you need to multiply // by the fontsize to get the real sizes + + // Return 2geom pathvector for glyph. Deallocated when font instance dies. Geom::PathVector* PathVector(int glyph_id); - // returns the 2geom-type pathvector for this glyph. no refcounting needed, it's deallocated when the font_instance dies + + // Horizontal advance if 'vertical' is false, vertical advance if true. double Advance(int glyph_id, bool vertical); - // nominal advance of the font. + + double GetTypoAscent() { return _ascent; } + double GetTypoDescent() { return _descent; } + double GetXHeight() { return _xheight; } + double GetMaxAscent() { return _ascent_max; } + double GetMaxDescent() { return _descent_max; } + const double* GetBaselines() { return _baselines; } + bool FontMetrics(double &ascent, double &descent, double &leading); - bool FontDecoration(double &underline_position, double &underline_thickness, - double &linethrough_position, double &linethrough_thickness); + bool FontDecoration(double &underline_position, double &underline_thickness, + double &linethrough_position, double &linethrough_thickness); bool FontSlope(double &run, double &rise); // for generating slanted cursors for oblique fonts - Geom::OptRect BBox(int glyph_id); + Geom::OptRect BBox(int glyph_id); private: void FreeTheFace(); + // Find ascent, descent, x-height, and baselines. + void FindFontMetrics(); // Temp: make public public: @@ -81,6 +93,17 @@ public: // as long as pFont is valid, theFace is too #endif +private: + + // Font metrics in em-box units + double _ascent; // Typographic ascent. + double _descent; // Typographic descent. + double _xheight; // x-height of font. + double _ascent_max; // Maxiumum ascent of all glyphs in font. + double _descent_max; // Maxiumum descent of all glyphs in font. + + // Baselines + double _baselines[SP_CSS_BASELINE_SIZE]; }; -- cgit v1.2.3 From 1c89d667e01b9ed8a8aa283ca7332ab61857c6bc Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 18 Nov 2015 11:17:24 +0100 Subject: Turn FontMetrics into a class. Add maximum ascent/descent variables. (bzr r14430.1.8) --- src/libnrtype/Layout-TNG-Compute.cpp | 2 +- src/libnrtype/Layout-TNG-OutIter.cpp | 3 ++- src/libnrtype/Layout-TNG-Output.cpp | 26 ++++++++++++++++----- src/libnrtype/Layout-TNG.h | 44 +++++++++++++++++++++++++++--------- 4 files changed, 56 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 6b5697b10..2081b5a6d 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -482,7 +482,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ // Vertical text, use em box center as baseline new_line.baseline_y += 0.5 * line_height.emSize(); } else { - new_line.baseline_y += line_height.getAscent(); + new_line.baseline_y += line_height.getTypoAscent(); } } diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index c7275c24e..8c29b7dbc 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -120,7 +120,8 @@ Layout::iterator Layout::getNearestCursorPositionTo(double x, double y) const double best_y_range = DBL_MAX; double best_x_range = DBL_MAX; for (chunk_index = 0 ; chunk_index < _chunks.size() ; chunk_index++) { - FontMetrics line_height = {0.0, 0.0, 0.0}; + FontMetrics line_height; + line_height *= 0.0; // Set all metrics to zero. double chunk_width = 0.0; for ( ; span_index < _spans.size() && _spans[span_index].in_chunk == chunk_index ; span_index++) { line_height.max(_spans[span_index].line_height); diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 0bbf266c7..9557bc84c 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -93,10 +93,24 @@ void Layout::_clearOutputObjects() _path_fitted = NULL; } +void Layout::FontMetrics::set(font_instance *font) +{ + if( font != NULL ) { + ascent = font->GetTypoAscent(); + descent = font->GetTypoDescent(); + xheight = font->GetXHeight(); + ascent_max = font->GetMaxAscent(); + descent_max = font->GetMaxDescent(); + } +} + void Layout::FontMetrics::max(FontMetrics const &other) { - if (other.ascent > ascent) ascent = other.ascent; - if (other.descent > descent) descent = other.descent; + if (other.ascent > ascent ) ascent = other.ascent; + if (other.descent > descent ) descent = other.descent; + if( other.xheight > xheight ) xheight = other.xheight; + if( other.ascent_max > ascent_max ) ascent_max = other.ascent_max; + if( other.descent_max > descent_max ) descent_max = other.descent_max; } void Layout::FontMetrics::computeEffective( const double &line_height_multiplier ) { @@ -142,8 +156,8 @@ void Layout::show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const InputStreamTextSource const *text_source = static_cast(_input_stream[_spans[span_index].in_input_stream_item]); text_source->style->text_decoration_data.tspan_width = _spans[span_index].width(); - text_source->style->text_decoration_data.ascender = _spans[span_index].line_height.getAscent(); - text_source->style->text_decoration_data.descender = _spans[span_index].line_height.getDescent(); + text_source->style->text_decoration_data.ascender = _spans[span_index].line_height.getTypoAscent(); + text_source->style->text_decoration_data.descender = _spans[span_index].line_height.getTypoDescent(); if(!span_index || (_chunks[_spans[span_index].in_chunk].in_line != _chunks[_spans[span_index-1].in_chunk].in_line)){ @@ -188,8 +202,8 @@ void Layout::show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const // save the starting coordinates for the line - these are needed for figuring out dot/dash/wave phase (void) nr_text->addComponent(_spans[span_index].font, _glyphs[glyph_index].glyph, glyph_matrix, _glyphs[glyph_index].width, - _spans[span_index].line_height.getAscent(), - _spans[span_index].line_height.getDescent(), + _spans[span_index].line_height.getTypoAscent(), + _spans[span_index].line_height.getTypoDescent(), glyph_matrix.translation()[Geom::X] - phase0 ); } diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index c2895e05f..ccf4bbe43 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -622,20 +622,32 @@ public: * * It's useful for this to be public so that ScanlineMaker can use it. */ - struct FontMetrics { - - double ascent; - double descent; - double xheight; + class FontMetrics { + public: + FontMetrics() { reset(); } + + void reset() { + ascent = 0.8; + descent = -0.2; + xheight = 0.5; + ascent_max = 0.8; + descent_max = 0.2; + } + + inline void set( font_instance *font ); + // CSS 2.1 dictates that font-size is based on em-size which is defined as ascent + descent inline double emSize() const {return ascent + descent;} // Alternatively name function for use 2. inline double lineSize() const { return ascent + descent; } - inline void setZero() {ascent = descent = xheight = 0.0;} + inline void setZero() {ascent = descent = xheight = ascent_max = descent_max = 0.0;} // For scaling for 'font-size'. - inline FontMetrics& operator*=(double x) {ascent *= x; descent *= x; xheight *= x; return *this;} + inline FontMetrics& operator*=(double x) { + ascent *= x; descent *= x; xheight *= x; ascent_max *= x; descent_max *= x; + return *this; + } /// Save the larger values of ascent and descent between this and other. Needed for laying /// out a line with mixed font-sizes, fonts, or line spacings. @@ -644,10 +656,20 @@ public: /// Calculate the effective ascent and descent including half "leading". void computeEffective( const double &line_height ); - inline double getAscent() const {return ascent; } - inline double getDescent() const {return descent; } - inline double getXheight() const {return xheight; } - }; + inline double getTypoAscent() const {return ascent; } + inline double getTypoDescent() const {return descent; } + inline double getXHeight() const {return xheight; } + inline double getMaxAscent() const {return ascent_max; } + inline double getMaxDescent() const {return descent_max; } + + // private: + double ascent; // Typographic ascent. + double descent; // Typographic descent. + double xheight; // Height of 'x' measured from alphabetic baseline. + double ascent_max; // Maximum ascent of all glyphs in font. + double descent_max; // Maximum descent of all glyphs in font. + + }; // End FontMetrics /// see _enum_converter() struct EnumConversionItem { -- cgit v1.2.3 From bfc8e4559285237d13c45e37240a9561c8af5264 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 18 Nov 2015 15:53:56 +0100 Subject: Code cleanup. Remove/simplify some functions. (bzr r14430.1.9) --- src/libnrtype/Layout-TNG-Compute.cpp | 70 +++++++++++++++--------------------- src/libnrtype/Layout-TNG-Input.cpp | 46 ------------------------ src/libnrtype/Layout-TNG.h | 3 +- src/style.cpp | 2 +- 4 files changed, 30 insertions(+), 91 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 2081b5a6d..05cc638f7 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -194,9 +194,8 @@ class Layout::Calculator void _buildPangoItemizationForPara(ParagraphInfo *para) const; - static void _computeFontLineHeight(font_instance *font, double font_size, - SPStyle const *style, FontMetrics *line_height, - double *line_height_multiplier); + // Returns line_height_multiplier + static double _computeFontLineHeight( SPStyle const *style ); unsigned _buildSpansForPara(ParagraphInfo *para) const; @@ -1106,46 +1105,32 @@ void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) con } /** - * Gets the ascent and descent for a font given the 'font-size' propert and finds the value of - * line_height_multiplier given the 'line-height' property. The result of multiplying - * \a l by \a line_height_multiplier is the inline box height as specified in css2 + * Finds the value of line_height_multiplier given the 'line-height' property. The result of + * multiplying \a l by \a line_height_multiplier is the inline box height as specified in css2 * section 10.8. http://www.w3.org/TR/CSS2/visudet.html#line-height + * + * The 'computed' value of 'line-height' does not have a consistent meaning. We need to find the + * 'used' value and divide that by the font size. */ -// THIS FUNCTION SHOULD NOT BE NECESSARY -void Layout::Calculator::_computeFontLineHeight(font_instance *font, double font_size, - SPStyle const *style, FontMetrics *font_metrics, - double *line_height_multiplier) +double Layout::Calculator::_computeFontLineHeight( SPStyle const *style ) { - if (font == NULL) { - font_metrics->setZero(); - *line_height_multiplier = 1.0; - } - else { - font->FontMetrics(font_metrics->ascent, font_metrics->descent, font_metrics->xheight); - } - *font_metrics *= font_size; - // yet another borked SPStyle member that we're going to have to fix ourselves - // To do: check if it really is still borked. + // We shouldn't need to climb the element tree... for ( ; ; ) { if (style->line_height.set && !style->line_height.inherit) { if (style->line_height.normal) break; switch (style->line_height.unit) { case SP_CSS_UNIT_NONE: - *line_height_multiplier = style->line_height.computed; - return; + return style->line_height.computed; case SP_CSS_UNIT_EX: - *line_height_multiplier = style->line_height.value * 0.5; + return style->line_height.value * 0.5; // 0.5 is an approximation of the x-height. Fixme. - return; case SP_CSS_UNIT_EM: case SP_CSS_UNIT_PERCENT: - *line_height_multiplier = style->line_height.value; - return; + return style->line_height.value; default: // absolute values - *line_height_multiplier = style->line_height.computed / font_metrics->emSize(); - return; + return style->line_height.computed / style->font_size.computed; } break; } @@ -1153,7 +1138,7 @@ void Layout::Calculator::_computeFontLineHeight(font_instance *font, double font style = style->object->parent->style; if (style == NULL) break; } - *line_height_multiplier = LINE_HEIGHT_NORMAL; + return (LINE_HEIGHT_NORMAL); } bool compareGlyphWidth(const PangoGlyphInfo &a, const PangoGlyphInfo &b) @@ -1270,7 +1255,7 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const } // now we know the length, do some final calculations and add the UnbrokenSpan to the list - new_span.font_size = text_source->styleComputeFontSize() * _flow.getTextLengthMultiplierDue(); + new_span.font_size = text_source->style->font_size.computed * _flow.getTextLengthMultiplierDue(); if (new_span.text_bytes) { new_span.glyph_string = pango_glyph_string_new(); /* Some assertions intended to help diagnose bug #1277746. */ @@ -1366,7 +1351,9 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const /* glyphs[].x_offset values may be out of order within any log_clusters, apparently harmless */ } new_span.pango_item_index = pango_item_index; - _computeFontLineHeight(para->pango_items[pango_item_index].font, new_span.font_size, text_source->style, &new_span.line_height, &new_span.line_height_multiplier); + new_span.line_height_multiplier = _computeFontLineHeight( text_source->style ); + new_span.line_height.set( para->pango_items[pango_item_index].font ); + new_span.line_height *= new_span.font_size; // At some point we may want to calculate baseline_shift here (to take advantage // of otm features like superscript baseline), but for now we use style baseline_shift. @@ -1381,11 +1368,13 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const new_span.pango_item_index = -1; font_instance *font = text_source->styleGetFontInstance(); if (font) { - _computeFontLineHeight(font, new_span.font_size, text_source->style, &new_span.line_height, &new_span.line_height_multiplier); + new_span.line_height_multiplier = _computeFontLineHeight( text_source->style ); + new_span.line_height.set( font ); + new_span.line_height *= new_span.font_size; font->Unref(); } else { - new_span.line_height.setZero(); - new_span.line_height_multiplier = 1.0; + new_span.line_height *= 0.0; // Set all to zero + new_span.line_height_multiplier = LINE_HEIGHT_NORMAL; } TRACE(("add style init span %lu\n", para->unbroken_spans.size())); } @@ -1451,9 +1440,9 @@ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, InputStreamTextSource const *text_source = static_cast(_flow._input_stream.front()); font_instance *font = text_source->styleGetFontInstance(); if (font) { - double font_size = text_source->styleComputeFontSize(); - double multiplier; - _computeFontLineHeight(font, font_size, text_source->style, line_height, &multiplier); + double multiplier = _computeFontLineHeight(text_source->style); + line_height->set( font ); + *line_height *= text_source->style->font_size.computed; font->Unref(); *line_height *= multiplier; _scanline_maker->setNewYCoordinate(_scanline_maker->yCoordinate() - line_height->ascent); @@ -1814,7 +1803,7 @@ void Layout::_calculateCursorShapeForEmpty() InputStreamTextSource const *text_source = static_cast(_input_stream.front()); font_instance *font = text_source->styleGetFontInstance(); - double font_size = text_source->styleComputeFontSize(); + double font_size = text_source->style->font_size.computed; double caret_slope_run = 0.0, caret_slope_rise = 1.0; FontMetrics line_height; if (font) { @@ -1822,11 +1811,8 @@ void Layout::_calculateCursorShapeForEmpty() font->FontMetrics(line_height.ascent, line_height.descent, line_height.xheight); line_height *= font_size; font->Unref(); - } else { - line_height.ascent = font_size * 0.85; // random guesses - line_height.descent = font_size * 0.15; - line_height.xheight = 0.0; } + double caret_slope = atan2(caret_slope_run, caret_slope_rise); _empty_cursor_shape.height = font_size / cos(caret_slope); _empty_cursor_shape.rotation = caret_slope; diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index d99433adf..b66bbb5cd 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -126,52 +126,6 @@ int Layout::_enum_converter(int input, EnumConversionItem const *conversion_tabl return conversion_table[0].output; } -// ***** the style format interface -// this doesn't include all accesses to SPStyle, only the ones that are non-trivial - -static const float medium_font_size = 12.0; // more of a default if all else fails than anything else -float Layout::InputStreamTextSource::styleComputeFontSize() const -{ - return style->font_size.computed; - - // in case the computed value's not good enough, here's some manual code held in reserve: - SPStyle const *this_style = style; - float inherit_multiplier = 1.0; - - for ( ; ; ) { - if (this_style->font_size.set && !this_style->font_size.inherit) { - switch (this_style->font_size.type) { - case SP_FONT_SIZE_LITERAL: { - switch(this_style->font_size.literal) { // these multipliers are straight out of the CSS spec - case SP_CSS_FONT_SIZE_XX_SMALL: return medium_font_size * inherit_multiplier * (3.0/5.0); - case SP_CSS_FONT_SIZE_X_SMALL: return medium_font_size * inherit_multiplier * (3.0/4.0); - case SP_CSS_FONT_SIZE_SMALL: return medium_font_size * inherit_multiplier * (8.0/9.0); - default: - case SP_CSS_FONT_SIZE_MEDIUM: return medium_font_size * inherit_multiplier; - case SP_CSS_FONT_SIZE_LARGE: return medium_font_size * inherit_multiplier * (6.0/5.0); - case SP_CSS_FONT_SIZE_X_LARGE: return medium_font_size * inherit_multiplier * (3.0/2.0); - case SP_CSS_FONT_SIZE_XX_LARGE: return medium_font_size * inherit_multiplier * 2.0; - case SP_CSS_FONT_SIZE_SMALLER: inherit_multiplier *= 0.84; break; //not exactly according to spec - case SP_CSS_FONT_SIZE_LARGER: inherit_multiplier *= 1.26; break; //not exactly according to spec - } - break; - } - case SP_FONT_SIZE_PERCENTAGE: { // 'em' units should be in here, but aren't. Fix in style.cpp. - inherit_multiplier *= this_style->font_size.value; - break; - } - case SP_FONT_SIZE_LENGTH: { - return this_style->font_size.value * inherit_multiplier; - } - } - } - if (this_style->object == NULL || this_style->object->parent == NULL) break; - this_style = this_style->object->parent->style; - if (this_style == NULL) break; - } - return medium_font_size * inherit_multiplier; -} - Layout::Direction Layout::InputStreamTextSource::styleGetBlockProgression() const { switch( style->writing_mode.computed ) { diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index ccf4bbe43..c923cc0dc 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -635,7 +635,7 @@ public: descent_max = 0.2; } - inline void set( font_instance *font ); + void set( font_instance *font ); // CSS 2.1 dictates that font-size is based on em-size which is defined as ascent + descent inline double emSize() const {return ascent + descent;} @@ -718,7 +718,6 @@ private: LengthAdjust lengthAdjust; // a few functions for some of the more complicated style accesses - float styleComputeFontSize() const; /// The return value must be freed with pango_font_description_free() PangoFontDescription *styleGetFontDescription() const; font_instance *styleGetFontInstance() const; diff --git a/src/style.cpp b/src/style.cpp index 0bad376a4..2a216e940 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -113,7 +113,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : font_weight( "font-weight", enum_font_weight, SP_CSS_FONT_WEIGHT_NORMAL, SP_CSS_FONT_WEIGHT_400 ), font_stretch( "font-stretch", enum_font_stretch, SP_CSS_FONT_STRETCH_NORMAL ), font_size(), - line_height( "line-height", 1.0 ), // SPILengthOrNormal + line_height( "line-height", 1.25 ), // SPILengthOrNormal font_family( "font-family", "sans-serif" ), // SPIString w/default font(), // SPIFont font_specification( "-inkscape-font-specification" ), // SPIString -- cgit v1.2.3 From 3e68cf3b33b153dd0fc7eda9a2850f448a42c76c Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 18 Nov 2015 16:05:09 +0100 Subject: Use maximum ascent and descent for glyphs to ensure that glyphs that extend outside the em-box are fully drawn. (bzr r14430.1.10) --- src/libnrtype/Layout-TNG-Output.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 9557bc84c..526319f35 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -199,11 +199,14 @@ void Layout::show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const first_line_glyph = false; phase0 = glyph_matrix.translation()[Geom::X]; } - // save the starting coordinates for the line - these are needed for figuring out dot/dash/wave phase + // Save the starting coordinates for the line - these are needed for figuring out + // dot/dash/wave phase. + // Use maximum ascent and descent to ensure glpyhs that extend outside the embox + // are fully drawn. (void) nr_text->addComponent(_spans[span_index].font, _glyphs[glyph_index].glyph, glyph_matrix, _glyphs[glyph_index].width, - _spans[span_index].line_height.getTypoAscent(), - _spans[span_index].line_height.getTypoDescent(), + _spans[span_index].line_height.getMaxAscent(), + _spans[span_index].line_height.getMaxDescent(), glyph_matrix.translation()[Geom::X] - phase0 ); } -- cgit v1.2.3 From c1e4090d4e1d4deed0ea4fde9929360b6b291ea2 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 18 Nov 2015 22:05:48 +0100 Subject: Implement rendering of 'dominant-baseline' property. (bzr r14430.1.11) --- src/libnrtype/FontInstance.cpp | 46 ++++++++++++++++++------------------ src/libnrtype/Layout-TNG-Compute.cpp | 35 ++++++++++++++------------- src/libnrtype/Layout-TNG-Input.cpp | 5 ++++ src/libnrtype/Layout-TNG.h | 9 +++++++ 4 files changed, 56 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index 4578efe8f..79477d431 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -194,7 +194,7 @@ font_instance::font_instance(void) : _baselines[ SP_CSS_BASELINE_IDEOGRAPHIC ] = -_descent; _baselines[ SP_CSS_BASELINE_HANGING ] = 0.8 * _ascent; _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = 0.8 * _xheight; - _baselines[ SP_CSS_BASELINE_CENTRAL ] = 0.5; + _baselines[ SP_CSS_BASELINE_CENTRAL ] = 0.5 - _descent; _baselines[ SP_CSS_BASELINE_MIDDLE ] = 0.5 * _xheight; _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] = -_descent; _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] = _ascent; @@ -710,7 +710,7 @@ void font_instance::FindFontMetrics() { _baselines[ SP_CSS_BASELINE_IDEOGRAPHIC ] = -_descent; // Recommendation _baselines[ SP_CSS_BASELINE_HANGING ] = 0.8 * _ascent; // Guess _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = 0.8 * _xheight; // Guess - _baselines[ SP_CSS_BASELINE_CENTRAL ] = 0.5; // Definition + _baselines[ SP_CSS_BASELINE_CENTRAL ] = 0.5 - _descent; // Definition _baselines[ SP_CSS_BASELINE_MIDDLE ] = 0.5 * _xheight; // Definition _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] = -_descent; // Definition _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] = _ascent; // Definition @@ -783,7 +783,7 @@ void font_instance::FindFontMetrics() { _baselines[ SP_CSS_BASELINE_IDEOGRAPHIC ] = -_descent; // Recommendation _baselines[ SP_CSS_BASELINE_HANGING ] = 0.8 * _ascent; // Guess _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = 0.8 * _xheight; // Guess - _baselines[ SP_CSS_BASELINE_CENTRAL ] = 0.5; // Definition + _baselines[ SP_CSS_BASELINE_CENTRAL ] = 0.5 - _descent; // Definition _baselines[ SP_CSS_BASELINE_MIDDLE ] = 0.5 * _xheight; // Definition _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] = -_descent; // Definition _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] = _ascent; // Definition @@ -803,9 +803,9 @@ void font_instance::FindFontMetrics() { FT_Glyph_Get_CBox( aglyph, FT_GLYPH_BBOX_UNSCALED, &acbox ); double math = (acbox.yMin + acbox.yMax)/2.0/(double)theFace->units_per_EM; _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = math; - std::cout << "Math baseline: - bbox: y_min: " << acbox.yMin - << " y_max: " << acbox.yMax - << " math: " << math << std::endl; + // std::cout << "Math baseline: - bbox: y_min: " << acbox.yMin + // << " y_max: " << acbox.yMax + // << " math: " << math << std::endl; } // Find hanging baseline... assume it is at top of 'म'. @@ -818,26 +818,26 @@ void font_instance::FindFontMetrics() { FT_Glyph_Get_CBox( aglyph, FT_GLYPH_BBOX_UNSCALED, &acbox ); double hanging = (double)acbox.yMax/(double)theFace->units_per_EM; _baselines[ SP_CSS_BASELINE_HANGING ] = hanging; - std::cout << "Hanging baseline: प: " << hanging << std::endl; + // std::cout << "Hanging baseline: प: " << hanging << std::endl; } } #endif - const gchar *family = pango_font_description_get_family(descr); - std::cout << "Font: " << (family?family:"null") << std::endl; - std::cout << " ascent: " << _ascent << std::endl; - std::cout << " descent: " << _descent << std::endl; - std::cout << " x-height: " << _xheight << std::endl; - std::cout << " max ascent: " << _ascent_max << std::endl; - std::cout << " max descent: " << _descent_max << std::endl; - std::cout << " Baselines:" << std::endl; - std::cout << " alphabetic: " << _baselines[ SP_CSS_BASELINE_ALPHABETIC ] << std::endl; - std::cout << " ideographic: " << _baselines[ SP_CSS_BASELINE_IDEOGRAPHIC ] << std::endl; - std::cout << " hanging: " << _baselines[ SP_CSS_BASELINE_HANGING ] << std::endl; - std::cout << " math: " << _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] << std::endl; - std::cout << " central: " << _baselines[ SP_CSS_BASELINE_CENTRAL ] << std::endl; - std::cout << " middle: " << _baselines[ SP_CSS_BASELINE_MIDDLE ] << std::endl; - std::cout << " text_before: " << _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] << std::endl; - std::cout << " text_after: " << _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] << std::endl; + // const gchar *family = pango_font_description_get_family(descr); + // std::cout << "Font: " << (family?family:"null") << std::endl; + // std::cout << " ascent: " << _ascent << std::endl; + // std::cout << " descent: " << _descent << std::endl; + // std::cout << " x-height: " << _xheight << std::endl; + // std::cout << " max ascent: " << _ascent_max << std::endl; + // std::cout << " max descent: " << _descent_max << std::endl; + // std::cout << " Baselines:" << std::endl; + // std::cout << " alphabetic: " << _baselines[ SP_CSS_BASELINE_ALPHABETIC ] << std::endl; + // std::cout << " ideographic: " << _baselines[ SP_CSS_BASELINE_IDEOGRAPHIC ] << std::endl; + // std::cout << " hanging: " << _baselines[ SP_CSS_BASELINE_HANGING ] << std::endl; + // std::cout << " math: " << _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] << std::endl; + // std::cout << " central: " << _baselines[ SP_CSS_BASELINE_CENTRAL ] << std::endl; + // std::cout << " middle: " << _baselines[ SP_CSS_BASELINE_MIDDLE ] << std::endl; + // std::cout << " text_before: " << _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] << std::endl; + // std::cout << " text_after: " << _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] << std::endl; } } diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 05cc638f7..2ae13efa6 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -692,10 +692,18 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ // y-coordinate is flipped between vertical and horizontal text... delta_y is common offset but applied with opposite sign double delta_y = unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier + unbroken_span.baseline_shift; + SPCSSBaseline dominant_baseline = _flow._blockBaseline(); if (_block_progression == LEFT_TO_RIGHT || _block_progression == RIGHT_TO_LEFT) { // Vertical text + // Default dominant baseline is determined by overall block (i.e. ) 'text-orientation' value. + if( _flow._blockTextOrientation() != SP_CSS_TEXT_ORIENTATION_SIDEWAYS ) { + if( dominant_baseline == SP_CSS_BASELINE_AUTO ) dominant_baseline = SP_CSS_BASELINE_CENTRAL; + } else { + if( dominant_baseline == SP_CSS_BASELINE_AUTO ) dominant_baseline = SP_CSS_BASELINE_ALPHABETIC; + } + new_glyph.y += delta_y; // TODO: Should also check 'glyph_orientation_vertical' if 'text-orientation' is unset... @@ -703,15 +711,10 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ (new_span.text_orientation == SP_CSS_TEXT_ORIENTATION_MIXED && para.pango_items[unbroken_span.pango_item_index].item->analysis.gravity == 0) ) { - // Sideways orientation (Latin characters, CJK punctuation), 90deg rotation done at output stage. + // Sideways orientation (Latin characters, CJK punctuation), 90deg rotation done at output stage. zzzzzzz new_glyph.orientation = ORIENTATION_SIDEWAYS; - // Baseline is determined by overall block (i.e. ) 'text-orientation' value. - if( _flow._blockTextOrientation() != SP_CSS_TEXT_ORIENTATION_SIDEWAYS ) { - // Baseline is center (shift: alphabetic to center) - new_glyph.y += 0.5 * (new_span.line_height.descent - new_span.line_height.ascent); - } - + new_glyph.y -= new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->GetBaselines()[ dominant_baseline ]; new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, false); } else { @@ -719,14 +722,10 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ new_glyph.x += new_span.line_height.ascent; - // Baseline is determined by overall block (i.e. ) 'text-orientation' value. - if( _flow._blockTextOrientation() == SP_CSS_TEXT_ORIENTATION_SIDEWAYS ) { - // Baseline is alphabetic .. sideways (shift: left edge to alphabetic) - new_glyph.y -= new_span.line_height.descent; - } else { - // Baseline is center (shift: left edge to center) - new_glyph.y -= unbroken_span_glyph_info->geometry.width * 0.5 * font_size_multiplier; - } + // Glyph reference point is center (shift: left edge to center glyph) + new_glyph.y -= unbroken_span_glyph_info->geometry.width * 0.5 * font_size_multiplier; + new_glyph.y -= new_span.font_size * (para.pango_items[unbroken_span.pango_item_index].font->GetBaselines()[ dominant_baseline ] - + para.pango_items[unbroken_span.pango_item_index].font->GetBaselines()[ SP_CSS_BASELINE_CENTRAL ] ); new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, true); if( new_glyph.width == 0 ) { @@ -736,8 +735,12 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ } } else { // Horizontal text - new_glyph.y -= delta_y; + if( dominant_baseline == SP_CSS_BASELINE_AUTO ) dominant_baseline = SP_CSS_BASELINE_ALPHABETIC; + + new_glyph.y -= delta_y; + new_glyph.y += new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->GetBaselines()[ dominant_baseline ]; + new_glyph.width = unbroken_span_glyph_info->geometry.width * font_size_multiplier; if ((new_glyph.width == 0) && (para.pango_items[unbroken_span.pango_item_index].font)) new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, false); diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index b66bbb5cd..6f5d4e5f8 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -151,6 +151,11 @@ SPCSSTextOrientation Layout::InputStreamTextSource::styleGetTextOrientation() co return ((SPCSSTextOrientation)style->text_orientation.computed); } +SPCSSBaseline Layout::InputStreamTextSource::styleGetDominantBaseline() const +{ + return ((SPCSSBaseline)style->dominant_baseline.computed); +} + static Layout::Alignment text_anchor_to_alignment(unsigned anchor, Layout::Direction para_direction) { switch (anchor) { diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index c923cc0dc..97a05bde8 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -723,6 +723,7 @@ private: font_instance *styleGetFontInstance() const; Direction styleGetBlockProgression() const; SPCSSTextOrientation styleGetTextOrientation() const; + SPCSSBaseline styleGetDominantBaseline() const; Alignment styleGetAlignment(Direction para_direction, bool try_text_align) const; }; @@ -769,6 +770,14 @@ private: return SP_CSS_TEXT_ORIENTATION_MIXED; } + /** The overall text-orientation of the whole flow. */ + inline SPCSSBaseline _blockBaseline() const + { + if(!_input_stream.empty()) + return static_cast(_input_stream.front())->styleGetDominantBaseline(); + return SP_CSS_BASELINE_AUTO; + } + /** so that LEFT_TO_RIGHT == RIGHT_TO_LEFT but != TOP_TO_BOTTOM */ static bool _directions_are_orthogonal(Direction d1, Direction d2); -- cgit v1.2.3 From 9966fe3579bc3d8f0bfc0d453f549119de1d6884 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 19 Nov 2015 11:33:34 +0100 Subject: Swap text-before-edge and text-after-edge baseline values. (bzr r14430.1.12) --- src/libnrtype/FontInstance.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index 79477d431..f0b87efa7 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -196,8 +196,8 @@ font_instance::font_instance(void) : _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = 0.8 * _xheight; _baselines[ SP_CSS_BASELINE_CENTRAL ] = 0.5 - _descent; _baselines[ SP_CSS_BASELINE_MIDDLE ] = 0.5 * _xheight; - _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] = -_descent; - _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] = _ascent; + _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] = _ascent; + _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] = -_descent; } font_instance::~font_instance(void) @@ -712,8 +712,8 @@ void font_instance::FindFontMetrics() { _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = 0.8 * _xheight; // Guess _baselines[ SP_CSS_BASELINE_CENTRAL ] = 0.5 - _descent; // Definition _baselines[ SP_CSS_BASELINE_MIDDLE ] = 0.5 * _xheight; // Definition - _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] = -_descent; // Definition - _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] = _ascent; // Definition + _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] = _ascent; // Definition + _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] = -_descent; // Definition MAT2 identity = {{0,1},{0,0},{0,0},{0,1}}; @@ -785,8 +785,8 @@ void font_instance::FindFontMetrics() { _baselines[ SP_CSS_BASELINE_MATHEMATICAL ] = 0.8 * _xheight; // Guess _baselines[ SP_CSS_BASELINE_CENTRAL ] = 0.5 - _descent; // Definition _baselines[ SP_CSS_BASELINE_MIDDLE ] = 0.5 * _xheight; // Definition - _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] = -_descent; // Definition - _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] = _ascent; // Definition + _baselines[ SP_CSS_BASELINE_TEXT_BEFORE_EDGE ] = _ascent; // Definition + _baselines[ SP_CSS_BASELINE_TEXT_AFTER_EDGE ] = -_descent; // Definition // Better math baseline: // Try center of minus sign -- cgit v1.2.3 From f4ed6e3898b0e21cf131533bb9b4511ce82de86a Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Thu, 19 Nov 2015 22:15:59 +0100 Subject: fix for bug 1517740 (crash in some cases in selection sets) Fixed bugs: - https://launchpad.net/bugs/1517740 (bzr r14478) --- src/uri-references.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/uri-references.cpp b/src/uri-references.cpp index b6ccdbf5f..db46a156f 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -19,7 +19,7 @@ #include "uri.h" #include "uri-references.h" #include "extract-uri.h" - +#include "sp-tag-use.h" #include #include @@ -84,7 +84,14 @@ bool URIReference::_acceptObject(SPObject *obj) const positions.push_back(position); owner = owner->parent; } - owner = ((SPUse *)owner)->get_original(); + if (dynamic_cast(owner)) + owner = ((SPUse *)owner)->get_original(); + else if (dynamic_cast(owner)) + owner = ((SPTagUse *)owner)->get_original(); + else { + g_warning("cloned object with no known type\n"); + return false; + } for (int i = positions.size() - 2; i >= 0; i--) owner = owner->childList(false)[positions[i]]; } -- cgit v1.2.3 From 9211d88591d6bbb00a803237cf5c6fa2860e5a96 Mon Sep 17 00:00:00 2001 From: Raphael Rosch Date: Fri, 20 Nov 2015 12:34:03 -0500 Subject: window/task bar icon missing when installed in non-standard location Fixed bugs: - https://launchpad.net/bugs/1516238 (bzr r14479) --- src/main.cpp | 4 ++++ src/path-prefix.h | 2 ++ 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 5393ddc6f..840643a90 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1045,6 +1045,10 @@ sp_main_gui(int argc, char const **argv) gchar *usericondir = Inkscape::Application::profile_path("icons"); gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), usericondir); gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), INKSCAPE_PIXMAPDIR); +#ifdef INKSCAPE_THEMEDIR + gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), INKSCAPE_THEMEDIR); + gtk_icon_theme_rescan_if_needed (gtk_icon_theme_get_default()); +#endif g_free(usericondir); gdk_event_handler_set((GdkEventFunc)snooper, NULL, NULL); diff --git a/src/path-prefix.h b/src/path-prefix.h index 7042d5124..7f9bcec51 100644 --- a/src/path-prefix.h +++ b/src/path-prefix.h @@ -35,6 +35,7 @@ # define INKSCAPE_PATTERNSDIR BR_DATADIR( "/inkscape/patterns" ) # define INKSCAPE_SCREENSDIR BR_DATADIR( "/inkscape/screens" ) # define INKSCAPE_SYMBOLSDIR BR_DATADIR( "/inkscape/symbols" ) +# define INKSCAPE_THEMEDIR BR_DATADIR( "/icons" ) # define INKSCAPE_TUTORIALSDIR BR_DATADIR( "/inkscape/tutorials" ) # define INKSCAPE_TEMPLATESDIR BR_DATADIR( "/inkscape/templates" ) # define INKSCAPE_UIDIR BR_DATADIR( "/inkscape/ui" ) @@ -102,6 +103,7 @@ # define INKSCAPE_PATTERNSDIR INKSCAPE_DATADIR "/inkscape/patterns" # define INKSCAPE_SCREENSDIR INKSCAPE_DATADIR "/inkscape/screens" # define INKSCAPE_SYMBOLSDIR INKSCAPE_DATADIR "/inkscape/symbols" +# define INKSCAPE_THEMEDIR INKSCAPE_DATADIR "/icons" # define INKSCAPE_TUTORIALSDIR INKSCAPE_DATADIR "/inkscape/tutorials" # define INKSCAPE_TEMPLATESDIR INKSCAPE_DATADIR "/inkscape/templates" # define INKSCAPE_UIDIR INKSCAPE_DATADIR "/inkscape/ui" -- cgit v1.2.3 From 37c1a351b7db98d0d09531f811e310615abd955e Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 21 Nov 2015 11:57:48 +0000 Subject: Hide unused verbs if Potrace is not available (bzr r14449.1.7) --- src/menus-skeleton.h | 2 ++ src/shortcuts.cpp | 9 ++++++- src/ui/dialog/inkscape-preferences.cpp | 2 ++ src/ui/dialog/inkscape-preferences.h | 8 +++++++ src/ui/tools-switch.h | 8 +++++++ src/verbs.cpp | 43 ++++++++++++++++++++++++++++++++-- src/verbs.h | 16 +++++++++++++ 7 files changed, 85 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index b02b31bd9..da78f99f1 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -290,7 +290,9 @@ static char const menus_skeleton[] = " \n" " \n" " \n" +#if HAVE_POTRACE " \n" +#endif " \n" " \n" " \n" diff --git a/src/shortcuts.cpp b/src/shortcuts.cpp index e72c16de0..194d4d2a4 100644 --- a/src/shortcuts.cpp +++ b/src/shortcuts.cpp @@ -575,7 +575,14 @@ static void read_shortcuts_file(char const *filename, bool const is_user_set) { } Inkscape::Verb *verb=Inkscape::Verb::getbyid(verb_name); - if (!verb) { + if (!verb +#if !HAVE_POTRACE + // Squash warning about disabled features + && strcmp(verb_name, "ToolPaintBucket") != 0 + && strcmp(verb_name, "SelectionTrace") != 0 + && strcmp(verb_name, "PaintBucketPrefs") != 0 +#endif + ) { g_warning("Unknown verb name: %s", verb_name); continue; } diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index fec49d484..b6d7e25ec 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -478,10 +478,12 @@ void InkscapePreferences::initPageTools() this->AddPage(_page_eraser, _("Eraser"), iter_tools, PREFS_PAGE_TOOLS_ERASER); this->AddNewObjectsStyle(_page_eraser, "/tools/eraser"); +#if HAVE_POTRACE //Paint Bucket this->AddPage(_page_paintbucket, _("Paint Bucket"), iter_tools, PREFS_PAGE_TOOLS_PAINTBUCKET); this->AddSelcueCheckbox(_page_paintbucket, "/tools/paintbucket", false); this->AddNewObjectsStyle(_page_paintbucket, "/tools/paintbucket"); +#endif //Gradient this->AddPage(_page_gradient, _("Gradient"), iter_tools, PREFS_PAGE_TOOLS_GRADIENT); diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 7e0184c55..b7696ab8c 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -15,6 +15,10 @@ #ifndef INKSCAPE_UI_DIALOG_INKSCAPE_PREFERENCES_H #define INKSCAPE_UI_DIALOG_INKSCAPE_PREFERENCES_H +#if HAVE_CONFIG_H +# include "config.h" +#endif + #include #include #include "ui/widget/preferences-widget.h" @@ -56,7 +60,11 @@ enum { PREFS_PAGE_TOOLS_TEXT, PREFS_PAGE_TOOLS_SPRAY, PREFS_PAGE_TOOLS_ERASER, + +#if HAVE_POTRACE PREFS_PAGE_TOOLS_PAINTBUCKET, +#endif + PREFS_PAGE_TOOLS_GRADIENT, PREFS_PAGE_TOOLS_DROPPER, PREFS_PAGE_TOOLS_CONNECTOR, diff --git a/src/ui/tools-switch.h b/src/ui/tools-switch.h index 280837e87..d396597ca 100644 --- a/src/ui/tools-switch.h +++ b/src/ui/tools-switch.h @@ -12,6 +12,10 @@ #ifndef SEEN_TOOLS_SWITCH_H #define SEEN_TOOLS_SWITCH_H +#if HAVE_CONFIG_H +# include "config.h" +#endif + class SPDesktop; class SPItem; namespace Geom { @@ -40,7 +44,11 @@ enum { TOOLS_MEASURE, TOOLS_DROPPER, TOOLS_CONNECTOR, + +#if HAVE_POTRACE TOOLS_PAINTBUCKET, +#endif + TOOLS_ERASER, TOOLS_LPETOOL }; diff --git a/src/verbs.cpp b/src/verbs.cpp index e0ef27b0d..6b13eabb6 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -832,7 +832,14 @@ Verb *Verb::getbyid(gchar const *id) verb = verb_found->second; } - if (verb == NULL) + if (verb == NULL +#if !HAVE_POTRACE + // Squash warning about disabled features + && strcmp(id, "ToolPaintBucket") != 0 + && strcmp(id, "SelectionTrace") != 0 + && strcmp(id, "PaintBucketPrefs") != 0 +#endif + ) printf("Unable to find: %s\n", id); return verb; @@ -1201,10 +1208,14 @@ void SelectionVerb::perform(SPAction *action, void *data) case SP_VERB_SELECTION_REVERSE: SelectionHelper::reverse(dt); break; + +#if HAVE_POTRACE case SP_VERB_SELECTION_TRACE: INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("Trace"); break; +#endif + case SP_VERB_SELECTION_PIXEL_ART: INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("PixelArt"); @@ -1606,7 +1617,7 @@ void ContextVerb::perform(SPAction *action, void *data) /** \todo !!! hopefully this can go away soon and actions can look after * themselves */ - for (vidx = SP_VERB_CONTEXT_SELECT; vidx <= SP_VERB_CONTEXT_PAINTBUCKET_PREFS; vidx++) + for (vidx = SP_VERB_CONTEXT_SELECT; vidx <= SP_VERB_CONTEXT_LPETOOL_PREFS; vidx++) { SPAction *tool_action= get((sp_verb_t)vidx)->get_action(action->context); if (tool_action) { @@ -1673,9 +1684,13 @@ void ContextVerb::perform(SPAction *action, void *data) case SP_VERB_CONTEXT_CONNECTOR: tools_switch(dt, TOOLS_CONNECTOR); break; + +#if HAVE_POTRACE case SP_VERB_CONTEXT_PAINTBUCKET: tools_switch(dt, TOOLS_PAINTBUCKET); break; +#endif + case SP_VERB_CONTEXT_ERASER: tools_switch(dt, TOOLS_ERASER); break; @@ -1759,10 +1774,14 @@ void ContextVerb::perform(SPAction *action, void *data) prefs->setInt("/dialogs/preferences/page", PREFS_PAGE_TOOLS_CONNECTOR); dt->_dlg_mgr->showDialog("InkscapePreferences"); break; + +#if HAVE_POTRACE case SP_VERB_CONTEXT_PAINTBUCKET_PREFS: prefs->setInt("/dialogs/preferences/page", PREFS_PAGE_TOOLS_PAINTBUCKET); dt->_dlg_mgr->showDialog("InkscapePreferences"); break; +#endif + case SP_VERB_CONTEXT_ERASER_PREFS: prefs->setInt("/dialogs/preferences/page", PREFS_PAGE_TOOLS_ERASER); dt->_dlg_mgr->showDialog("InkscapePreferences"); @@ -2160,10 +2179,14 @@ void TutorialVerb::perform(SPAction *action, void *data) // TRANSLATORS: See "tutorial-basic.svg" comment. sp_help_open_tutorial(NULL, (gpointer)_("tutorial-advanced.svg")); break; + +#if HAVE_POTRACE case SP_VERB_TUTORIAL_TRACING: // TRANSLATORS: See "tutorial-basic.svg" comment. sp_help_open_tutorial(NULL, (gpointer)_("tutorial-tracing.svg")); break; +#endif + case SP_VERB_TUTORIAL_TRACING_PIXELART: sp_help_open_tutorial(NULL, (gpointer)_("tutorial-tracing-pixelart.svg")); break; @@ -2593,9 +2616,13 @@ Verb *Verb::_base_verbs[] = { N_("Simplify selected paths (remove extra nodes)"), INKSCAPE_ICON("path-simplify")), new SelectionVerb(SP_VERB_SELECTION_REVERSE, "SelectionReverse", N_("_Reverse"), N_("Reverse the direction of selected paths (useful for flipping markers)"), INKSCAPE_ICON("path-reverse")), + +#if HAVE_POTRACE // TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) new SelectionVerb(SP_VERB_SELECTION_TRACE, "SelectionTrace", N_("_Trace Bitmap..."), N_("Create one or more paths from a bitmap by tracing it"), INKSCAPE_ICON("bitmap-trace")), +#endif + new SelectionVerb(SP_VERB_SELECTION_PIXEL_ART, "SelectionPixelArt", N_("Trace Pixel Art..."), N_("Create paths using Kopf-Lischinski algorithm to vectorize pixel art"), INKSCAPE_ICON("pixelart-trace")), new SelectionVerb(SP_VERB_SELECTION_CREATE_BITMAP, "SelectionCreateBitmap", N_("Make a _Bitmap Copy"), @@ -2733,8 +2760,12 @@ Verb *Verb::_base_verbs[] = { N_("Pick colors from image"), INKSCAPE_ICON("color-picker")), new ContextVerb(SP_VERB_CONTEXT_CONNECTOR, "ToolConnector", NC_("ContextVerb", "Connector"), N_("Create diagram connectors"), INKSCAPE_ICON("draw-connector")), + +#if HAVE_POTRACE new ContextVerb(SP_VERB_CONTEXT_PAINTBUCKET, "ToolPaintBucket", NC_("ContextVerb", "Paint Bucket"), N_("Fill bounded areas"), INKSCAPE_ICON("color-fill")), +#endif + new ContextVerb(SP_VERB_CONTEXT_LPE, "ToolLPE", NC_("ContextVerb", "LPE Edit"), N_("Edit Path Effect parameters"), NULL), new ContextVerb(SP_VERB_CONTEXT_ERASER, "ToolEraser", NC_("ContextVerb", "Eraser"), @@ -2780,8 +2811,12 @@ Verb *Verb::_base_verbs[] = { N_("Open Preferences for the Dropper tool"), NULL), new ContextVerb(SP_VERB_CONTEXT_CONNECTOR_PREFS, "ConnectorPrefs", N_("Connector Preferences"), N_("Open Preferences for the Connector tool"), NULL), + +#if HAVE_POTRACE new ContextVerb(SP_VERB_CONTEXT_PAINTBUCKET_PREFS, "PaintBucketPrefs", N_("Paint Bucket Preferences"), N_("Open Preferences for the Paint Bucket tool"), NULL), +#endif + new ContextVerb(SP_VERB_CONTEXT_ERASER_PREFS, "EraserPrefs", N_("Eraser Preferences"), N_("Open Preferences for the Eraser tool"), NULL), new ContextVerb(SP_VERB_CONTEXT_LPETOOL_PREFS, "LPEToolPrefs", N_("LPE Tool Preferences"), @@ -2937,9 +2972,13 @@ Verb *Verb::_base_verbs[] = { N_("Using shape tools to create and edit shapes"), NULL), new TutorialVerb(SP_VERB_TUTORIAL_ADVANCED, "TutorialsAdvanced", N_("Inkscape: _Advanced"), N_("Advanced Inkscape topics"), NULL/*"tutorial_advanced"*/), + +#if HAVE_POTRACE // TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) new TutorialVerb(SP_VERB_TUTORIAL_TRACING, "TutorialsTracing", N_("Inkscape: T_racing"), N_("Using bitmap tracing"), NULL/*"tutorial_tracing"*/), +#endif + new TutorialVerb(SP_VERB_TUTORIAL_TRACING_PIXELART, "TutorialsTracingPixelArt", N_("Inkscape: Tracing Pixel Art"), N_("Using Trace Pixel Art dialog"), NULL), new TutorialVerb(SP_VERB_TUTORIAL_CALLIGRAPHY, "TutorialsCalligraphy", N_("Inkscape: _Calligraphy"), diff --git a/src/verbs.h b/src/verbs.h index 06fc4fb05..27aecae64 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -136,7 +136,11 @@ enum { SP_VERB_SELECTION_OUTLINE, SP_VERB_SELECTION_SIMPLIFY, SP_VERB_SELECTION_REVERSE, + +#if HAVE_POTRACE SP_VERB_SELECTION_TRACE, +#endif + SP_VERB_SELECTION_PIXEL_ART, SP_VERB_SELECTION_CREATE_BITMAP, SP_VERB_SELECTION_COMBINE, @@ -203,7 +207,11 @@ enum { SP_VERB_CONTEXT_MEASURE, SP_VERB_CONTEXT_DROPPER, SP_VERB_CONTEXT_CONNECTOR, + +#if HAVE_POTRACE SP_VERB_CONTEXT_PAINTBUCKET, +#endif + SP_VERB_CONTEXT_LPE, /* not really a tool but used for editing LPE parameters on-canvas for example */ SP_VERB_CONTEXT_ERASER, SP_VERB_CONTEXT_LPETOOL, /* note that this is very different from SP_VERB_CONTEXT_LPE above! */ @@ -227,7 +235,11 @@ enum { SP_VERB_CONTEXT_MEASURE_PREFS, SP_VERB_CONTEXT_DROPPER_PREFS, SP_VERB_CONTEXT_CONNECTOR_PREFS, + +#if HAVE_POTRACE SP_VERB_CONTEXT_PAINTBUCKET_PREFS, +#endif + SP_VERB_CONTEXT_ERASER_PREFS, SP_VERB_CONTEXT_LPETOOL_PREFS, /* Zooming and desktop settings */ @@ -311,7 +323,11 @@ enum { SP_VERB_TUTORIAL_BASIC, SP_VERB_TUTORIAL_SHAPES, SP_VERB_TUTORIAL_ADVANCED, + +#if HAVE_POTRACE SP_VERB_TUTORIAL_TRACING, +#endif + SP_VERB_TUTORIAL_TRACING_PIXELART, SP_VERB_TUTORIAL_CALLIGRAPHY, SP_VERB_TUTORIAL_INTERPOLATE, -- cgit v1.2.3 From bbce0bf3da568e49af0112166e57df00e2b8bb6b Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 21 Nov 2015 13:41:55 +0000 Subject: src/Makefile.am: Rm notes about tests that have been fixed (bzr r14481) --- src/Makefile.am | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 04e33c471..27d4fb844 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -259,9 +259,7 @@ check-local: # the XFAIL_TESTS build target should be removed. # See the following Launchpad bugs: # -# LP #1202271 # LP #1208013 -# LP #1208002 # LP #1208005 # LP #1207502 -- cgit v1.2.3 From b3cfa57e9a646fdabfda1f32e1bcc2a1ac396542 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 23 Nov 2015 14:25:10 +0100 Subject: Correct return value. (bzr r14484) --- src/sp-mesh-array.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index d76b884ae..355150893 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -2330,6 +2330,7 @@ guint SPMeshNodeArray::color_pick( std::vector icorners, SPItem* item ) { pick_doc->getRoot()->invoke_hide(pick_visionkey); delete pick_drawing; + picked = 1; // Picking always happens if( picked > 0 ) built = false; return picked; } -- cgit v1.2.3 From 3072259d86819390ae254347586f801e64853eb1 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 24 Nov 2015 10:24:52 +0100 Subject: Remove unneeded header. (bzr r14485) --- src/libnrtype/font-lister.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 70374864a..568a7c8cc 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include "font-lister.h" -- cgit v1.2.3 From ae79787329b6f01f52591a70c2b4ccfae9fec14d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 24 Nov 2015 10:25:42 +0100 Subject: Change context from gradient to mesh. (bzr r14486) --- src/widgets/mesh-toolbar.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp index 4e0b6d68b..9937b23ed 100644 --- a/src/widgets/mesh-toolbar.cpp +++ b/src/widgets/mesh-toolbar.cpp @@ -292,6 +292,9 @@ static void ms_col_changed(GtkAdjustment *adj, GObject * /*tbl*/ ) blocked = FALSE; } +/** + * Sets mesh type: Coons, Bicubic + */ static void ms_type_changed(EgeSelectOneAction *act, GtkWidget *widget) { // std::cout << "ms_type_changed" << std::endl; @@ -311,7 +314,7 @@ static void ms_type_changed(EgeSelectOneAction *act, GtkWidget *widget) gradient->type_set = true; gradient->updateRepr(); - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, _("Set mesh type")); } } -- cgit v1.2.3 From 43189db24ea0e36e60007be56daab50a1e0cc52a Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 24 Nov 2015 17:47:17 +0100 Subject: Use deprecated constant to maintain backwards compatibility with freetype 2.4. (bzr r14488) --- src/libnrtype/FontInstance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index f0b87efa7..7a16fc0c3 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -744,7 +744,7 @@ void font_instance::FindFontMetrics() { if ( theFace->units_per_EM != 0 ) { // If zero then it's a bitmap font. - TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table( theFace, FT_SFNT_OS2 ); + TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table( theFace, ft_sfnt_os2 ); if( os2 ) { _ascent = fabs(((double)os2->sTypoAscender) / ((double)theFace->units_per_EM)); _descent = fabs(((double)os2->sTypoDescender)/ ((double)theFace->units_per_EM)); -- cgit v1.2.3 From b2f49404d1fcffc1627c76a1f053a457637de7b3 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Wed, 25 Nov 2015 02:05:31 +0100 Subject: fixes infinite loop due to buggy recursion in flattening function Fixed bugs: - https://launchpad.net/bugs/1519547 (bzr r14489) --- src/document.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 0e49f23e2..23d99d78c 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1337,20 +1337,25 @@ SPItem *SPDocument::getItemFromListAtPointBottom(unsigned int dkey, SPGroup *gro /** Turn the SVG DOM into a flat list of nodes that can be searched from top-down. The list can be persisted, which improves "find at multiple points" speed. +Returns true if upto is reached. */ -static void build_flat_item_list(std::deque *nodes, unsigned int dkey, SPGroup *group, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL) +static bool build_flat_item_list(std::deque *nodes, unsigned int dkey, SPGroup *group, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL) { + bool found_upto = false; for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) { if (!SP_IS_ITEM(o)) { continue; } if (upto && SP_ITEM(o) == upto) { + found_upto = true; break; } if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { - build_flat_item_list(nodes, dkey, SP_GROUP(o), into_groups, take_insensitive, upto); + found_upto = build_flat_item_list(nodes, dkey, SP_GROUP(o), into_groups, take_insensitive, upto); + if (found_upto) + break; } else { SPItem *child = SP_ITEM(o); @@ -1359,6 +1364,7 @@ static void build_flat_item_list(std::deque *nodes, unsigned int dkey, } } } + return found_upto; } /** -- cgit v1.2.3 From a04c4d8187fcae59a6d3fe4bd215304dcfa15619 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 25 Nov 2015 11:16:15 +0100 Subject: Remove unused headers. (bzr r14490) --- src/widgets/pencil-toolbar.cpp | 2 -- src/widgets/spray-toolbar.cpp | 2 -- 2 files changed, 4 deletions(-) (limited to 'src') diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index 17c1d341d..aed80a66f 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -34,7 +34,6 @@ #include "pencil-toolbar.h" #include "desktop.h" -#include "document-undo.h" #include "widgets/ege-adjustment-action.h" #include "widgets/ege-select-one-action.h" #include "widgets/ink-action.h" @@ -57,7 +56,6 @@ #include "util/glib-list-iterators.h" using Inkscape::UI::UXManager; -using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; using Inkscape::UI::PrefPusher; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 1774ba418..30e9c6418 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -34,7 +34,6 @@ #include "spray-toolbar.h" #include "desktop.h" #include "inkscape.h" -#include "document-undo.h" #include "widgets/ege-adjustment-action.h" #include "widgets/ege-select-one-action.h" #include "widgets/ink-action.h" @@ -47,7 +46,6 @@ #include -using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; using Inkscape::UI::PrefPusher; -- cgit v1.2.3 From b3595c96864bd1e5f8e641fbd6444d7c92deaeba Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 25 Nov 2015 11:16:49 +0100 Subject: Fix undo of mesh creation. (bzr r14491) --- src/ui/tools/mesh-tool.cpp | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index 303757493..794296329 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -57,7 +57,7 @@ namespace Inkscape { namespace UI { namespace Tools { -static void sp_mesh_drag(MeshTool &rc, Geom::Point const pt, guint state, guint32 etime); +static void sp_mesh_end_drag(MeshTool &rc); const std::string& MeshTool::getPrefsPath() { return MeshTool::prefsPath; @@ -560,8 +560,9 @@ bool MeshTool::root_handler(GdkEvent* event) { Inkscape::Rubberband::get(desktop)->move(motion_dt); this->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Draw around handles to select them")); } else { - // Create new gradient with coordinates determined by drag. - sp_mesh_drag(*this, motion_dt, event->motion.state, event->motion.time); + // Do nothing. For a linear/radial gradient we follow the drag, updating the + // gradient as the end node is dragged. For a mesh gradient, the gradient is always + // created to fill the object when the drag ends. } gobble_motion_events(GDK_BUTTON1_MASK); @@ -649,7 +650,7 @@ bool MeshTool::root_handler(GdkEvent* event) { } if (!this->within_tolerance) { - // we've been dragging, either do nothing (grdrag handles that), + // we've been dragging, either create a new gradient // or rubberband-select if we have rubberband Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop); @@ -659,6 +660,9 @@ bool MeshTool::root_handler(GdkEvent* event) { Geom::OptRect const b = r->getRectangle(); drag->selectRect(*b); } + } else { + // Create a new mesh gradient + sp_mesh_end_drag(*this); } } else if (this->item_to_select) { if (over_line && line) { @@ -922,7 +926,7 @@ bool MeshTool::root_handler(GdkEvent* event) { return ret; } -static void sp_mesh_drag(MeshTool &rc, Geom::Point const /*pt*/, guint /*state*/, guint32 /*etime*/) { +static void sp_mesh_end_drag(MeshTool &rc) { SPDesktop *desktop = SP_EVENT_CONTEXT(&rc)->desktop; Inkscape::Selection *selection = desktop->getSelection(); SPDocument *document = desktop->getDocument(); @@ -963,19 +967,8 @@ static void sp_mesh_drag(MeshTool &rc, Geom::Point const /*pt*/, guint /*state*/ (*i)->requestModified(SP_OBJECT_MODIFIED_FLAG); } - // if (ec->_grdrag) { - // ec->_grdrag->updateDraggers(); - // // prevent regenerating draggers by selection modified signal, which sometimes - // // comes too late and thus destroys the knot which we will now grab: - // ec->_grdrag->local_change = true; - // // give the grab out-of-bounds values of xp/yp because we're already dragging - // // and therefore are already out of tolerance - // ec->_grdrag->grabKnot (SP_ITEM(selection->itemList()->data), - // type == SP_GRADIENT_TYPE_LINEAR? POINT_LG_END : POINT_RG_R1, - // -1, // ignore number (though it is always 1) - // fill_or_stroke, 99999, 99999, etime); - // } - // We did an undoable action, but SPDocumentUndo::done will be called by the knot when released + + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, _("Create mesh")); // status text; we do not track coords because this branch is run once, not all the time // during drag -- cgit v1.2.3 From b8e75b7f3780e0a5c72ad6507ac0a92d285deead Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 26 Nov 2015 22:59:19 -0800 Subject: Reimplement the functions in src/xml/quote.cpp to clear up license. This file was one of the very few that was marked as GPL v2 only, which prevents us from declaring GPL v2+ licensing. (bzr r14492) --- src/xml/quote.cpp | 118 ++++++++++++++++++++++++++---------------------------- 1 file changed, 57 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/xml/quote.cpp b/src/xml/quote.cpp index 02c12dfb0..b889b890d 100644 --- a/src/xml/quote.cpp +++ b/src/xml/quote.cpp @@ -1,81 +1,77 @@ /** \file - * XML quoting routines. - */ - -/* Based on Lauris' repr_quote_write in repr-io.cpp. - * - * Copyright (C) 1999-2002 Lauris Kaplinski - * Copyright (C) 2004 Monash University - * - * May be modified and/or redistributed under the terms of version 2 - * of the GNU General Public License: see the file `COPYING'. + * @brief XML quoting routines + *//* + * Authors: + * Krzysztof Kosiński + * + * This file is in the public domain. */ +#include "xml/quote.h" #include #include -#include "quote.h" - -/** \return strlen(xml_quote_strdup(\a val)) (without doing the malloc). - * \pre val != NULL - */ -size_t -xml_quoted_strlen(char const *val) +/// Returns the length of the string after quoting the characters "&<>. +size_t xml_quoted_strlen(char const *val) { - size_t ret = 0; - if (val != NULL) { - for (; *val != '\0'; val++) { - switch (*val) { - case '"': ret += sizeof(""") - 1; break; - case '&': ret += sizeof("&") - 1; break; - case '<': ret += sizeof("<") - 1; break; - case '>': ret += sizeof(">") - 1; break; - default: ++ret; break; - } + if (!val) return 0; + size_t len = 0; + + for (char const *valp = val; *valp; ++valp) { + switch (*valp) { + case '"': + len += 6; // " + break; + case '&': + len += 5; // & + break; + case '<': + case '>': + len += 4; // < or > + break; + default: + ++len; + break; } } - return ret; + return len; } -/** Writes \a src (including the NUL byte) to \a dest, doing XML quoting as necessary. - * - * \pre \a src != NULL. - * \pre \a dest must have enough space for (xml_quoted_strlen(src) + 1) bytes. - */ -static void -xml_quote(char *dest, char const *src) +char *xml_quote_strdup(char const *src) { -#define COPY_LIT(_lit) do { \ - size_t cpylen = sizeof(_lit "") - 1; \ - memcpy(dest, _lit, cpylen); \ - dest += cpylen; \ - } while(0) + size_t len = xml_quoted_strlen(src); + char *result = static_cast(g_malloc(len + 1)); + char *resp = result; - for (; *src != '\0'; ++src) { - switch (*src) { - case '"': COPY_LIT("""); break; - case '&': COPY_LIT("&"); break; - case '<': COPY_LIT("<"); break; - case '>': COPY_LIT(">"); break; - default: *dest++ = *src; break; + for (char const *srcp = src; *srcp; ++srcp) { + switch(*srcp) { + case '"': + strcpy(resp, """); + resp += 6; + break; + case '&': + strcpy(resp, "&"); + resp += 5; + break; + case '<': + strcpy(resp, "<"); + resp += 4; + break; + case '>': + strcpy(resp, ">"); + resp += 4; + break; + default: + *resp++ = *srcp; + break; } } - *dest = '\0'; - -#undef COPY_LIT + *resp = 0; + return result; } -/** \return A g_malloc'd buffer containing an XML-quoted version of \a src. - * \pre src != NULL. - */ -char * -xml_quote_strdup(char const *src) -{ - size_t const quoted_size = xml_quoted_strlen(src) + 1; - char *ret = (char *) g_malloc(quoted_size); - xml_quote(ret, src); - return ret; -} +// quote: ", &, <, > + /* Local Variables: -- cgit v1.2.3 From ed0cc33f8ffa68b71218fdf17f53c19a63d2de55 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 30 Nov 2015 16:26:14 +0100 Subject: Correct position of lines in multi-line text when some lines have different font sizes. Correctly handle vertical left to right and right to left text. (bzr r14494) --- src/libnrtype/Layout-TNG-Compute.cpp | 35 ++++++++++++++++++++-------- src/libnrtype/Layout-TNG-Scanline-Makers.cpp | 8 +++---- 2 files changed, 29 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 2ae13efa6..cd86d2450 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -475,14 +475,18 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ Layout::Line new_line; new_line.in_paragraph = _flow._paragraphs.size() - 1; new_line.baseline_y = _scanline_maker->yCoordinate(); - if( !_flow._input_wrap_shapes.empty() ) { - // Flowed text - if( _block_progression == RIGHT_TO_LEFT || _block_progression == LEFT_TO_RIGHT ) { - // Vertical text, use em box center as baseline - new_line.baseline_y += 0.5 * line_height.emSize(); - } else { - new_line.baseline_y += line_height.getTypoAscent(); - } + + // The y coordinate is at the beginning edge of the line box (top for horizontal text, left + // edge for vertical lr text, right edge for vertical rl text. We align, by default to the + // alphabetic baseline for horizontal text and the central baseline for vertical text. + if( _block_progression == RIGHT_TO_LEFT ) { + // Vertical text, use em box center as baseline + new_line.baseline_y -= 0.5 * line_height.emSize(); + } else if ( _block_progression == LEFT_TO_RIGHT ) { + // Vertical text, use em box center as baseline + new_line.baseline_y += 0.5 * line_height.emSize(); + } else { + new_line.baseline_y += line_height.getTypoAscent(); } new_line.in_shape = _current_shape_index; @@ -533,8 +537,19 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ // Save baseline _flow._lines.back().baseline_y = new_line.baseline_y; - // Set the initial y coordinate of the next line. - _scanline_maker->setNewYCoordinate(new_line.baseline_y); + double top_of_line_box = new_line.baseline_y; + if( _block_progression == RIGHT_TO_LEFT ) { + // Vertical text, use em box center as baseline + top_of_line_box += 0.5 * line_height.emSize(); + } else if (_block_progression == LEFT_TO_RIGHT ) { + // Vertical text, use em box center as baseline + top_of_line_box -= 0.5 * line_height.emSize(); + } else { + top_of_line_box -= line_height.getTypoAscent(); + } + + // Set the initial y coordinate of the next line (see above). + _scanline_maker->setNewYCoordinate(top_of_line_box); } // Reset relative y_offset ("dy" attribute is relative but should be reset at diff --git a/src/libnrtype/Layout-TNG-Scanline-Makers.cpp b/src/libnrtype/Layout-TNG-Scanline-Makers.cpp index 67fffd620..ea487a597 100644 --- a/src/libnrtype/Layout-TNG-Scanline-Makers.cpp +++ b/src/libnrtype/Layout-TNG-Scanline-Makers.cpp @@ -141,7 +141,7 @@ std::vector Layout::ShapeScanlineMaker::makeScan std::vector result(1); result[0].x_start = line_rasterization.runs[0].st; result[0].x_end = line_rasterization.runs[0].st; - result[0].y = _negative_block_progression ? -_current_line_height - _y : _y; + result[0].y = _negative_block_progression ? - _y : _y; return result; } @@ -150,7 +150,7 @@ std::vector Layout::ShapeScanlineMaker::makeScan for (unsigned i = 0 ; i < result.size() ; i++) { result[i].x_start = line_decent_length_runs.runs[i].st; result[i].x_end = line_decent_length_runs.runs[i].en; - result[i].y = _negative_block_progression ? -_current_line_height - _y : _y; + result[i].y = _negative_block_progression ? - _y : _y; } return result; @@ -163,14 +163,14 @@ void Layout::ShapeScanlineMaker::completeLine() double Layout::ShapeScanlineMaker::yCoordinate() { - if (_negative_block_progression) return -_current_line_height - _y; + if (_negative_block_progression) return - _y; return _y; } void Layout::ShapeScanlineMaker::setNewYCoordinate(double new_y) { _y = (float)new_y; - if (_negative_block_progression) _y = -_current_line_height - _y; + if (_negative_block_progression) _y = - _y; // what will happen with the rasteriser if we move off the shape? // it's not an important question because doesn't have a y attribute } -- cgit v1.2.3 From 50e28d20c9262114fa1e5e10dfbce20ffdffe65b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Nov 2015 20:44:50 +0100 Subject: Bug fixes for simplify LPE and applied fix also affected #166937 (bzr r14495) --- src/live_effects/lpe-simplify.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 2d79d5b34..a919756df 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -28,8 +28,8 @@ namespace LivePathEffect { LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) : Effect(lpeobject), steps(_("Steps:"),_("Change number of simplify steps "), "steps", &wr, this,1), - threshold(_("Roughly threshold:"), _("Roughly threshold:"), "threshold", &wr, this, 0.003), - smooth_angles(_("Smooth angles:"), _("Max degree difference on handles to perform a smooth"), "smooth_angles", &wr, this, 20.), + threshold(_("Roughly threshold:"), _("Roughly threshold:"), "threshold", &wr, this, 0.002), + smooth_angles(_("Smooth angles:"), _("Max degree difference on handles to perform a smooth"), "smooth_angles", &wr, this, 0.), helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 5), simplify_individual_paths(_("Paths separately"), _("Simplifying paths (separately)"), "simplify_individual_paths", &wr, this, false, "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), @@ -51,7 +51,7 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) steps.param_set_increments(1, 1); steps.param_set_digits(0); - smooth_angles.param_set_range(0.0, 365.0); + smooth_angles.param_set_range(0.0, 360.0); smooth_angles.param_set_increments(10, 10); smooth_angles.param_set_digits(2); @@ -138,6 +138,7 @@ LPESimplify::doEffect(SPCurve *curve) if(simplify_individual_paths) { size = Geom::L2(Geom::bounds_fast(original_pathv)->dimensions()); } + size /= sp_lpe_item->i2doc_affine().descrim(); for (int unsigned i = 0; i < steps; i++) { if ( simplify_just_coalesce ) { pathliv->Coalesce(threshold * size); @@ -198,13 +199,15 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) Geom::Point point_at2 = curve_it1->finalPoint(); Geom::Point point_at3 = curve_it1->finalPoint(); Geom::Point point_at4 = curve_it1->finalPoint(); + + if(start == Geom::Point(0,0)) { + start = point_at1; + } + if (cubic) { point_at1 = (*cubic)[1]; point_at2 = (*cubic)[2]; } - if(start == Geom::Point(0,0)) { - start = point_at1; - } if(path_it->closed() && curve_it2 == curve_endit) { point_at4 = start; @@ -219,11 +222,11 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) Geom::Ray ray2(point_at3, point_at4); double angle1 = Geom::rad_to_deg(ray1.angle()); double angle2 = Geom::rad_to_deg(ray2.angle()); - if((smooth_angles >= angle2 - angle1) && !are_near(point_at4,point_at3) && !are_near(point_at2,point_at3)) { + if((smooth_angles >= std::abs(angle2 - angle1)) && !are_near(point_at4,point_at3) && !are_near(point_at2,point_at3)) { double dist = Geom::distance(point_at2,point_at3); Geom::Angle angleFixed = ray2.angle(); angleFixed -= Geom::Angle::from_degrees(180.0); - point_at2 = Geom::Point::polar(angleFixed,dist) + point_at3; + point_at2 = Geom::Point::polar(angleFixed, dist) + point_at3; } nCurve->curveto(point_at1, point_at2, curve_it1->finalPoint()); cubic = dynamic_cast(nCurve->last_segment()); -- cgit v1.2.3 From 3fc8a303e78687b106ed9f726657b529f63de5bd Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 2 Dec 2015 17:22:45 +0100 Subject: Correct line spacing for text in a shape when various font-sizes present. (bzr r14499) --- src/libnrtype/Layout-TNG-Compute.cpp | 101 +++++++++++++++++---------- src/libnrtype/Layout-TNG-Scanline-Maker.h | 16 +++++ src/libnrtype/Layout-TNG-Scanline-Makers.cpp | 10 +++ 3 files changed, 91 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index cd86d2450..6b2a6f622 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -243,7 +243,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ bool _goToNextWrapShape(); bool _findChunksForLine(ParagraphInfo const ¶, UnbrokenSpanPosition *start_span_pos, - std::vector *chunk_info, FontMetrics *line_height); + std::vector *chunk_info, FontMetrics *line_box_height); static inline PangoLogAttr const &_charAttributes(ParagraphInfo const ¶, UnbrokenSpanPosition const &span_pos) @@ -270,6 +270,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ or will be unaltered if there is none. */ bool _measureUnbrokenSpan(ParagraphInfo const ¶, BrokenSpan *span, BrokenSpan *last_break_span, BrokenSpan *last_emergency_break_span, double maximum_width) const { + TRACE((" start _measureUnbrokenSpan %g\n", maximum_width)); span->setZero(); if (span->start.iter_span->dx._set && span->start.char_byte == 0){ @@ -296,7 +297,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ if (control_code->code == ARBITRARY_GAP) { if (span->width + control_code->width > maximum_width) return false; - TRACE(("fitted control code, width = %f\n", control_code->width)); + TRACE((" fitted control code, width = %f\n", control_code->width)); span->width += control_code->width; span->end.increment(); } @@ -335,12 +336,14 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ PangoLogAttr const &char_attributes = _charAttributes(para, span->end); if (char_attributes.is_mandatory_break && span->end != span->start) { + TRACE((" is_mandatory_break ************\n")); *last_emergency_break_span = *last_break_span = *span; - TRACE(("span %ld end of para; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + TRACE((" span %ld end of para; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); return false; } if (char_attributes.is_line_break) { + TRACE((" is_line_break ************\n")); // a suitable position to break at, record where we are *last_emergency_break_span = *last_break_span = *span; if (soft_hyphen_in_word) { @@ -405,13 +408,14 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ span->word_spacing = text_source->style->word_spacing.computed; if (test_width > maximum_width && !char_attributes.is_white) { // whitespaces don't matter, we can put as many as we want at eol - TRACE(("span %ld exceeded scanrun; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + TRACE((" span %ld exceeded scanrun; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); return false; } } while (span->end.char_byte != 0); // while we haven't wrapped to the next span - TRACE(("fitted span %ld width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + TRACE((" fitted span %ld width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + TRACE((" end _measureUnbrokenSpan %g\n", maximum_width)); return true; } @@ -464,14 +468,14 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ */ void _outputLine(ParagraphInfo const ¶, FontMetrics const &line_height, std::vector const &chunk_info) { - TRACE(("Start _outputLine\n")); + TRACE((" Start _outputLine: ascent %f, descent %f, top of box %f\n", line_height.ascent, line_height.descent, _scanline_maker->yCoordinate() )); if (chunk_info.empty()) { - TRACE(("line too short to fit anything on it, go to next\n")); + TRACE((" line too short to fit anything on it, go to next\n")); return; } // we've finished fiddling about with ascents and descents: create the output - TRACE(("found line fit; creating output\n")); + TRACE((" found line fit; creating output\n")); Layout::Line new_line; new_line.in_paragraph = _flow._paragraphs.size() - 1; new_line.baseline_y = _scanline_maker->yCoordinate(); @@ -498,7 +502,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ // add the chunk to the list Layout::Chunk new_chunk; new_chunk.in_line = _flow._lines.size() - 1; - TRACE((" New chunk: in_line: %d\n", new_chunk.in_line)); + TRACE((" New chunk: in_line: %d\n", new_chunk.in_line)); new_chunk.left_x = _getChunkLeftWithAlignment(para, it_chunk, &add_to_each_whitespace); // we may also have y move orders to deal with here (dx, dy and rotate are done per span) @@ -547,7 +551,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ } else { top_of_line_box -= line_height.getTypoAscent(); } - + TRACE((" y attribute set, next line top_of_line_box: %f\n", top_of_line_box )); // Set the initial y coordinate of the next line (see above). _scanline_maker->setNewYCoordinate(top_of_line_box); } @@ -853,7 +857,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ } // end adding spans to the list, on to the next chunk... } - TRACE(("output done\n")); + TRACE((" End _outputLine\n")); } /* *********************************************************************************************************/ @@ -1442,16 +1446,18 @@ bool Layout::Calculator::_goToNextWrapShape() * bits of information that will prove useful when we come to output the * line to #_flow. Returns with \a start_span_pos set to the end of the * text that was fitted, \a chunk_info completely filled out and - * \a line_height set to the largest line box on the line. The return + * \a line_box_height set with the largest ascent and the largest + * descent (individually per CSS) on the line. The return * value is false only if we've run out of shapes to wrap inside (and * hence couldn't create any chunks). */ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, UnbrokenSpanPosition *start_span_pos, std::vector *chunk_info, - FontMetrics *line_height) + FontMetrics *line_box_height) { - // init the initial line_height + TRACE((" begin _findChunksForLine: chunks: %lu\n", chunk_info->size())); + // init the initial line_box_height if (start_span_pos->iter_span == para.unbroken_spans.end()) { if (_flow._spans.empty()) { // empty first para: create a font for the sole purpose of measuring it @@ -1459,42 +1465,44 @@ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, font_instance *font = text_source->styleGetFontInstance(); if (font) { double multiplier = _computeFontLineHeight(text_source->style); - line_height->set( font ); - *line_height *= text_source->style->font_size.computed; + line_box_height->set( font ); + *line_box_height *= text_source->style->font_size.computed; font->Unref(); - *line_height *= multiplier; - _scanline_maker->setNewYCoordinate(_scanline_maker->yCoordinate() - line_height->ascent); + line_box_height->computeEffective( multiplier ); + TRACE((" initial next line top_of_line_box: %f\n", _scanline_maker->yCoordinate() - line_box_height->ascent )); + _scanline_maker->setNewYCoordinate(_scanline_maker->yCoordinate() - line_box_height->ascent); } } // else empty subsequent para: keep the old line height } else { if (_flow._input_wrap_shapes.empty()) { - // if we're not wrapping set the line_height big and negative so we can use negative line height - line_height->ascent = -1.0e10; - line_height->descent = -1.0e10; + // if we're not wrapping set the line_box_height big and negative so we can use negative line height + line_box_height->ascent = -1.0e10; + line_box_height->descent = -1.0e10; } else - line_height->setZero(); + line_box_height->setZero(); } + TRACE((" initial line_box_height: %f\n", line_box_height->emSize() )); UnbrokenSpanPosition span_pos; for( ; ; ) { std::vector scan_runs; - scan_runs = _scanline_maker->makeScanline(*line_height); // Only one line with "InfiniteScanlineMaker + scan_runs = _scanline_maker->makeScanline(*line_box_height); // Only one line with "InfiniteScanlineMaker while (scan_runs.empty()) { // Only used by ShapeScanlineMaker if (!_goToNextWrapShape()) return false; // no more shapes to wrap in to - scan_runs = _scanline_maker->makeScanline(*line_height); + scan_runs = _scanline_maker->makeScanline(*line_box_height); } - TRACE(("finding line fit y=%f, %lu scan runs\n", scan_runs.front().y, scan_runs.size())); + TRACE((" finding line fit y=%f, %lu scan runs\n", scan_runs.front().y, scan_runs.size())); chunk_info->clear(); chunk_info->reserve(scan_runs.size()); if (para.direction == RIGHT_TO_LEFT) std::reverse(scan_runs.begin(), scan_runs.end()); unsigned scan_run_index; span_pos = *start_span_pos; for (scan_run_index = 0 ; scan_run_index < scan_runs.size() ; scan_run_index++) { - if (!_buildChunksInScanRun(para, span_pos, scan_runs[scan_run_index], chunk_info, line_height)) + if (!_buildChunksInScanRun(para, span_pos, scan_runs[scan_run_index], chunk_info, line_box_height)) break; if (!chunk_info->empty() && !chunk_info->back().broken_spans.empty()) span_pos = chunk_info->back().broken_spans.back().end; @@ -1502,6 +1510,8 @@ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, if (scan_run_index == scan_runs.size()) break; // ie when buildChunksInScanRun() succeeded } *start_span_pos = span_pos; + TRACE((" final line_box_height: %f\n", line_box_height->emSize() )); + TRACE((" end _findChunksForLine: chunks: %lu\n", chunk_info->size())); return true; } @@ -1525,6 +1535,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, std::vector *chunk_info, FontMetrics *line_height) const { + TRACE((" begin _buildChunksInScanRun: chunks: %lu\n", chunk_info->size())); ChunkInfo new_chunk; new_chunk.text_width = 0.0; new_chunk.whitespace_count = 0; @@ -1538,7 +1549,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, last_span_at_emergency_break.start = start_span_pos; last_span_at_emergency_break.setZero(); - TRACE(("trying chunk from %f to %g\n", scan_run.x_start, scan_run.x_end)); + TRACE((" trying chunk from %f to %g\n", scan_run.x_start, scan_run.x_end)); BrokenSpan new_span; new_span.end = start_span_pos; while (new_span.end.iter_span != para.unbroken_spans.end()) { // this loops once for each UnbrokenSpan @@ -1587,7 +1598,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, } } - TRACE(("chunk complete, used %f width (%d whitespaces, %lu brokenspans)\n", new_chunk.text_width, new_chunk.whitespace_count, new_chunk.broken_spans.size())); + TRACE((" chunk complete, used %f width (%d whitespaces, %lu brokenspans)\n", new_chunk.text_width, new_chunk.whitespace_count, new_chunk.broken_spans.size())); chunk_info->push_back(new_chunk); if (scan_run.width() >= 4.0 * line_height->emSize() && last_span_at_break.end == start_span_pos) { @@ -1625,12 +1636,25 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, chunk_info->back().text_width += last_span_at_break.width; chunk_info->back().whitespace_count += last_span_at_break.whitespace_count; } - TRACE(("correction: fitted span %lu width = %f\n", last_span_at_break.start.iter_span - para.unbroken_spans.begin(), last_span_at_break.width)); + TRACE((" correction: fitted span %lu width = %f\n", last_span_at_break.start.iter_span - para.unbroken_spans.begin(), last_span_at_break.width)); + } + } + + // Recalculate line_box_height after backing out chunks + line_height->setZero(); + for (std::vector::const_iterator it_chunk = chunk_info->begin() ; it_chunk != chunk_info->end() ; it_chunk++) { + for (std::vector::const_iterator it_span = it_chunk->broken_spans.begin() ; it_span != it_chunk->broken_spans.end() ; it_span++) { + TRACE((" brokenspan line_height: %f\n", it_span->start.iter_span->line_height.emSize() )); + FontMetrics span_height = it_span->start.iter_span->line_height; + span_height.computeEffective( it_span->start.iter_span->line_height_multiplier ); + line_height->max( span_height ); } } + TRACE((" line_box_height: %f\n", line_height->emSize())); if (!chunk_info->empty() && !chunk_info->back().broken_spans.empty() && chunk_info->back().broken_spans.back().ends_with_whitespace) { // for justification we need to discard space occupied by the single whitespace at the end of the chunk + TRACE((" backing out whitespace\n")); chunk_info->back().broken_spans.back().ends_with_whitespace = false; chunk_info->back().broken_spans.back().width -= chunk_info->back().broken_spans.back().each_whitespace_width; chunk_info->back().broken_spans.back().whitespace_count--; @@ -1642,9 +1666,10 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, // for justification we need to discard line-spacing and word-spacing at end of the chunk chunk_info->back().broken_spans.back().width -= chunk_info->back().broken_spans.back().letter_spacing; chunk_info->back().text_width -= chunk_info->back().broken_spans.back().letter_spacing; - TRACE(("width after subtracting last letter_spacing: %f\n", chunk_info->back().broken_spans.back().width)); + TRACE((" width after subtracting last letter_spacing: %f\n", chunk_info->back().broken_spans.back().width)); } + TRACE((" end _buildChunksInScanRun: chunks: %lu\n", chunk_info->size())); return true; } @@ -1664,7 +1689,7 @@ bool Layout::Calculator::calculate() g_warning("flow text is not of type TEXT_SOURCE. Abort."); return false; } - TRACE(("begin calculateFlow()\n")); + TRACE(("begin calculate()\n")); _flow._clearOutputObjects(); @@ -1689,7 +1714,7 @@ bool Layout::Calculator::calculate() _createFirstScanlineMaker(); ParagraphInfo para; - FontMetrics line_height; // needs to be maintained across paragraphs to be able to deal with blank paras + FontMetrics line_box_height; // needs to be maintained across paragraphs to be able to deal with blank paras for(para.first_input_index = 0 ; para.first_input_index < _flow._input_stream.size() ; ) { // jump to the next wrap shape if this is a SHAPE_BREAK control code if (_flow._input_stream[para.first_input_index]->Type() == CONTROL_CODE) { @@ -1729,14 +1754,17 @@ bool Layout::Calculator::calculate() do { // for each line in the paragraph TRACE(("begin line\n")); std::vector line_chunk_info; - if (!_findChunksForLine(para, &span_pos, &line_chunk_info, &line_height)) + if (!_findChunksForLine(para, &span_pos, &line_chunk_info, &line_box_height)) break; // out of shapes to wrap in to - _outputLine(para, line_height, line_chunk_info); + _outputLine(para, line_box_height, line_chunk_info); + _scanline_maker->setLineHeight( line_box_height ); _scanline_maker->completeLine(); // Increments y by line height + TRACE(("end line\n")); } while (span_pos.iter_span != para.unbroken_spans.end()); TRACE(("para %lu end\n\n", _flow._paragraphs.size() - 1)); + assert (_scanline_maker != NULL ); if (_scanline_maker != NULL) { bool is_empty_para = _flow._characters.empty() || _flow._characters.back().line(&_flow).in_paragraph != _flow._paragraphs.size() - 1; if ((is_empty_para && para_end_input_index + 1 >= _flow._input_stream.size()) @@ -1745,8 +1773,8 @@ bool Layout::Calculator::calculate() Layout::Span new_span; if (_flow._spans.empty()) { new_span.font = NULL; - new_span.font_size = line_height.emSize(); - new_span.line_height = line_height; + new_span.font_size = line_box_height.emSize(); + new_span.line_height = line_box_height; new_span.x_end = 0.0; } else { new_span = _flow._spans.back(); @@ -1856,6 +1884,7 @@ void Layout::_calculateCursorShapeForEmpty() bool Layout::calculateFlow() { + TRACE(("begin calculateFlow()\n")); Layout::Calculator calc = Calculator(this); bool result = calc.calculate(); if (textLengthIncrement != 0) { diff --git a/src/libnrtype/Layout-TNG-Scanline-Maker.h b/src/libnrtype/Layout-TNG-Scanline-Maker.h index da70bff89..7c90ea8cc 100644 --- a/src/libnrtype/Layout-TNG-Scanline-Maker.h +++ b/src/libnrtype/Layout-TNG-Scanline-Maker.h @@ -72,6 +72,11 @@ public: used now, and hence is the line advance height used by completeLine(). */ virtual bool canExtendCurrentScanline(Layout::FontMetrics const &line_height) =0; + + /** Sets current line block height. Call before completeLine() to correct for + actually used line height (in case some chunks with larger font-size rolled back). + */ + virtual void setLineHeight(Layout::FontMetrics const &line_height) =0; }; /** \brief private to Layout. Generates infinite scanlines for when you don't want wrapping @@ -104,6 +109,11 @@ public: /** Always true, but has to save the new height */ virtual bool canExtendCurrentScanline(Layout::FontMetrics const &line_height); + /** Sets current line block height. Call before completeLine() to correct for + actually used line height (in case some chunks with larger font-size rolled back). + */ + virtual void setLineHeight(Layout::FontMetrics const &line_height); + private: double _x, _y; Layout::FontMetrics _current_line_height; @@ -132,6 +142,12 @@ public: /** never true */ virtual bool canExtendCurrentScanline(Layout::FontMetrics const &line_height); + + /** Sets current line block height. Call before completeLine() to correct for + actually used line height (in case some chunks with larger font-size rolled back). + */ + virtual void setLineHeight(Layout::FontMetrics const &line_height); + private: /** To generate scanlines for top-to-bottom text it is easiest if we simply rotate the given shape by a multiple of 90 degrees. This stores diff --git a/src/libnrtype/Layout-TNG-Scanline-Makers.cpp b/src/libnrtype/Layout-TNG-Scanline-Makers.cpp index ea487a597..dcc973a24 100644 --- a/src/libnrtype/Layout-TNG-Scanline-Makers.cpp +++ b/src/libnrtype/Layout-TNG-Scanline-Makers.cpp @@ -69,6 +69,11 @@ bool Layout::InfiniteScanlineMaker::canExtendCurrentScanline(Layout::FontMetrics return true; } +void Layout::InfiniteScanlineMaker::setLineHeight(Layout::FontMetrics const &line_height) +{ + _current_line_height = line_height; +} + // *********************** real shapes version Layout::ShapeScanlineMaker::ShapeScanlineMaker(Shape const *shape, Layout::Direction block_progression) @@ -181,5 +186,10 @@ bool Layout::ShapeScanlineMaker::canExtendCurrentScanline(Layout::FontMetrics co return false; } +void Layout::ShapeScanlineMaker::setLineHeight(Layout::FontMetrics const &line_height) +{ + _current_line_height = line_height.emSize(); +} + }//namespace Text }//namespace Inkscape -- cgit v1.2.3 From 067752b1cf216b8aa55c9e52926496553673cdb7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 2 Dec 2015 18:24:10 +0100 Subject: Add lock to guides (bzr r14500.1.1) --- src/attributes.cpp | 1 + src/attributes.h | 1 + src/display/guideline.cpp | 8 ++++++++ src/display/guideline.h | 2 ++ src/sp-guide.cpp | 28 ++++++++++++++++++++++++++++ src/sp-guide.h | 4 ++++ src/ui/dialog/guides.cpp | 22 ++++++++++++++++++++++ src/ui/dialog/guides.h | 1 + 8 files changed, 67 insertions(+) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index a237f8861..5da75e348 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -116,6 +116,7 @@ static SPStyleProp const props[] = { {SP_ATTR_INKSCAPE_SNAP_PAGE_BORDER, "inkscape:snap-page"}, {SP_ATTR_INKSCAPE_CURRENT_LAYER, "inkscape:current-layer"}, {SP_ATTR_INKSCAPE_DOCUMENT_UNITS, "inkscape:document-units"}, // This setting sets the Display units, *not* the units used in SVG + {SP_ATTR_INKSCAPE_LOCKED, "inkscape:locked"}, {SP_ATTR_UNITS, "units"}, {SP_ATTR_INKSCAPE_CONNECTOR_SPACING, "inkscape:connector-spacing"}, /* SPColorProfile */ diff --git a/src/attributes.h b/src/attributes.h index 42ec99d8f..d5bb20ca3 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -118,6 +118,7 @@ enum SPAttributeEnum { SP_ATTR_INKSCAPE_SNAP_PAGE_BORDER, SP_ATTR_INKSCAPE_CURRENT_LAYER, SP_ATTR_INKSCAPE_DOCUMENT_UNITS, + SP_ATTR_INKSCAPE_LOCKED, SP_ATTR_UNITS, SP_ATTR_INKSCAPE_CONNECTOR_SPACING, /* SPColorProfile */ diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 44bbd14bd..0a564f550 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -53,6 +53,7 @@ static void sp_guideline_init(SPGuideLine *gl) { gl->rgba = 0x0000ff7f; + gl->locked = false; gl->normal_to_line = Geom::Point(0,1); gl->angle = 3.14159265358979323846/2; gl->point_on_line = Geom::Point(0,0); @@ -219,6 +220,7 @@ SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point p normal.normalize(); gl->label = label; + gl->locked = false; gl->normal_to_line = normal; gl->angle = tan( -gl->normal_to_line[Geom::X] / gl->normal_to_line[Geom::Y]); sp_guideline_set_position(gl, point_on_line); @@ -238,6 +240,12 @@ void sp_guideline_set_label(SPGuideLine *gl, const char* label) sp_canvas_item_request_update(SP_CANVAS_ITEM (gl)); } +void sp_guideline_set_locked(SPGuideLine *gl, const bool locked) +{ + gl->locked = locked; + sp_canvas_item_request_update(SP_CANVAS_ITEM (gl)); +} + void sp_guideline_set_position(SPGuideLine *gl, Geom::Point point_on_line) { gl->point_on_line = point_on_line; diff --git a/src/display/guideline.h b/src/display/guideline.h index 2d9a87d9b..778517f1d 100644 --- a/src/display/guideline.h +++ b/src/display/guideline.h @@ -32,6 +32,7 @@ struct SPGuideLine { guint32 rgba; char* label; + bool locked; Geom::Point normal_to_line; Geom::Point point_on_line; double angle; @@ -51,6 +52,7 @@ GType sp_guideline_get_type(); SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point point_on_line, Geom::Point normal); void sp_guideline_set_label(SPGuideLine *gl, const char* label); +void sp_guideline_set_locked(SPGuideLine *gl, const bool locked); void sp_guideline_set_position(SPGuideLine *gl, Geom::Point point_on_line); void sp_guideline_set_normal(SPGuideLine *gl, Geom::Point normal_to_line); void sp_guideline_set_color(SPGuideLine *gl, unsigned int rgba); diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index bbdf5f260..fd07f76ef 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -43,6 +43,7 @@ #include <2geom/angle.h> #include "document.h" #include "document-undo.h" +#include "helper-fns.h" #include "verbs.h" using Inkscape::DocumentUndo; @@ -51,6 +52,7 @@ using std::vector; SPGuide::SPGuide() : SPObject() , label(NULL) + , locked(0) , views(NULL) , normal_to_line(Geom::Point(0.,1.)) , point_on_line(Geom::Point(0.,0.)) @@ -73,6 +75,7 @@ void SPGuide::build(SPDocument *document, Inkscape::XML::Node *repr) this->readAttr( "inkscape:color" ); this->readAttr( "inkscape:label" ); + this->readAttr( "inkscape:locked" ); this->readAttr( "orientation" ); this->readAttr( "position" ); @@ -113,6 +116,12 @@ void SPGuide::set(unsigned int key, const gchar *value) { this->set_label(this->label, false); break; + case SP_ATTR_INKSCAPE_LOCKED: + this->locked = helperfns_read_bool(value, false); + if (value) { + this->set_locked(this->locked, false); + } + break; case SP_ATTR_ORIENTATION: { if (value && !strcmp(value, "horizontal")) { @@ -339,6 +348,9 @@ double SPGuide::getDistanceFrom(Geom::Point const &pt) const */ void SPGuide::moveto(Geom::Point const point_on_line, bool const commit) { + if(this->locked) { + return; + } for (GSList *l = views; l != NULL; l = l->next) { sp_guideline_set_position(SP_GUIDELINE(l->data), point_on_line); } @@ -385,6 +397,9 @@ void SPGuide::moveto(Geom::Point const point_on_line, bool const commit) */ void SPGuide::set_normal(Geom::Point const normal_to_line, bool const commit) { + if(this->locked) { + return; + } for (GSList *l = this->views; l != NULL; l = l->next) { sp_guideline_set_normal(SP_GUIDELINE(l->data), normal_to_line); } @@ -423,6 +438,18 @@ void SPGuide::set_color(const unsigned r, const unsigned g, const unsigned b, bo } } +void SPGuide::set_locked(const bool locked, bool const commit) +{ + this->locked = locked; + if (views) { + sp_guideline_set_locked(SP_GUIDELINE(views->data), locked); + } + + if (commit) { + getRepr()->setAttribute("inkscape:locked", g_strdup(locked ? "true" : "false")); + } +} + void SPGuide::set_label(const char* label, bool const commit) { if (views) { @@ -482,6 +509,7 @@ char* SPGuide::description(bool const verbose) const descr = g_strconcat(oldDescr, shortcuts, NULL); g_free(oldDescr); } + g_free(shortcuts); } diff --git a/src/sp-guide.h b/src/sp-guide.h index 382ea56f0..1ad415e85 100644 --- a/src/sp-guide.h +++ b/src/sp-guide.h @@ -53,6 +53,9 @@ public: void set_label(const char* label, bool const commit); char const* getLabel() const { return label; } + void set_locked(const bool locked, bool const commit); + bool getLocked() const { return locked; } + static SPGuide *createSPGuide(SPDocument *doc, Geom::Point const &pt1, Geom::Point const &pt2); void showSPGuide(SPCanvasGroup *group, GCallback handler); @@ -77,6 +80,7 @@ protected: virtual void set(unsigned int key, const char* value); char* label; + bool locked; GSList *views; // contains an object of type SPGuideline (see display/guideline.cpp for definition) Geom::Point normal_to_line; Geom::Point point_on_line; diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index af8e2cc31..4951cf39c 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -44,6 +44,7 @@ namespace Dialogs { GuidelinePropertiesDialog::GuidelinePropertiesDialog(SPGuide *guide, SPDesktop *desktop) : _desktop(desktop), _guide(guide), + _locked_toggle(_("Lo_cked"), _("Lock the movement of guides")), _relative_toggle(_("Rela_tive change"), _("Move and/or rotate the guide relative to current settings")), _spin_button_x(C_("Guides", "_X:"), "", UNIT_TYPE_LINEAR, "", "", &_unit_menu), _spin_button_y(C_("Guides", "_Y:"), "", UNIT_TYPE_LINEAR, "", "", &_unit_menu), @@ -100,6 +101,9 @@ void GuidelinePropertiesDialog::_onOK() double rad_angle = Geom::deg_to_rad( deg_angle ); normal = Geom::rot90(Geom::Point::polar(rad_angle, 1.0)); } + //To allow reposition from dialog + _guide->set_locked(false, true); + _guide->set_normal(normal, true); double const points_x = _spin_button_x.getValue("px"); @@ -113,6 +117,11 @@ void GuidelinePropertiesDialog::_onOK() const gchar* name = g_strdup( _label_entry.getEntry()->get_text().c_str() ); _guide->set_label(name, true); + + const bool locked = _locked_toggle.get_active(); + + _guide->set_locked(locked, true); + g_free((gpointer) name); #if WITH_GTKMM_3_0 @@ -269,6 +278,12 @@ void GuidelinePropertiesDialog::_setup() { _relative_toggle.set_valign(Gtk::ALIGN_FILL); _relative_toggle.set_hexpand(); _layout_table.attach(_relative_toggle, 1, 7, 2, 1); + + // locked radio button + _locked_toggle.set_halign(Gtk::ALIGN_FILL); + _locked_toggle.set_valign(Gtk::ALIGN_FILL); + _locked_toggle.set_hexpand(); + _layout_table.attach(_locked_toggle, 1, 8, 2, 1); #else _layout_table.attach(_spin_angle, 1, 3, 6, 7, Gtk::EXPAND | Gtk::FILL, Gtk::FILL); @@ -276,11 +291,18 @@ void GuidelinePropertiesDialog::_setup() { // mode radio button _layout_table.attach(_relative_toggle, 1, 3, 7, 8, Gtk::EXPAND | Gtk::FILL, Gtk::FILL); + + // locked radio button + _layout_table.attach(_locked_toggle, + 1, 3, 8, 9, Gtk::EXPAND | Gtk::FILL, Gtk::FILL); #endif _relative_toggle.signal_toggled().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_modeChanged)); _relative_toggle.set_active(_relative_toggle_status); + std::cout << _guide->getLocked() << "_guide->getLocked()\n"; + _locked_toggle.set_active(_guide->getLocked()); + // don't know what this exactly does, but it results in that the dialog closes when entering a value and pressing enter (see LP bug 484187) g_signal_connect_swapped(G_OBJECT(_spin_button_x.getWidget()->gobj()), "activate", G_CALLBACK(gtk_window_activate_default), gobj()); diff --git a/src/ui/dialog/guides.h b/src/ui/dialog/guides.h index 4ff7b4fde..5dce0d6ed 100644 --- a/src/ui/dialog/guides.h +++ b/src/ui/dialog/guides.h @@ -79,6 +79,7 @@ private: Gtk::Label _label_name; Gtk::Label _label_descr; + Inkscape::UI::Widget::CheckButton _locked_toggle; Inkscape::UI::Widget::CheckButton _relative_toggle; static bool _relative_toggle_status; // remember the status of the _relative_toggle_status button across instances Inkscape::UI::Widget::UnitMenu _unit_menu; -- cgit v1.2.3 From 6adeeb23bc139967e8c81a4790250aba43390b61 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 2 Dec 2015 18:31:07 +0100 Subject: Add spray-origin missing atribute (bzr r14501) --- src/attributes.cpp | 1 + src/attributes.h | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index a237f8861..d373dbc68 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -41,6 +41,7 @@ static SPStyleProp const props[] = { {SP_ATTR_TRANSFORM_CENTER_Y, "inkscape:transform-center-y"}, {SP_ATTR_INKSCAPE_PATH_EFFECT, "inkscape:path-effect"}, {SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR, "inkscape:highlight-color"}, + {SP_ATTR_INKSCAPE_SPRAY_ORIGIN, "inkscape:spray-origin"}, /* SPAnchor */ {SP_ATTR_XLINK_HREF, "xlink:href"}, {SP_ATTR_XLINK_TYPE, "xlink:type"}, diff --git a/src/attributes.h b/src/attributes.h index 42ec99d8f..7d22858b8 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -41,6 +41,7 @@ enum SPAttributeEnum { SP_ATTR_TRANSFORM_CENTER_Y, SP_ATTR_INKSCAPE_PATH_EFFECT, SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR, + SP_ATTR_INKSCAPE_SPRAY_ORIGIN, /* SPAnchor */ SP_ATTR_XLINK_HREF, SP_ATTR_XLINK_TYPE, -- cgit v1.2.3 From dc6693bd22141b4bcecdc023bebf826f08baa0de Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 2 Dec 2015 18:39:59 +0100 Subject: Reorder attribute lock to better position (bzr r14500.1.2) --- src/attributes.cpp | 2 +- src/attributes.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index 5da75e348..853e22345 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -116,7 +116,6 @@ static SPStyleProp const props[] = { {SP_ATTR_INKSCAPE_SNAP_PAGE_BORDER, "inkscape:snap-page"}, {SP_ATTR_INKSCAPE_CURRENT_LAYER, "inkscape:current-layer"}, {SP_ATTR_INKSCAPE_DOCUMENT_UNITS, "inkscape:document-units"}, // This setting sets the Display units, *not* the units used in SVG - {SP_ATTR_INKSCAPE_LOCKED, "inkscape:locked"}, {SP_ATTR_UNITS, "units"}, {SP_ATTR_INKSCAPE_CONNECTOR_SPACING, "inkscape:connector-spacing"}, /* SPColorProfile */ @@ -127,6 +126,7 @@ static SPStyleProp const props[] = { {SP_ATTR_ORIENTATION, "orientation"}, {SP_ATTR_POSITION, "position"}, {SP_ATTR_INKSCAPE_COLOR, "inkscape:color"}, + {SP_ATTR_INKSCAPE_LOCKED, "inkscape:locked"}, /* SPImage */ {SP_ATTR_X, "x"}, {SP_ATTR_Y, "y"}, diff --git a/src/attributes.h b/src/attributes.h index d5bb20ca3..bb15590a1 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -118,7 +118,6 @@ enum SPAttributeEnum { SP_ATTR_INKSCAPE_SNAP_PAGE_BORDER, SP_ATTR_INKSCAPE_CURRENT_LAYER, SP_ATTR_INKSCAPE_DOCUMENT_UNITS, - SP_ATTR_INKSCAPE_LOCKED, SP_ATTR_UNITS, SP_ATTR_INKSCAPE_CONNECTOR_SPACING, /* SPColorProfile */ @@ -129,6 +128,7 @@ enum SPAttributeEnum { SP_ATTR_ORIENTATION, SP_ATTR_POSITION, SP_ATTR_INKSCAPE_COLOR, + SP_ATTR_INKSCAPE_LOCKED, /* SPImage */ SP_ATTR_X, SP_ATTR_Y, -- cgit v1.2.3 From a4b8f88b71de0fc72eb14e5f36ccad9c8292ceb2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 3 Dec 2015 00:21:43 +0100 Subject: Removed auto calulate distances in roughen LPE because strange resulton apply on LPE copy effect (bzr r14502) --- src/live_effects/lpe-roughen.cpp | 38 -------------------------------------- src/live_effects/lpe-roughen.h | 1 - 2 files changed, 39 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 310f791a1..b4ee54f1a 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -91,44 +91,6 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) LPERoughen::~LPERoughen() {} -static void -sp_get_better_default_size(SPItem *item, double &value) -{ - if (SP_IS_GROUP(item)) { - std::vector const item_list = sp_item_group_item_list(SP_GROUP(item)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { - SPItem *subitem = *iter; - sp_get_better_default_size(subitem, value); - } - if(item_list.size() > 0){ - value /= item_list.size(); - } - } else { - SPShape *shape = dynamic_cast(item); - if (shape) { - SPCurve * c = NULL; - SPPath *path = dynamic_cast(shape); - if (path) { - c = path->get_original_curve(); - } else { - c = shape->getCurve(); - } - if (c) { - value += Geom::length(paths_to_pw(c->get_pathvector()))/(c->get_segment_count () * 6); - } - } - } -} - -void LPERoughen::doOnApply(SPLPEItem const* lpeitem) -{ - SPLPEItem * splpeitem = const_cast(lpeitem); - double initial = 0; - sp_get_better_default_size(SP_ITEM(splpeitem), initial); - displace_x.param_set_value(initial, 0); - displace_y.param_set_value(initial, 0); -} - void LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem) { if(spray_tool_friendly && seed == 0 && SP_OBJECT(lpeitem)->getId()){ diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index 7e6a19d5a..44a723c89 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -45,7 +45,6 @@ public: virtual void doEffect(SPCurve *curve); virtual double sign(double randNumber); - virtual void doOnApply(SPLPEItem const* lpeitem); virtual Geom::Point randomize(double max_lenght, bool is_node = false); virtual void doBeforeEffect(SPLPEItem const * lpeitem); virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move, double t, bool last); -- cgit v1.2.3 From af5c1ec831e2f225364717c7dc03d88579850b85 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 3 Dec 2015 18:55:52 +0100 Subject: Added no highlight and cross icon on locked guides (bzr r14500.1.4) --- src/desktop-events.cpp | 3 +++ src/display/guideline.cpp | 3 ++- src/sp-guide.cpp | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp index b685dacbf..42e7c2fb6 100644 --- a/src/desktop-events.cpp +++ b/src/desktop-events.cpp @@ -531,6 +531,9 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) } else { GdkCursor *guide_cursor; guide_cursor = gdk_cursor_new (GDK_HAND1); + if(guide->getLocked()){ + guide_cursor = gdk_cursor_new (GDK_X_CURSOR); + } gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), guide_cursor); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(guide_cursor); diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 0a564f550..24353c681 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -18,6 +18,7 @@ #include <2geom/transforms.h> #include "sp-canvas-util.h" #include "sp-ctrlpoint.h" +#include "sp-ctrlquadr.h" #include "guideline.h" #include "display/cairo-utils.h" @@ -180,7 +181,7 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, sp_ctrlpoint_set_coords(gl->origin, gl->point_on_line); sp_canvas_item_request_update(SP_CANVAS_ITEM (gl->origin)); - + Geom::Point pol_transformed = gl->point_on_line*affine; if (gl->is_horizontal()) { sp_canvas_update_bbox (item, -1000000, round(pol_transformed[Geom::Y] - 16), 1000000, round(pol_transformed[Geom::Y] + 1)); diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index fd07f76ef..e37f0b470 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -118,6 +118,7 @@ void SPGuide::set(unsigned int key, const gchar *value) { break; case SP_ATTR_INKSCAPE_LOCKED: this->locked = helperfns_read_bool(value, false); + this->hicolor = this->color; if (value) { this->set_locked(this->locked, false); } -- cgit v1.2.3 From 1cab611c173b2903512268994343f58ef83883ec Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 3 Dec 2015 21:51:29 +0100 Subject: Add global lock guides to the rulers (bzr r14500.1.5) --- src/desktop-events.cpp | 4 ++- src/desktop.cpp | 7 +++++ src/desktop.h | 1 + src/sp-guide.cpp | 4 ++- src/ui/dialog/guides.cpp | 6 ++++- src/verbs.cpp | 5 ++++ src/verbs.h | 1 + src/widgets/desktop-widget.cpp | 58 +++++++++++++++++++++++++++++++++++++----- src/widgets/desktop-widget.h | 3 +++ 9 files changed, 80 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp index 42e7c2fb6..f86cb2991 100644 --- a/src/desktop-events.cpp +++ b/src/desktop-events.cpp @@ -531,7 +531,9 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) } else { GdkCursor *guide_cursor; guide_cursor = gdk_cursor_new (GDK_HAND1); - if(guide->getLocked()){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool global_lock = prefs->getBool("/options/guides/guides_lock", false); + if(guide->getLocked() || global_lock){ guide_cursor = gdk_cursor_new (GDK_X_CURSOR); } gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), guide_cursor); diff --git a/src/desktop.cpp b/src/desktop.cpp index 7b20bcb9f..0ddd77594 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -1467,6 +1467,13 @@ void SPDesktop::toggleColorProfAdjust() _widget->toggleColorProfAdjust(); } +void SPDesktop::toggleGuidesLock() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool guides_lock = prefs->getBool("/options/guides/guides_lock", false); + prefs->setBool("/options/guides/guides_lock", !guides_lock); +} + bool SPDesktop::colorProfAdjustEnabled() { return _widget->colorProfAdjustEnabled(); diff --git a/src/desktop.h b/src/desktop.h index 754e09766..6d3b96223 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -386,6 +386,7 @@ public: void toggleColorProfAdjust(); bool colorProfAdjustEnabled(); + void toggleGuidesLock(); void toggleGrids(); void toggleSnapGlobal(); bool gridsEnabled() const { return grids_visible; }; diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index e37f0b470..00ded2a75 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -349,7 +349,9 @@ double SPGuide::getDistanceFrom(Geom::Point const &pt) const */ void SPGuide::moveto(Geom::Point const point_on_line, bool const commit) { - if(this->locked) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool global_lock = prefs->getBool("/options/guides/guides_lock", false); + if(this->locked || global_lock) { return; } for (GSList *l = views; l != NULL; l = l->next) { diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index 4951cf39c..faba71615 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -300,7 +300,11 @@ void GuidelinePropertiesDialog::_setup() { _relative_toggle.signal_toggled().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_modeChanged)); _relative_toggle.set_active(_relative_toggle_status); - std::cout << _guide->getLocked() << "_guide->getLocked()\n"; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool global_guides_lock = prefs->getBool("/options/guides/guides_lock", false); + if(global_guides_lock){ + _locked_toggle.set_sensitive(false); + } _locked_toggle.set_active(_guide->getLocked()); // don't know what this exactly does, but it results in that the dialog closes when entering a value and pressing enter (see LP bug 484187) diff --git a/src/verbs.cpp b/src/verbs.cpp index 6b13eabb6..029deac3c 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1989,6 +1989,9 @@ void ZoomVerb::perform(SPAction *action, void *data) case SP_VERB_VIEW_CMS_TOGGLE: dt->toggleColorProfAdjust(); break; + case SP_VERB_VIEW_GUIDES_LOCK_TOGGLE: + dt->toggleGuidesLock(); + break; case SP_VERB_VIEW_ICON_PREVIEW: INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("IconPreviewPanel"); @@ -2877,6 +2880,8 @@ Verb *Verb::_base_verbs[] = { new ZoomVerb(SP_VERB_VIEW_CMS_TOGGLE, "ViewCmsToggle", N_("Color-managed view"), N_("Toggle color-managed display for this document window"), INKSCAPE_ICON("color-management")), + new ZoomVerb(SP_VERB_VIEW_GUIDES_LOCK_TOGGLE, "GuidesLockToggle", N_("Lock or unlock guides"), + N_("Lock or unlock guides"), INKSCAPE_ICON("object-locked")), new ZoomVerb(SP_VERB_VIEW_ICON_PREVIEW, "ViewIconPreview", N_("Ico_n Preview..."), N_("Open a window to preview objects at different icon resolutions"), INKSCAPE_ICON("dialog-icon-preview")), diff --git a/src/verbs.h b/src/verbs.h index 27aecae64..c50829525 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -277,6 +277,7 @@ enum { // SP_VERB_VIEW_COLOR_MODE_PRINT_COLORS_PREVIEW, SP_VERB_VIEW_COLOR_MODE_TOGGLE, SP_VERB_VIEW_CMS_TOGGLE, + SP_VERB_VIEW_GUIDES_LOCK_TOGGLE, SP_VERB_VIEW_ICON_PREVIEW, SP_VERB_ZOOM_PAGE, SP_VERB_ZOOM_PAGE_WIDTH, diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index e19f56e48..ee8c3fb26 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -107,6 +107,7 @@ static void sp_desktop_widget_realize (GtkWidget *widget); static gint sp_desktop_widget_event (GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw); static void sp_dtw_color_profile_event(EgeColorProfTracker *widget, SPDesktopWidget *dtw); +static void update_guides_lock( GtkWidget *button, gpointer data ); #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) static void cms_adjust_toggled( GtkWidget *button, gpointer data ); #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -390,6 +391,27 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) dtw->tool_toolbox = ToolboxFactory::createToolToolbox(); ToolboxFactory::setOrientation( dtw->tool_toolbox, GTK_ORIENTATION_VERTICAL ); gtk_box_pack_start( GTK_BOX(dtw->hbox), dtw->tool_toolbox, FALSE, TRUE, 0 ); + /* Lock all guides */ + gchar const* tip = ""; + Inkscape::Verb* verb = Inkscape::Verb::get( SP_VERB_VIEW_GUIDES_LOCK_TOGGLE ); + if ( verb ) { + SPAction *act = verb->get_action( Inkscape::ActionContext( dtw->viewwidget.view ) ); + if ( act && act->tip ) { + tip = act->tip; + } + } + dtw->guides_lock = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION, + SP_BUTTON_TYPE_TOGGLE, + NULL, + INKSCAPE_ICON("object-locked"), + tip ); + { + bool locked = prefs->getBool("/options/guides/locked"); + if ( locked ) { + sp_button_toggle_set_down( SP_BUTTON(dtw->guides_lock), TRUE ); + } + } + g_signal_connect_after( G_OBJECT(dtw->guides_lock), "clicked", G_CALLBACK(update_guides_lock), dtw ); /* Horizontal ruler */ GtkWidget *eventbox = gtk_event_box_new (); @@ -398,7 +420,11 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) Inkscape::Util::Unit const *pt = unit_table.getUnit("pt"); sp_ruler_set_unit(SP_RULER(dtw->hruler), pt); gtk_widget_set_tooltip_text (dtw->hruler_box, gettext(pt->name_plural.c_str())); - gtk_container_add (GTK_CONTAINER (eventbox), dtw->hruler); + /* Lock all guides */ + dtw->hruler_box = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start( GTK_BOX(dtw->hruler_box), dtw->guides_lock, FALSE, FALSE, 0 ); + gtk_box_pack_start( GTK_BOX(dtw->hruler_box), dtw->hruler, true, true, 1 ); + gtk_container_add (GTK_CONTAINER (eventbox), dtw->hruler_box); g_signal_connect (G_OBJECT (eventbox), "button_press_event", G_CALLBACK (sp_dt_hruler_event), dtw); g_signal_connect (G_OBJECT (eventbox), "button_release_event", G_CALLBACK (sp_dt_hruler_event), dtw); g_signal_connect (G_OBJECT (eventbox), "motion_notify_event", G_CALLBACK (sp_dt_hruler_event), dtw); @@ -407,23 +433,25 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) GtkWidget *tbl = gtk_grid_new(); dtw->canvas_tbl = gtk_grid_new(); - gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), eventbox, 1, 0, 1, 1); + gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), eventbox, 0, 0, 1, 1); #else GtkWidget *tbl = gtk_table_new(2, 3, FALSE); dtw->canvas_tbl = gtk_table_new(3, 3, FALSE); gtk_table_attach(GTK_TABLE(dtw->canvas_tbl), eventbox, - 1, 2, 0, 1, + 0, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0); #endif - + gtk_box_pack_start( GTK_BOX(dtw->hbox), tbl, TRUE, TRUE, 1 ); /* Vertical ruler */ eventbox = gtk_event_box_new (); dtw->vruler = sp_ruler_new(GTK_ORIENTATION_VERTICAL); + + /* Vertical ruler */ dtw->vruler_box = eventbox; sp_ruler_set_unit (SP_RULER (dtw->vruler), pt); gtk_widget_set_tooltip_text (dtw->vruler_box, gettext(pt->name_plural.c_str())); @@ -446,6 +474,9 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) // Horizontal scrollbar dtw->hadj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, -4000.0, 4000.0, 10.0, 100.0, 4.0)); + + + #if GTK_CHECK_VERSION(3,0,0) dtw->hscrollbar = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (dtw->hadj)); gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), dtw->hscrollbar, 1, 2, 1, 1); @@ -487,8 +518,8 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) 0, 0); #endif - gchar const* tip = ""; - Inkscape::Verb* verb = Inkscape::Verb::get( SP_VERB_VIEW_CMS_TOGGLE ); + tip = ""; + verb = Inkscape::Verb::get( SP_VERB_VIEW_CMS_TOGGLE ); if ( verb ) { SPAction *act = verb->get_action( Inkscape::ActionContext( dtw->viewwidget.view ) ); if ( act && act->tip ) { @@ -1015,6 +1046,7 @@ sp_desktop_widget_event (GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dt return FALSE; } + #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) void sp_dtw_color_profile_event(EgeColorProfTracker */*tracker*/, SPDesktopWidget *dtw) { @@ -1036,6 +1068,20 @@ void sp_dtw_color_profile_event(EgeColorProfTracker */*tracker*/, SPDesktopWidge } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +void update_guides_lock( GtkWidget */*button*/, gpointer data ) +{ + SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(data); + + bool down = SP_BUTTON_IS_DOWN(dtw->guides_lock); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/options/guides/guides_lock", down); + if (down) { + dtw->setMessage (Inkscape::NORMAL_MESSAGE, _("Guides are locked")); + } else { + dtw->setMessage (Inkscape::NORMAL_MESSAGE, _("Guides are unlocked")); + } +} + #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) void cms_adjust_toggled( GtkWidget */*button*/, gpointer data ) { diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h index 489217d9a..ef3bd9a38 100644 --- a/src/widgets/desktop-widget.h +++ b/src/widgets/desktop-widget.h @@ -77,6 +77,8 @@ struct SPDesktopWidget { GtkWidget *hbox; + GtkWidget *hrulerbox; + GtkWidget *menubar, *statusbar; Inkscape::UI::Dialogs::SwatchesPanel *panels; @@ -87,6 +89,7 @@ struct SPDesktopWidget { GtkWidget *hruler, *vruler; GtkWidget *hruler_box, *vruler_box; // eventboxes for setting tooltips + GtkWidget *guides_lock; GtkWidget *sticky_zoom; GtkWidget *cms_adjust; GtkWidget *coord_status; -- cgit v1.2.3 From dad44686e614958c26cfa2056891ebe9ea6db0dc Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 3 Dec 2015 22:15:42 +0100 Subject: String desc fix (bzr r14500.1.6) --- src/verbs.cpp | 4 ++-- src/widgets/desktop-widget.cpp | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/verbs.cpp b/src/verbs.cpp index 029deac3c..6eace6048 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -2880,8 +2880,8 @@ Verb *Verb::_base_verbs[] = { new ZoomVerb(SP_VERB_VIEW_CMS_TOGGLE, "ViewCmsToggle", N_("Color-managed view"), N_("Toggle color-managed display for this document window"), INKSCAPE_ICON("color-management")), - new ZoomVerb(SP_VERB_VIEW_GUIDES_LOCK_TOGGLE, "GuidesLockToggle", N_("Lock or unlock guides"), - N_("Lock or unlock guides"), INKSCAPE_ICON("object-locked")), + new ZoomVerb(SP_VERB_VIEW_GUIDES_LOCK_TOGGLE, "GuidesLockToggle", N_("Lock all guides"), + N_("Lock all guides"), INKSCAPE_ICON("object-locked")), new ZoomVerb(SP_VERB_VIEW_ICON_PREVIEW, "ViewIconPreview", N_("Ico_n Preview..."), N_("Open a window to preview objects at different icon resolutions"), INKSCAPE_ICON("dialog-icon-preview")), diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index ee8c3fb26..c2e69e469 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1077,8 +1077,6 @@ void update_guides_lock( GtkWidget */*button*/, gpointer data ) prefs->setBool("/options/guides/guides_lock", down); if (down) { dtw->setMessage (Inkscape::NORMAL_MESSAGE, _("Guides are locked")); - } else { - dtw->setMessage (Inkscape::NORMAL_MESSAGE, _("Guides are unlocked")); } } -- cgit v1.2.3 From 8fb3a773c484fc3fc5c17ec7da21ba26cf409037 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Thu, 3 Dec 2015 23:28:20 +0100 Subject: Correct rounding when importing bitmaps (bzr r14503) --- src/extension/internal/gdkpixbuf-input.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index f99c9050d..27b71c252 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -86,8 +86,12 @@ GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri) ir = new ImageResolution(uri); } if (ir && ir->ok()) { - xscale = 960.0 / round(10.*ir->x() + .5); // round-off to 0.1 dpi - yscale = 960.0 / round(10.*ir->y() + .5); + xscale = 960.0 / floor(10.*ir->x() + .5); // round-off to 0.1 dpi + yscale = 960.0 / floor(10.*ir->y() + .5); + if (ir->x() <= .05) + xscale = 960.0; + if (ir->y() <= .05) + yscale = 960.0; } else { xscale = 96.0 / defaultxdpi; yscale = 96.0 / defaultxdpi; -- cgit v1.2.3 From cbbc1697f7ac096ffb5404a5d96f9d79ea27ba64 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Fri, 4 Dec 2015 11:06:44 +0100 Subject: added comment + simpler rounding (bzr r14504) --- src/extension/internal/gdkpixbuf-input.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index 27b71c252..c15e28854 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -86,8 +86,9 @@ GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri) ir = new ImageResolution(uri); } if (ir && ir->ok()) { - xscale = 960.0 / floor(10.*ir->x() + .5); // round-off to 0.1 dpi - yscale = 960.0 / floor(10.*ir->y() + .5); + xscale = 960.0 / round(10.*ir->x()); // round-off to 0.1 dpi + yscale = 960.0 / round(10.*ir->y()); + // prevent crash on image with too small dpi (bug 1479193) if (ir->x() <= .05) xscale = 960.0; if (ir->y() <= .05) -- cgit v1.2.3 From 151733327589217e84c5ac7006b9076f428c53a0 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sat, 5 Dec 2015 12:33:26 +0100 Subject: cppification: GSList replaced by vectors (mostly related to guides and grids) (bzr r14504.1.1) --- src/desktop.cpp | 2 +- src/guide-snapper.cpp | 9 +- src/satisfied-guide-cns.cpp | 4 +- src/snap.cpp | 9 +- src/sp-guide.cpp | 56 ++++++------ src/sp-guide.h | 4 +- src/sp-mask.cpp | 39 +++------ src/sp-namedview.cpp | 155 ++++++++++++++-------------------- src/sp-namedview.h | 9 +- src/ui/dialog/document-properties.cpp | 22 ++--- 10 files changed, 130 insertions(+), 179 deletions(-) (limited to 'src') diff --git a/src/desktop.cpp b/src/desktop.cpp index 7b20bcb9f..5e9401ee0 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -1474,7 +1474,7 @@ bool SPDesktop::colorProfAdjustEnabled() void SPDesktop::toggleGrids() { - if (namedview->grids) { + if (! namedview->grids.empty()) { if(gridgroup) { showGrids(!grids_visible); } diff --git a/src/guide-snapper.cpp b/src/guide-snapper.cpp index 960caed67..17f2d9583 100644 --- a/src/guide-snapper.cpp +++ b/src/guide-snapper.cpp @@ -44,11 +44,10 @@ Inkscape::GuideSnapper::LineList Inkscape::GuideSnapper::_getSnapLines(Geom::Poi } SPGuide const *guide_to_ignore = _snapmanager->getGuideToIgnore(); - - for (GSList const *l = _snapmanager->getNamedView()->guides; l != NULL; l = l->next) { - SPGuide const *g = SP_GUIDE(l->data); - if (g != guide_to_ignore) { - s.push_back(std::pair(g->getNormal(), g->getPoint())); + std::vector guides = _snapmanager->getNamedView()->guides; + for(std::vector::const_iterator it = guides.begin() ; it != guides.end(); ++it) { + if ((*it) != guide_to_ignore) { + s.push_back(std::pair((*it)->getNormal(), (*it)->getPoint())); } } diff --git a/src/satisfied-guide-cns.cpp b/src/satisfied-guide-cns.cpp index 028a22405..a83417865 100644 --- a/src/satisfied-guide-cns.cpp +++ b/src/satisfied-guide-cns.cpp @@ -10,8 +10,8 @@ void satisfied_guide_cns(SPDesktop const &desktop, std::vector &cns) { SPNamedView const &nv = *desktop.getNamedView(); - for (GSList const *l = nv.guides; l != NULL; l = l->next) { - SPGuide &g = *SP_GUIDE(l->data); + for(std::vector::const_iterator it = nv.guides.begin(); it != nv.guides.end(); ++it) { + SPGuide &g = *(*it); for (unsigned int i = 0; i < snappoints.size(); ++i) { if (Geom::are_near(g.getDistanceFrom(snappoints[i].getPoint()), 0, 1e-2)) { cns.push_back(SPGuideConstraint(&g, i)); diff --git a/src/snap.cpp b/src/snap.cpp index 4721283c3..7f0e8d9dc 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -69,9 +69,8 @@ SnapManager::SnapperList SnapManager::getGridSnappers() const SnapperList s; if (_desktop && _desktop->gridsEnabled() && snapprefs.isTargetSnappable(Inkscape::SNAPTARGET_GRID)) { - for ( GSList const *l = _named_view->grids; l != NULL; l = l->next) { - Inkscape::CanvasGrid *grid = (Inkscape::CanvasGrid*) l->data; - s.push_back(grid->snapper); + for(std::vector::const_iterator it = _named_view->grids.begin(); it != _named_view->grids.end(); ++it) { + s.push_back((*it)->snapper); } } @@ -173,8 +172,8 @@ Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t, Geom::Point c // Cannot use getGridSnappers() because we need both the grids AND their snappers // Therefore we iterate through all grids manually - for (GSList const *l = _named_view->grids; l != NULL; l = l->next) { - Inkscape::CanvasGrid *grid = (Inkscape::CanvasGrid*) l->data; + for (std::vector::const_iterator it = _named_view->grids.begin(); it != _named_view->grids.end(); ++it) { + Inkscape::CanvasGrid *grid = (*it); const Inkscape::Snapper* snapper = grid->snapper; if (snapper && snapper->ThisSnapperMightSnap()) { // To find the nearest multiple of the grid pitch for a given translation t, we diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index bbdf5f260..06eaee001 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -51,7 +51,6 @@ using std::vector; SPGuide::SPGuide() : SPObject() , label(NULL) - , views(NULL) , normal_to_line(Geom::Point(0.,1.)) , point_on_line(Geom::Point(0.,0.)) , color(0x0000ff7f) @@ -62,8 +61,8 @@ void SPGuide::setColor(guint32 c) { color = c; - for (GSList *l = this->views; l != NULL; l = l->next) { - sp_guideline_set_color(SP_GUIDELINE(l->data), this->color); + for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { + sp_guideline_set_color(*it, this->color); } } @@ -82,10 +81,10 @@ void SPGuide::build(SPDocument *document, Inkscape::XML::Node *repr) void SPGuide::release() { - while (this->views) { - sp_guideline_delete(SP_GUIDELINE(this->views->data)); - this->views = g_slist_remove(this->views, this->views->data); + for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { + sp_guideline_delete(*it); } + this->views.clear(); if (this->document) { // Unregister ourselves @@ -272,14 +271,14 @@ void SPGuide::showSPGuide(SPCanvasGroup *group, GCallback handler) g_signal_connect(G_OBJECT(item), "event", G_CALLBACK(handler), this); - views = g_slist_prepend(views, item); + views.push_back(SP_GUIDELINE(item)); } void SPGuide::showSPGuide() { - for (GSList *v = views; v != NULL; v = v->next) { - sp_canvas_item_show(SP_CANVAS_ITEM(v->data)); - sp_canvas_item_show(SP_CANVAS_ITEM(SP_GUIDELINE(v->data)->origin)); + for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { + sp_canvas_item_show(SP_CANVAS_ITEM(*it)); + sp_canvas_item_show(SP_CANVAS_ITEM((*it)->origin)); } } @@ -287,11 +286,10 @@ void SPGuide::hideSPGuide(SPCanvas *canvas) { g_assert(canvas != NULL); g_assert(SP_IS_CANVAS(canvas)); - - for (GSList *l = views; l != NULL; l = l->next) { - if (canvas == SP_CANVAS_ITEM(l->data)->canvas) { - sp_guideline_delete(SP_GUIDELINE(l->data)); - views = g_slist_remove(views, l->data); + for(std::vector::iterator it = this->views.begin(); it != this->views.end(); ++it) { + if (canvas == SP_CANVAS_ITEM(*it)->canvas) { + sp_guideline_delete(*it); + views.erase(it); return; } } @@ -301,9 +299,9 @@ void SPGuide::hideSPGuide(SPCanvas *canvas) void SPGuide::hideSPGuide() { - for (GSList *v = views; v != NULL; v = v->next) { - sp_canvas_item_hide(SP_CANVAS_ITEM(v->data)); - sp_canvas_item_hide(SP_CANVAS_ITEM(SP_GUIDELINE(v->data)->origin)); + for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { + sp_canvas_item_hide(SP_CANVAS_ITEM(*it)); + sp_canvas_item_hide(SP_CANVAS_ITEM((*it)->origin)); } } @@ -312,9 +310,9 @@ void SPGuide::sensitize(SPCanvas *canvas, bool sensitive) g_assert(canvas != NULL); g_assert(SP_IS_CANVAS(canvas)); - for (GSList *l = views; l != NULL; l = l->next) { - if (canvas == SP_CANVAS_ITEM(l->data)->canvas) { - sp_guideline_set_sensitive(SP_GUIDELINE(l->data), sensitive); + for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { + if (canvas == SP_CANVAS_ITEM(*it)->canvas) { + sp_guideline_set_sensitive(*it, sensitive); return; } } @@ -339,8 +337,8 @@ double SPGuide::getDistanceFrom(Geom::Point const &pt) const */ void SPGuide::moveto(Geom::Point const point_on_line, bool const commit) { - for (GSList *l = views; l != NULL; l = l->next) { - sp_guideline_set_position(SP_GUIDELINE(l->data), point_on_line); + for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { + sp_guideline_set_position(*it, point_on_line); } /* Calling sp_repr_set_point must precede calling sp_item_notify_moveto in the commit @@ -385,8 +383,8 @@ void SPGuide::moveto(Geom::Point const point_on_line, bool const commit) */ void SPGuide::set_normal(Geom::Point const normal_to_line, bool const commit) { - for (GSList *l = this->views; l != NULL; l = l->next) { - sp_guideline_set_normal(SP_GUIDELINE(l->data), normal_to_line); + for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { + sp_guideline_set_normal(*it, normal_to_line); } /* Calling sp_repr_set_svg_point must precede calling sp_item_notify_moveto in the commit @@ -411,8 +409,8 @@ void SPGuide::set_color(const unsigned r, const unsigned g, const unsigned b, bo { this->color = (r << 24) | (g << 16) | (b << 8) | 0x7f; - if (views) { - sp_guideline_set_color(SP_GUIDELINE(views->data), this->color); + if (! views.empty()) { + sp_guideline_set_color(views[0], this->color); } if (commit) { @@ -425,8 +423,8 @@ void SPGuide::set_color(const unsigned r, const unsigned g, const unsigned b, bo void SPGuide::set_label(const char* label, bool const commit) { - if (views) { - sp_guideline_set_label(SP_GUIDELINE(views->data), label); + if (!views.empty()) { + sp_guideline_set_label(views[0], label); } if (commit) { diff --git a/src/sp-guide.h b/src/sp-guide.h index 382ea56f0..bcd1e57b6 100644 --- a/src/sp-guide.h +++ b/src/sp-guide.h @@ -28,7 +28,7 @@ extern "C" { class SPDesktop; struct SPCanvas; struct SPCanvasGroup; - +struct SPGuideLine; #define SP_GUIDE(obj) (dynamic_cast((SPObject*)obj)) #define SP_IS_GUIDE(obj) (dynamic_cast((SPObject*)obj) != NULL) @@ -77,7 +77,7 @@ protected: virtual void set(unsigned int key, const char* value); char* label; - GSList *views; // contains an object of type SPGuideline (see display/guideline.cpp for definition) + std::vector views; // contains an object of type SPGuideline (see display/guideline.cpp for definition) Geom::Point normal_to_line; Geom::Point point_on_line; diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp index 5f7a2ec26..7b9ab11c3 100644 --- a/src/sp-mask.cpp +++ b/src/sp-mask.cpp @@ -138,23 +138,18 @@ void SPMask::update(SPCtx* ctx, unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - GSList *l = NULL; - for (SPObject *child = this->firstChild(); child; child = child->getNext()) { - sp_object_ref(child); - l = g_slist_prepend (l, child); + std::vector children = this->childList(false); + for (std::vector::const_iterator child = children.begin();child != children.end();child++) { + sp_object_ref(*child); } - l = g_slist_reverse (l); - while (l) { - SPObject *child = SP_OBJECT(l->data); - l = g_slist_remove(l, child); - - if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - child->updateDisplay(ctx, flags); + for (std::vector::const_iterator child = children.begin();child != children.end();child++) { + if (flags || ((*child)->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + (*child)->updateDisplay(ctx, flags); } - sp_object_unref(child); + sp_object_unref(*child); } for (SPMaskView *v = this->display; v != NULL; v = v->next) { @@ -177,23 +172,17 @@ void SPMask::modified(unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - GSList *l = NULL; - for (SPObject *child = this->firstChild(); child; child = child->getNext()) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + std::vector children = this->childList(false); + for (std::vector::const_iterator child = children.begin();child != children.end();child++) { + sp_object_ref(*child); } - l = g_slist_reverse(l); - - while (l) { - SPObject *child = SP_OBJECT(l->data); - l = g_slist_remove(l, child); - - if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - child->emitModified(flags); + for (std::vector::const_iterator child = children.begin();child != children.end();child++) { + if (flags || ((*child)->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + (*child)->emitModified(flags); } - sp_object_unref(child); + sp_object_unref(*child); } } diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index b8554f352..fa62cf169 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -60,7 +60,7 @@ SPNamedView::SPNamedView() : SPObjectGroup(), snap_manager(this) { this->zoom = 0; this->guidecolor = 0; this->guidehicolor = 0; - this->views = NULL; + this->views.clear(); this->borderlayer = 0; this->page_size_units = NULL; this->window_x = 0; @@ -83,9 +83,9 @@ SPNamedView::SPNamedView() : SPObjectGroup(), snap_manager(this) { this->showborder = TRUE; this->showpageshadow = TRUE; - this->guides = NULL; + this->guides.clear(); this->viewcount = 0; - this->grids = NULL; + this->grids.clear(); this->default_layer_id = 0; @@ -245,7 +245,7 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) { for (SPObject *o = this->firstChild() ; o; o = o->getNext() ) { if (SP_IS_GUIDE(o)) { SPGuide * g = SP_GUIDE(o); - this->guides = g_slist_prepend(this->guides, g); + this->guides.push_back(g); //g_object_set(G_OBJECT(g), "color", nv->guidecolor, "hicolor", nv->guidehicolor, NULL); g->setColor(this->guidecolor); g->setHiColor(this->guidehicolor); @@ -268,18 +268,12 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) { } void SPNamedView::release() { - if (this->guides) { - g_slist_free(this->guides); - this->guides = NULL; - } + this->guides.clear(); // delete grids: - while ( this->grids ) { - Inkscape::CanvasGrid *gr = (Inkscape::CanvasGrid *)this->grids->data; // get first entry - delete gr; - this->grids = g_slist_remove_link(this->grids, this->grids); // deletes first entry - } - + for(std::vector::const_iterator it=this->grids.begin();it!=this->grids.end();++it ) + delete *it; + this->grids.clear(); SPObjectGroup::release(); } @@ -325,10 +319,9 @@ void SPNamedView::set(unsigned int key, const gchar* value) { this->guidecolor = (this->guidecolor & 0xff) | sp_svg_read_color(value, this->guidecolor); } - for (GSList *l = this->guides; l != NULL; l = l->next) { - SPGuide * g = SP_GUIDE(l->data); - g->setColor(this->guidecolor); - g->readAttr("inkscape:color"); + for(std::vector::const_iterator it=this->guides.begin();it!=this->guides.end();++it ) { + (*it)->setColor(this->guidecolor); + (*it)->readAttr("inkscape:color"); } this->requestModified(SP_OBJECT_MODIFIED_FLAG); @@ -337,10 +330,9 @@ void SPNamedView::set(unsigned int key, const gchar* value) { this->guidecolor = (this->guidecolor & 0xffffff00) | (DEFAULTGUIDECOLOR & 0xff); sp_nv_read_opacity(value, &this->guidecolor); - for (GSList *l = this->guides; l != NULL; l = l->next) { - SPGuide * g = SP_GUIDE(l->data); - g->setColor(this->guidecolor); - g->readAttr("inkscape:color"); + for(std::vector::const_iterator it=this->guides.begin();it!=this->guides.end();++it ) { + (*it)->setColor(this->guidecolor); + (*it)->readAttr("inkscape:color"); } this->requestModified(SP_OBJECT_MODIFIED_FLAG); @@ -351,10 +343,8 @@ void SPNamedView::set(unsigned int key, const gchar* value) { if (value) { this->guidehicolor = (this->guidehicolor & 0xff) | sp_svg_read_color(value, this->guidehicolor); } - - for (GSList *l = this->guides; l != NULL; l = l->next) { - //g_object_set(G_OBJECT(l->data), "hicolor", nv->guidehicolor, NULL); - SP_GUIDE(l->data)->setHiColor(this->guidehicolor); + for(std::vector::const_iterator it=this->guides.begin();it!=this->guides.end();++it ) { + (*it)->setHiColor(this->guidehicolor); } this->requestModified(SP_OBJECT_MODIFIED_FLAG); @@ -362,10 +352,8 @@ void SPNamedView::set(unsigned int key, const gchar* value) { case SP_ATTR_GUIDEHIOPACITY: this->guidehicolor = (this->guidehicolor & 0xffffff00) | (DEFAULTGUIDEHICOLOR & 0xff); sp_nv_read_opacity(value, &this->guidehicolor); - - for (GSList *l = this->guides; l != NULL; l = l->next) { - //g_object_set(G_OBJECT(l->data), "hicolor", nv->guidehicolor, NULL); - SP_GUIDE(l->data)->setHiColor(this->guidehicolor); + for(std::vector::const_iterator it=this->guides.begin();it!=this->guides.end();++it ) { + (*it)->setHiColor(this->guidehicolor); } this->requestModified(SP_OBJECT_MODIFIED_FLAG); @@ -614,10 +602,9 @@ static Inkscape::CanvasGrid* sp_namedview_add_grid(SPNamedView *nv, Inkscape::XML::Node *repr, SPDesktop *desktop) { Inkscape::CanvasGrid* grid = NULL; //check if namedview already has an object for this grid - for (GSList *l = nv->grids; l != NULL; l = l->next) { - Inkscape::CanvasGrid* g = (Inkscape::CanvasGrid*) l->data; - if (repr == g->repr) { - grid = g; + for(std::vector::const_iterator it=nv->grids.begin();it!=nv->grids.end();++it ) { + if (repr == (*it)->repr) { + grid = (*it); break; } } @@ -630,14 +617,13 @@ sp_namedview_add_grid(SPNamedView *nv, Inkscape::XML::Node *repr, SPDesktop *des return NULL; } grid = Inkscape::CanvasGrid::NewGrid(nv, repr, nv->document, gridtype); - nv->grids = g_slist_append(nv->grids, grid); + nv->grids.push_back(grid); } if (!desktop) { //add canvasitem to all desktops - for (GSList *l = nv->views; l != NULL; l = l->next) { - SPDesktop *dt = static_cast(l->data); - grid->createCanvasItem(dt); + for(std::vector::const_iterator it=nv->views.begin();it!=nv->views.end();++it ) { + grid->createCanvasItem(*it); } } else { //add canvasitem only for specified desktop @@ -660,7 +646,7 @@ void SPNamedView::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *r if (SP_IS_GUIDE(no)) { SPGuide *g = (SPGuide *) no; - this->guides = g_slist_prepend(this->guides, g); + this->guides.push_back(g); //g_object_set(G_OBJECT(g), "color", this->guidecolor, "hicolor", this->guidehicolor, NULL); g->setColor(this->guidecolor); @@ -668,11 +654,11 @@ void SPNamedView::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *r g->readAttr("inkscape:color"); if (this->editable) { - for (GSList *l = this->views; l != NULL; l = l->next) { - g->SPGuide::showSPGuide(static_cast(l->data)->guides, (GCallback) sp_dt_guide_event); + for(std::vector::const_iterator it=this->views.begin();it!=this->views.end();++it ) { + g->SPGuide::showSPGuide((*it)->guides, (GCallback) sp_dt_guide_event); - if (static_cast(l->data)->guides_active) { - g->sensitize((static_cast (l->data))->getCanvas(), TRUE); + if ((*it)->guides_active) { + g->sensitize((*it)->getCanvas(), TRUE); } sp_namedview_show_single_guide(SP_GUIDE(g), this->showguides); @@ -684,27 +670,20 @@ void SPNamedView::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *r void SPNamedView::remove_child(Inkscape::XML::Node *child) { if (!strcmp(child->name(), "inkscape:grid")) { - for ( GSList *iter = this->grids ; iter ; iter = iter->next ) { - Inkscape::CanvasGrid *gr = (Inkscape::CanvasGrid *)iter->data; - - if ( gr->repr == child ) { - delete gr; - this->grids = g_slist_remove_link(this->grids, iter); + for(std::vector::iterator it=this->grids.begin();it!=this->grids.end();++it ) { + if ( (*it)->repr == child ) { + delete (*it); + this->grids.erase(it); break; } } } else { - GSList **ref = &this->guides; - for ( GSList *iter = this->guides ; iter ; iter = iter->next ) { - - if ( reinterpret_cast(iter->data)->getRepr() == child ) { - *ref = iter->next; - iter->next = NULL; - g_slist_free_1(iter); + for(std::vector::iterator it=this->guides.begin();it!=this->guides.end();++it ) { + if ( (*it)->getRepr() == child ) { + delete (*it); + this->guides.erase(it); break; - } - - ref = &iter->next; + } } } @@ -727,15 +706,15 @@ Inkscape::XML::Node* SPNamedView::write(Inkscape::XML::Document *xml_doc, Inksca void SPNamedView::show(SPDesktop *desktop) { - for (GSList *l = guides; l != NULL; l = l->next) { - SP_GUIDE(l->data)->showSPGuide( desktop->guides, (GCallback) sp_dt_guide_event); + for(std::vector::const_iterator it=this->guides.begin();it!=this->guides.end();++it ) { + (*it)->showSPGuide( desktop->guides, (GCallback) sp_dt_guide_event); if (desktop->guides_active) { - SP_GUIDE(l->data)->sensitize(desktop->getCanvas(), TRUE); + (*it)->sensitize(desktop->getCanvas(), TRUE); } - sp_namedview_show_single_guide(SP_GUIDE(l->data), showguides); + sp_namedview_show_single_guide((*it), showguides); } - views = g_slist_prepend(views, desktop); + views.push_back(desktop); // generate grids specified in SVG: Inkscape::XML::Node *repr = this->getRepr(); @@ -924,31 +903,28 @@ void sp_namedview_document_from_window(SPDesktop *desktop) void SPNamedView::hide(SPDesktop const *desktop) { g_assert(desktop != NULL); - g_assert(g_slist_find(views, desktop)); - - for (GSList *l = guides; l != NULL; l = l->next) { - SP_GUIDE(l->data)->hideSPGuide(desktop->getCanvas()); + g_assert(std::find(views.begin(),views.end(),desktop)!=views.end()); + for(std::vector::iterator it=this->guides.begin();it!=this->guides.end();++it ) { + (*it)->hideSPGuide(desktop->getCanvas()); } - - views = g_slist_remove(views, desktop); + views.erase(std::remove(views.begin(),views.end(),desktop),views.end()); } void SPNamedView::activateGuides(void* desktop, bool active) { g_assert(desktop != NULL); - g_assert(g_slist_find(views, desktop)); + g_assert(std::find(views.begin(),views.end(),desktop)!=views.end()); SPDesktop *dt = static_cast(desktop); - - for (GSList *l = guides; l != NULL; l = l->next) { - SP_GUIDE(l->data)->sensitize(dt->getCanvas(), active); + for(std::vector::iterator it=this->guides.begin();it!=this->guides.end();++it ) { + (*it)->sensitize(dt->getCanvas(), active); } } static void sp_namedview_setup_guides(SPNamedView *nv) { - for (GSList *l = nv->guides; l != NULL; l = l->next) { - sp_namedview_show_single_guide(SP_GUIDE(l->data), nv->showguides); + for(std::vector::iterator it=nv->guides.begin();it!=nv->guides.end();++it ) { + sp_namedview_show_single_guide(*it, nv->showguides); } } @@ -1010,7 +986,7 @@ guint SPNamedView::getViewCount() return ++viewcount; } -GSList const *SPNamedView::getViewList() const +std::vector const SPNamedView::getViewList() const { return views; } @@ -1144,18 +1120,17 @@ Inkscape::Util::Unit const & SPNamedView::getSVGUnit() const */ Inkscape::CanvasGrid * sp_namedview_get_first_enabled_grid(SPNamedView *namedview) { - for (GSList const * l = namedview->grids; l != NULL; l = l->next) { - Inkscape::CanvasGrid * grid = (Inkscape::CanvasGrid*) l->data; - if (grid->isEnabled()) - return grid; + for(std::vector::const_iterator it=namedview->grids.begin();it!=namedview->grids.end();++it ) { + if ((*it)->isEnabled()) + return (*it); } return NULL; } void SPNamedView::translateGuides(Geom::Translate const &tr) { - for (GSList *l = guides; l != NULL; l = l->next) { - SPGuide &guide = *SP_GUIDE(l->data); + for(std::vector::iterator it=this->guides.begin();it!=this->guides.end();++it ) { + SPGuide &guide = *(*it); Geom::Point point_on_line = guide.getPoint(); point_on_line *= tr; guide.moveto(point_on_line, true); @@ -1163,19 +1138,15 @@ void SPNamedView::translateGuides(Geom::Translate const &tr) { } void SPNamedView::translateGrids(Geom::Translate const &tr) { - for (GSList *l = grids; l != NULL; l = l->next) { - Inkscape::CanvasGrid* g = reinterpret_cast(l->data); - if (g) { - g->setOrigin(g->origin * tr); - } + for(std::vector::iterator it=this->grids.begin();it!=this->grids.end();++it ) { + (*it)->setOrigin((*it)->origin * tr); } } void SPNamedView::scrollAllDesktops(double dx, double dy, bool is_scrolling) { - for(GSList *l = views; l; l = l->next) { - SPDesktop *desktop = static_cast(l->data); - desktop->scroll_world_in_svg_coords(dx, dy, is_scrolling); - } + for(std::vector::iterator it=this->views.begin();it!=this->views.end();++it ) { + (*it)->scroll_world_in_svg_coords(dx, dy, is_scrolling); + } } diff --git a/src/sp-namedview.h b/src/sp-namedview.h index f1ecc12d3..8db253d25 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -21,6 +21,7 @@ #include "snap.h" #include "document.h" #include "util/units.h" +#include namespace Inkscape { class CanvasGrid; @@ -58,7 +59,7 @@ public: int window_maximized; SnapManager snap_manager; - GSList * grids; + std::vector grids; bool grids_visible; Inkscape::Util::Unit const *svg_units; // Units used for the values in SVG @@ -75,8 +76,8 @@ public: guint32 pagecolor; guint32 pageshadow; - GSList *guides; - GSList *views; + std::vector guides; + std::vector views; int viewcount; @@ -85,7 +86,7 @@ public: void activateGuides(void* desktop, bool active); char const *getName() const; unsigned int getViewCount(); - GSList const *getViewList() const; + std::vector const getViewList() const; Inkscape::Util::Unit const * getDisplayUnit() const; Inkscape::Util::Unit const & getSVGUnit() const; diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index b04e8ecc1..5b63d14e1 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1364,12 +1364,11 @@ void DocumentProperties::update_gridspage() //add tabs bool grids_present = false; - for (GSList const * l = nv->grids; l != NULL; l = l->next) { - Inkscape::CanvasGrid * grid = (Inkscape::CanvasGrid*) l->data; - if (!grid->repr->attribute("id")) continue; // update_gridspage is called again when "id" is added - Glib::ustring name(grid->repr->attribute("id")); + for(std::vector::const_iterator it = nv->grids.begin(); it != nv->grids.end(); ++it) { + if (!(*it)->repr->attribute("id")) continue; // update_gridspage is called again when "id" is added + Glib::ustring name((*it)->repr->attribute("id")); const char *icon = NULL; - switch (grid->getGridType()) { + switch ((*it)->getGridType()) { case GRID_RECTANGULAR: icon = "grid-rectangular"; break; @@ -1379,7 +1378,7 @@ void DocumentProperties::update_gridspage() default: break; } - _grids_notebook.append_page(*grid->newWidget(), _createPageTabLabel(name, icon)); + _grids_notebook.append_page(*(*it)->newWidget(), _createPageTabLabel(name, icon)); grids_present = true; } _grids_notebook.show_all(); @@ -1639,14 +1638,9 @@ void DocumentProperties::onRemoveGrid() SPDesktop *dt = getDesktop(); SPNamedView *nv = dt->getNamedView(); Inkscape::CanvasGrid * found_grid = NULL; - int i = 0; - for (GSList const * l = nv->grids; l != NULL; l = l->next, i++) { // not a very nice fix, but works. - Inkscape::CanvasGrid * grid = (Inkscape::CanvasGrid*) l->data; - if (pagenum == i) { - found_grid = grid; - break; // break out of for-loop - } - } + if( pagenum < nv->grids.size()) + found_grid = nv->grids[pagenum]; + if (found_grid) { // delete the grid that corresponds with the selected tab // when the grid is deleted from SVG, the SPNamedview handler automatically deletes the object, so found_grid becomes an invalid pointer! -- cgit v1.2.3 From 78005ad417dde6dddab40efacb757b1d6b0c03d0 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 5 Dec 2015 15:40:56 +0100 Subject: Handle units in the 'x', 'y', 'dx', and 'dy' text and tspan attributes. Fixed bugs: - https://launchpad.net/bugs/1522478 - https://launchpad.net/bugs/262528 - https://launchpad.net/bugs/168845 (bzr r14505) --- src/sp-rect.cpp | 12 +++---- src/sp-text.cpp | 88 ++++++++++++++++++++++++++++++++++------------- src/sp-tref.cpp | 2 +- src/sp-tspan.cpp | 32 +++++++++++++++-- src/svg/svg-length.cpp | 2 +- src/svg/svg-length.h | 2 +- src/text-tag-attributes.h | 5 ++- 7 files changed, 107 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp index e17d7373c..2ba9a7023 100644 --- a/src/sp-rect.cpp +++ b/src/sp-rect.cpp @@ -61,13 +61,13 @@ void SPRect::set(unsigned key, gchar const *value) { switch (key) { case SP_ATTR_X: this->x.readOrUnset(value); - this->x.update( ex, em, w ); + this->x.update( em, ex, w ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_Y: this->y.readOrUnset(value); - this->y.update( ex, em, h ); + this->y.update( em, ex, h ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -75,7 +75,7 @@ void SPRect::set(unsigned key, gchar const *value) { if (!this->width.read(value) || this->width.value < 0.0) { this->width.unset(); } - this->width.update( ex, em, w ); + this->width.update( em, ex, w ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -83,7 +83,7 @@ void SPRect::set(unsigned key, gchar const *value) { if (!this->height.read(value) || this->height.value < 0.0) { this->height.unset(); } - this->height.update( ex, em, h ); + this->height.update( em, ex, h ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -91,7 +91,7 @@ void SPRect::set(unsigned key, gchar const *value) { if (!this->rx.read(value) || this->rx.value <= 0.0) { this->rx.unset(); } - this->rx.update( ex, em, w ); + this->rx.update( em, ex, w ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -99,7 +99,7 @@ void SPRect::set(unsigned key, gchar const *value) { if (!this->ry.read(value) || this->ry.value <= 0.0) { this->ry.unset(); } - this->ry.update( ex, em, h ); + this->ry.update( em, ex, h ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; diff --git a/src/sp-text.cpp b/src/sp-text.cpp index d351e58e3..c7dfdd694 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -93,7 +93,7 @@ void SPText::release() { void SPText::set(unsigned int key, const gchar* value) { //std::cout << "SPText::set: " << sp_attribute_name( key ) << ": " << (value?value:"Null") << std::endl; - if (this->attributes.readSingleAttribute(key, value)) { + if (this->attributes.readSingleAttribute(key, value, style, &viewport)) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } else { switch (key) { @@ -181,6 +181,16 @@ void SPText::update(SPCtx *ctx, guint flags) { SP_OBJECT_CHILD_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG ) ) { + + SPItemCtx const *ictx = reinterpret_cast(ctx); + + double const w = ictx->viewport.width(); + double const h = ictx->viewport.height(); + double const em = style->font_size.computed; + double const ex = 0.5 * em; // fixme: get x height from pango or libnrtype. + + attributes.update( em, ex, w, h ); + /* fixme: It is not nice to have it here, but otherwise children content changes does not work */ /* fixme: Even now it may not work, as we are delayed */ /* fixme: So check modification flag everywhere immediate state is used */ @@ -576,7 +586,7 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio SPString *str = dynamic_cast(child); if (str) { Glib::ustring const &string = str->string; - // std::cout << " Appending: " << string << std::endl; + // std::cout << " Appending: >" << string << "<" << std::endl; layout.appendText(string, root->style, child, &optional_attrs, child_attrs_offset + length); length += string.length(); } else if (!sp_repr_is_meta_element(child->getRepr())) { @@ -671,25 +681,30 @@ void SPText::_clearFlow(Inkscape::DrawingGroup *in_arena) * TextTagAttributes implementation */ -void TextTagAttributes::readFrom(Inkscape::XML::Node const *node) -{ - readSingleAttribute(SP_ATTR_X, node->attribute("x")); - readSingleAttribute(SP_ATTR_Y, node->attribute("y")); - readSingleAttribute(SP_ATTR_DX, node->attribute("dx")); - readSingleAttribute(SP_ATTR_DY, node->attribute("dy")); - readSingleAttribute(SP_ATTR_ROTATE, node->attribute("rotate")); - readSingleAttribute(SP_ATTR_TEXTLENGTH, node->attribute("textLength")); - readSingleAttribute(SP_ATTR_LENGTHADJUST, node->attribute("lengthAdjust")); -} - -bool TextTagAttributes::readSingleAttribute(unsigned key, gchar const *value) +// Not used. +// void TextTagAttributes::readFrom(Inkscape::XML::Node const *node) +// { +// readSingleAttribute(SP_ATTR_X, node->attribute("x")); +// readSingleAttribute(SP_ATTR_Y, node->attribute("y")); +// readSingleAttribute(SP_ATTR_DX, node->attribute("dx")); +// readSingleAttribute(SP_ATTR_DY, node->attribute("dy")); +// readSingleAttribute(SP_ATTR_ROTATE, node->attribute("rotate")); +// readSingleAttribute(SP_ATTR_TEXTLENGTH, node->attribute("textLength")); +// readSingleAttribute(SP_ATTR_LENGTHADJUST, node->attribute("lengthAdjust")); +// } + +bool TextTagAttributes::readSingleAttribute(unsigned key, gchar const *value, SPStyle const *style, Geom::Rect const *viewport) { + // std::cout << "TextTagAttributes::readSingleAttribute: key: " << key + // << " value: " << (value?value:"Null") << std::endl; std::vector *attr_vector; + bool update_x = false; + bool update_y = false; switch (key) { - case SP_ATTR_X: attr_vector = &attributes.x; break; - case SP_ATTR_Y: attr_vector = &attributes.y; break; - case SP_ATTR_DX: attr_vector = &attributes.dx; break; - case SP_ATTR_DY: attr_vector = &attributes.dy; break; + case SP_ATTR_X: attr_vector = &attributes.x; update_x = true; break; + case SP_ATTR_Y: attr_vector = &attributes.y; update_y = true; break; + case SP_ATTR_DX: attr_vector = &attributes.dx; update_x = true; break; + case SP_ATTR_DY: attr_vector = &attributes.dy; update_y = true; break; case SP_ATTR_ROTATE: attr_vector = &attributes.rotate; break; case SP_ATTR_TEXTLENGTH: attributes.textLength.readOrUnset(value); @@ -706,6 +721,19 @@ bool TextTagAttributes::readSingleAttribute(unsigned key, gchar const *value) // FIXME: sp_svg_length_list_read() amalgamates repeated separators. This prevents unset values. *attr_vector = sp_svg_length_list_read(value); + + if( (update_x || update_y) && style != NULL && viewport != NULL ) { + double const w = viewport->width(); + double const h = viewport->height(); + double const em = style->font_size.computed; + double const ex = em * 0.5; + for(std::vector::iterator it = attr_vector->begin(); it != attr_vector->end(); ++it) { + if( update_x ) + it->update( em, ex, w ); + if( update_y ) + it->update( em, ex, h ); + } + } return true; } @@ -728,12 +756,26 @@ void TextTagAttributes::writeTo(Inkscape::XML::Node *node) const } } +void TextTagAttributes::update( double em, double ex, double w, double h ) +{ + for(std::vector::iterator it = attributes.x.begin(); it != attributes.x.end(); ++it) { + it->update( em, ex, w ); + } + for(std::vector::iterator it = attributes.y.begin(); it != attributes.y.end(); ++it) { + it->update( em, ex, h ); + } + for(std::vector::iterator it = attributes.dx.begin(); it != attributes.dx.end(); ++it) { + it->update( em, ex, w ); + } + for(std::vector::iterator it = attributes.dy.begin(); it != attributes.dy.end(); ++it) { + it->update( em, ex, h ); + } +} + void TextTagAttributes::writeSingleAttributeLength(Inkscape::XML::Node *node, gchar const *key, const SVGLength &length) { if (length._set) { - gchar single_value_string[32]; - g_ascii_formatd(single_value_string, sizeof (single_value_string), "%.8g", length.computed); - node->setAttribute(key, single_value_string); + node->setAttribute(key, length.write().c_str()); } else node->setAttribute(key, NULL); } @@ -744,13 +786,11 @@ void TextTagAttributes::writeSingleAttributeVector(Inkscape::XML::Node *node, gc node->setAttribute(key, NULL); else { Glib::ustring string; - gchar single_value_string[32]; // FIXME: this has no concept of unset values because sp_svg_length_list_read() can't read them back in for (std::vector::const_iterator it = attr_vector.begin() ; it != attr_vector.end() ; ++it) { - g_ascii_formatd(single_value_string, sizeof (single_value_string), "%.8g", it->computed); if (!string.empty()) string += ' '; - string += single_value_string; + string += it->write(); } node->setAttribute(key, string.c_str()); } diff --git a/src/sp-tref.cpp b/src/sp-tref.cpp index aef18462a..ba592058b 100644 --- a/src/sp-tref.cpp +++ b/src/sp-tref.cpp @@ -92,7 +92,7 @@ void SPTRef::set(unsigned int key, const gchar* value) { debug("0x%p %s(%u): '%s'",this, sp_attribute_name(key),key,value ? value : ""); - if (this->attributes.readSingleAttribute(key, value)) { // x, y, dx, dy, rotate + if (this->attributes.readSingleAttribute(key, value, style, &viewport)) { // x, y, dx, dy, rotate this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } else if (key == SP_ATTR_XLINK_HREF) { // xlink:href if ( !value ) { diff --git a/src/sp-tspan.cpp b/src/sp-tspan.cpp index 7582cb9e6..05f8430ba 100644 --- a/src/sp-tspan.cpp +++ b/src/sp-tspan.cpp @@ -70,7 +70,7 @@ void SPTSpan::release() { } void SPTSpan::set(unsigned int key, const gchar* value) { - if (this->attributes.readSingleAttribute(key, value)) { + if (this->attributes.readSingleAttribute(key, value, style, &viewport)) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } else { switch (key) { @@ -103,6 +103,20 @@ void SPTSpan::update(SPCtx *ctx, guint flags) { } SPItem::update(ctx, flags); + + if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG | + SP_OBJECT_CHILD_MODIFIED_FLAG | + SP_TEXT_LAYOUT_MODIFIED_FLAG ) ) + { + SPItemCtx const *ictx = reinterpret_cast(ctx); + + double const w = ictx->viewport.width(); + double const h = ictx->viewport.height(); + double const em = style->font_size.computed; + double const ex = 0.5 * em; // fixme: get x height from pango or libnrtype. + + attributes.update( em, ex, w, h ); + } } void SPTSpan::modified(unsigned int flags) { @@ -264,7 +278,7 @@ void SPTextPath::release() { } void SPTextPath::set(unsigned int key, const gchar* value) { - if (this->attributes.readSingleAttribute(key, value)) { + if (this->attributes.readSingleAttribute(key, value, style, &viewport)) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } else { switch (key) { @@ -304,6 +318,20 @@ void SPTextPath::update(SPCtx *ctx, guint flags) { ochild->updateDisplay(ctx, flags); } } + + if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG | + SP_OBJECT_CHILD_MODIFIED_FLAG | + SP_TEXT_LAYOUT_MODIFIED_FLAG ) ) + { + SPItemCtx const *ictx = reinterpret_cast(ctx); + + double const w = ictx->viewport.width(); + double const h = ictx->viewport.height(); + double const em = style->font_size.computed; + double const ex = 0.5 * em; // fixme: get x height from pango or libnrtype. + + attributes.update( em, ex, w, h ); + } } diff --git a/src/svg/svg-length.cpp b/src/svg/svg-length.cpp index edbc59c36..cd995582d 100644 --- a/src/svg/svg-length.cpp +++ b/src/svg/svg-length.cpp @@ -463,7 +463,7 @@ unsigned int sp_svg_length_read_ldd(gchar const *str, SVGLength::Unit *unit, dou return r; } -std::string const SVGLength::write() +std::string SVGLength::write() const { return sp_svg_length_write_with_units(*this); } diff --git a/src/svg/svg-length.h b/src/svg/svg-length.h index 84056dd5f..2aaf248b1 100644 --- a/src/svg/svg-length.h +++ b/src/svg/svg-length.h @@ -57,7 +57,7 @@ public: bool read(char const *str); void readOrUnset(char const *str, Unit u = NONE, float v = 0, float c = 0); bool readAbsolute(char const *str); - std::string const write(); + std::string write() const; // To set 'v' use '=' void set(Unit u, float v); // Sets computed value based on u and v. void set(Unit u, float v, float c); // Sets all three values. diff --git a/src/text-tag-attributes.h b/src/text-tag-attributes.h index 7a389ed39..2cf7a8bde 100644 --- a/src/text-tag-attributes.h +++ b/src/text-tag-attributes.h @@ -31,11 +31,14 @@ public: /** Process the parameters from the set() function of SPObject. Returns true if \a key was a recognised attribute. */ - bool readSingleAttribute(unsigned key, gchar const *value); + bool readSingleAttribute(unsigned key, gchar const *value, SPStyle const *style, Geom::Rect const *viewport); /// Write out all the contents of #attributes to the given node. void writeTo(Inkscape::XML::Node *node) const; + /// Update relative values + void update( double em, double ex, double w, double h ); + /** For tspan role=line elements we should not use the set x,y coordinates since that would overrule the values calculated by the text layout engine, however if there are more than one element in -- cgit v1.2.3 From e649a1d9cd29f39b2d1cf343cec97ccebce9cf08 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 5 Dec 2015 23:55:57 +0100 Subject: Changed from Desktop to namedview to handle multiples documents (bzr r14500.1.8) --- src/attributes-test.h | 1 + src/attributes.cpp | 1 + src/attributes.h | 1 + src/desktop-events.cpp | 13 +++++++------ src/desktop.cpp | 7 ------- src/desktop.h | 1 - src/display/guideline.cpp | 1 - src/pixmaps/cursor-select.xpm | 38 ++++++++++++++++++++++++++++++++++++++ src/sp-guide.cpp | 5 +---- src/sp-namedview.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/sp-namedview.h | 2 ++ src/ui/dialog/guides.cpp | 3 +-- src/verbs.cpp | 9 ++++----- src/verbs.h | 2 +- src/widgets/desktop-widget.cpp | 29 ++++++++++++++++------------- 15 files changed, 115 insertions(+), 40 deletions(-) create mode 100644 src/pixmaps/cursor-select.xpm (limited to 'src') diff --git a/src/attributes-test.h b/src/attributes-test.h index e197deedf..1fc3972c0 100644 --- a/src/attributes-test.h +++ b/src/attributes-test.h @@ -490,6 +490,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = { {"showgrid", true}, // {"gridtype", true}, {"showguides", true}, +// {"inkscape:lockguides", false}, //not sure about uncomment {"gridtolerance", true}, {"guidetolerance", true}, {"objecttolerance", true}, diff --git a/src/attributes.cpp b/src/attributes.cpp index 9a779836b..ad6a51c88 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -117,6 +117,7 @@ static SPStyleProp const props[] = { {SP_ATTR_INKSCAPE_SNAP_PAGE_BORDER, "inkscape:snap-page"}, {SP_ATTR_INKSCAPE_CURRENT_LAYER, "inkscape:current-layer"}, {SP_ATTR_INKSCAPE_DOCUMENT_UNITS, "inkscape:document-units"}, // This setting sets the Display units, *not* the units used in SVG + {SP_ATTR_INKSCAPE_LOCKGUIDES, "inkscape:lockguides"}, {SP_ATTR_UNITS, "units"}, {SP_ATTR_INKSCAPE_CONNECTOR_SPACING, "inkscape:connector-spacing"}, /* SPColorProfile */ diff --git a/src/attributes.h b/src/attributes.h index f0d3d1228..03df0cb94 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -119,6 +119,7 @@ enum SPAttributeEnum { SP_ATTR_INKSCAPE_SNAP_PAGE_BORDER, SP_ATTR_INKSCAPE_CURRENT_LAYER, SP_ATTR_INKSCAPE_DOCUMENT_UNITS, + SP_ATTR_INKSCAPE_LOCKGUIDES, SP_ATTR_UNITS, SP_ATTR_INKSCAPE_CONNECTOR_SPACING, /* SPColorProfile */ diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp index f86cb2991..6968a19f8 100644 --- a/src/desktop-events.cpp +++ b/src/desktop-events.cpp @@ -50,6 +50,8 @@ #include "ui/tools-switch.h" #include "verbs.h" #include "widgets/desktop-widget.h" +#include "sp-cursor.h" +#include "pixmaps/cursor-select.xpm" #include "xml/repr.h" using Inkscape::DocumentUndo; @@ -514,8 +516,9 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) break; case GDK_ENTER_NOTIFY: { - sp_guideline_set_color(SP_GUIDELINE(item), guide->getHiColor()); - + if (!guide->getLocked()) { + sp_guideline_set_color(SP_GUIDELINE(item), guide->getHiColor()); + } // set move or rotate cursor Geom::Point const event_w(event->crossing.x, event->crossing.y); @@ -531,10 +534,8 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) } else { GdkCursor *guide_cursor; guide_cursor = gdk_cursor_new (GDK_HAND1); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool global_lock = prefs->getBool("/options/guides/guides_lock", false); - if(guide->getLocked() || global_lock){ - guide_cursor = gdk_cursor_new (GDK_X_CURSOR); + if(guide->getLocked()){ + guide_cursor = sp_cursor_new_from_xpm(cursor_select_xpm , 1, 1); } gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), guide_cursor); #if GTK_CHECK_VERSION(3,0,0) diff --git a/src/desktop.cpp b/src/desktop.cpp index 0ddd77594..7b20bcb9f 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -1467,13 +1467,6 @@ void SPDesktop::toggleColorProfAdjust() _widget->toggleColorProfAdjust(); } -void SPDesktop::toggleGuidesLock() -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool guides_lock = prefs->getBool("/options/guides/guides_lock", false); - prefs->setBool("/options/guides/guides_lock", !guides_lock); -} - bool SPDesktop::colorProfAdjustEnabled() { return _widget->colorProfAdjustEnabled(); diff --git a/src/desktop.h b/src/desktop.h index 6d3b96223..754e09766 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -386,7 +386,6 @@ public: void toggleColorProfAdjust(); bool colorProfAdjustEnabled(); - void toggleGuidesLock(); void toggleGrids(); void toggleSnapGlobal(); bool gridsEnabled() const { return grids_visible; }; diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 24353c681..2df0b3f26 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -18,7 +18,6 @@ #include <2geom/transforms.h> #include "sp-canvas-util.h" #include "sp-ctrlpoint.h" -#include "sp-ctrlquadr.h" #include "guideline.h" #include "display/cairo-utils.h" diff --git a/src/pixmaps/cursor-select.xpm b/src/pixmaps/cursor-select.xpm new file mode 100644 index 000000000..569573618 --- /dev/null +++ b/src/pixmaps/cursor-select.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char const *cursor_select_xpm[] = { +"32 32 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +". ", +".. ", +".+. ", +".++. ", +".+++. ", +".++++. ", +".+++++. ", +".++++++. ", +".+++++++. ", +".++++++++. ", +".+++++++++. ", +".++++++..... ", +".++++++. ", +".++..++. ", +".+. .+++. ", +".. .++. ", +". .+++. ", +" .+. ", +" .. ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 00ded2a75..fd07f76ef 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -118,7 +118,6 @@ void SPGuide::set(unsigned int key, const gchar *value) { break; case SP_ATTR_INKSCAPE_LOCKED: this->locked = helperfns_read_bool(value, false); - this->hicolor = this->color; if (value) { this->set_locked(this->locked, false); } @@ -349,9 +348,7 @@ double SPGuide::getDistanceFrom(Geom::Point const &pt) const */ void SPGuide::moveto(Geom::Point const point_on_line, bool const commit) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool global_lock = prefs->getBool("/options/guides/guides_lock", false); - if(this->locked || global_lock) { + if(this->locked) { return; } for (GSList *l = views; l != NULL; l = l->next) { diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index b8554f352..9b34a3760 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -51,7 +51,9 @@ using Inkscape::Util::unit_table; #define DEFAULTPAGECOLOR 0xffffff00 static void sp_namedview_setup_guides(SPNamedView * nv); +static void sp_namedview_lock_guides(SPNamedView * nv); static void sp_namedview_show_single_guide(SPGuide* guide, bool show); +static void sp_namedview_lock_single_guide(SPGuide* guide, bool show); static gboolean sp_str_to_bool(const gchar *str); static gboolean sp_nv_read_opacity(const gchar *str, guint32 *color); @@ -79,6 +81,7 @@ SPNamedView::SPNamedView() : SPObjectGroup(), snap_manager(this) { this->editable = TRUE; this->showguides = TRUE; + this->lockguides = false; this->grids_visible = false; this->showborder = TRUE; this->showpageshadow = TRUE; @@ -240,6 +243,7 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "inkscape:snap-page" ); this->readAttr( "inkscape:current-layer" ); this->readAttr( "inkscape:connector-spacing" ); + this->readAttr( "inkscape:lockguides" ); /* Construct guideline list */ for (SPObject *o = this->firstChild() ; o; o = o->getNext() ) { @@ -600,6 +604,11 @@ void SPNamedView::set(unsigned int key, const gchar* value) { this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; } + case SP_ATTR_INKSCAPE_LOCKGUIDES: + this->lockguides = value ? sp_str_to_bool(value) : FALSE; + sp_namedview_lock_guides(this); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; default: SPObjectGroup::set(key, value); break; @@ -676,6 +685,7 @@ void SPNamedView::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *r } sp_namedview_show_single_guide(SP_GUIDE(g), this->showguides); + sp_namedview_lock_single_guide(SP_GUIDE(g), this->lockguides); } } } @@ -733,6 +743,7 @@ void SPNamedView::show(SPDesktop *desktop) SP_GUIDE(l->data)->sensitize(desktop->getCanvas(), TRUE); } sp_namedview_show_single_guide(SP_GUIDE(l->data), showguides); + sp_namedview_lock_single_guide(SP_GUIDE(l->data), lockguides); } views = g_slist_prepend(views, desktop); @@ -952,6 +963,13 @@ static void sp_namedview_setup_guides(SPNamedView *nv) } } +static void sp_namedview_lock_guides(SPNamedView *nv) +{ + for (GSList *l = nv->guides; l != NULL; l = l->next) { + sp_namedview_lock_single_guide(SP_GUIDE(l->data), nv->lockguides); + } +} + static void sp_namedview_show_single_guide(SPGuide* guide, bool show) { if (show) { @@ -961,6 +979,11 @@ static void sp_namedview_show_single_guide(SPGuide* guide, bool show) } } +static void sp_namedview_lock_single_guide(SPGuide* guide, bool locked) +{ + guide->set_locked(locked, true); +} + void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr) { unsigned int v; @@ -979,6 +1002,24 @@ void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr) doc->setModifiedSinceSave(); } +void sp_namedview_toggle_guides_lock(SPDocument *doc, Inkscape::XML::Node *repr) +{ + unsigned int v; + unsigned int set = sp_repr_get_boolean(repr, "inkscape:lockguides", &v); + if (!set) { // hide guides if not specified, for backwards compatibility + v = true; + } else { + v = !v; + } + + bool saved = DocumentUndo::getUndoSensitive(doc); + DocumentUndo::setUndoSensitive(doc, false); + sp_repr_set_boolean(repr, "inkscape:lockguides", v); + DocumentUndo::setUndoSensitive(doc, saved); + + doc->setModifiedSinceSave(); +} + void sp_namedview_show_grids(SPNamedView * namedview, bool show, bool dirty_document) { namedview->grids_visible = show; @@ -1077,6 +1118,7 @@ void SPNamedView::setGuides(bool v) g_assert(this->getRepr() != NULL); sp_repr_set_boolean(this->getRepr(), "showguides", v); sp_repr_set_boolean(this->getRepr(), "inkscape:guide-bbox", v); + sp_repr_set_boolean(this->getRepr(), "inkscape:locked", false); } bool SPNamedView::getGuides() diff --git a/src/sp-namedview.h b/src/sp-namedview.h index f1ecc12d3..a586ea71c 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -44,6 +44,7 @@ public: unsigned int editable : 1; unsigned int showguides : 1; + unsigned int lockguides : 1; unsigned int showborder : 1; unsigned int showpageshadow : 1; unsigned int borderlayer : 2; @@ -122,6 +123,7 @@ void sp_namedview_document_from_window(SPDesktop *desktop); void sp_namedview_update_layers_from_document (SPDesktop *desktop); void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr); +void sp_namedview_toggle_guides_lock(SPDocument *doc, Inkscape::XML::Node *repr); void sp_namedview_show_grids(SPNamedView *namedview, bool show, bool dirty_document); Inkscape::CanvasGrid * sp_namedview_get_first_enabled_grid(SPNamedView *namedview); diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index faba71615..e0efcde36 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -300,8 +300,7 @@ void GuidelinePropertiesDialog::_setup() { _relative_toggle.signal_toggled().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_modeChanged)); _relative_toggle.set_active(_relative_toggle_status); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool global_guides_lock = prefs->getBool("/options/guides/guides_lock", false); + bool global_guides_lock = _desktop->namedview->lockguides; if(global_guides_lock){ _locked_toggle.set_sensitive(false); } diff --git a/src/verbs.cpp b/src/verbs.cpp index 6eace6048..afcc37bc4 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1938,6 +1938,9 @@ void ZoomVerb::perform(SPAction *action, void *data) case SP_VERB_TOGGLE_GUIDES: sp_namedview_toggle_guides(doc, repr); break; + case SP_VERB_TOGGLE_GUIDES_LOCK: + sp_namedview_toggle_guides_lock(doc, repr); + break; case SP_VERB_TOGGLE_SNAPPING: dt->toggleSnapGlobal(); break; @@ -1989,9 +1992,6 @@ void ZoomVerb::perform(SPAction *action, void *data) case SP_VERB_VIEW_CMS_TOGGLE: dt->toggleColorProfAdjust(); break; - case SP_VERB_VIEW_GUIDES_LOCK_TOGGLE: - dt->toggleGuidesLock(); - break; case SP_VERB_VIEW_ICON_PREVIEW: INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("IconPreviewPanel"); @@ -2831,6 +2831,7 @@ Verb *Verb::_base_verbs[] = { new ZoomVerb(SP_VERB_TOGGLE_SCROLLBARS, "ToggleScrollbars", N_("Scroll_bars"), N_("Show or hide the canvas scrollbars"), NULL), new ZoomVerb(SP_VERB_TOGGLE_GRID, "ToggleGrid", N_("Page _Grid"), N_("Show or hide the page grid"), INKSCAPE_ICON("show-grid")), new ZoomVerb(SP_VERB_TOGGLE_GUIDES, "ToggleGuides", N_("G_uides"), N_("Show or hide guides (drag from a ruler to create a guide)"), INKSCAPE_ICON("show-guides")), + new ZoomVerb(SP_VERB_TOGGLE_GUIDES_LOCK, "ToggleGuidesLook", N_("Gui_des Lock"), N_("Lock or unlock all guides"), INKSCAPE_ICON("object-locked")), new ZoomVerb(SP_VERB_TOGGLE_SNAPPING, "ToggleSnapGlobal", N_("Snap"), N_("Enable snapping"), INKSCAPE_ICON("snap")), new ZoomVerb(SP_VERB_TOGGLE_COMMANDS_TOOLBAR, "ToggleCommandsToolbar", N_("_Commands Bar"), N_("Show or hide the Commands bar (under the menu)"), NULL), new ZoomVerb(SP_VERB_TOGGLE_SNAP_TOOLBAR, "ToggleSnapToolbar", N_("Sn_ap Controls Bar"), N_("Show or hide the snapping controls"), NULL), @@ -2880,8 +2881,6 @@ Verb *Verb::_base_verbs[] = { new ZoomVerb(SP_VERB_VIEW_CMS_TOGGLE, "ViewCmsToggle", N_("Color-managed view"), N_("Toggle color-managed display for this document window"), INKSCAPE_ICON("color-management")), - new ZoomVerb(SP_VERB_VIEW_GUIDES_LOCK_TOGGLE, "GuidesLockToggle", N_("Lock all guides"), - N_("Lock all guides"), INKSCAPE_ICON("object-locked")), new ZoomVerb(SP_VERB_VIEW_ICON_PREVIEW, "ViewIconPreview", N_("Ico_n Preview..."), N_("Open a window to preview objects at different icon resolutions"), INKSCAPE_ICON("dialog-icon-preview")), diff --git a/src/verbs.h b/src/verbs.h index c50829525..e1249684b 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -249,6 +249,7 @@ enum { SP_VERB_TOGGLE_SCROLLBARS, SP_VERB_TOGGLE_GRID, SP_VERB_TOGGLE_GUIDES, + SP_VERB_TOGGLE_GUIDES_LOCK, SP_VERB_TOGGLE_SNAPPING, SP_VERB_TOGGLE_COMMANDS_TOOLBAR, SP_VERB_TOGGLE_SNAP_TOOLBAR, @@ -277,7 +278,6 @@ enum { // SP_VERB_VIEW_COLOR_MODE_PRINT_COLORS_PREVIEW, SP_VERB_VIEW_COLOR_MODE_TOGGLE, SP_VERB_VIEW_CMS_TOGGLE, - SP_VERB_VIEW_GUIDES_LOCK_TOGGLE, SP_VERB_VIEW_ICON_PREVIEW, SP_VERB_ZOOM_PAGE, SP_VERB_ZOOM_PAGE_WIDTH, diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index c2e69e469..901b4d328 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -393,7 +393,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) gtk_box_pack_start( GTK_BOX(dtw->hbox), dtw->tool_toolbox, FALSE, TRUE, 0 ); /* Lock all guides */ gchar const* tip = ""; - Inkscape::Verb* verb = Inkscape::Verb::get( SP_VERB_VIEW_GUIDES_LOCK_TOGGLE ); + Inkscape::Verb* verb = Inkscape::Verb::get( SP_VERB_TOGGLE_GUIDES_LOCK ); if ( verb ) { SPAction *act = verb->get_action( Inkscape::ActionContext( dtw->viewwidget.view ) ); if ( act && act->tip ) { @@ -405,12 +405,6 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) NULL, INKSCAPE_ICON("object-locked"), tip ); - { - bool locked = prefs->getBool("/options/guides/locked"); - if ( locked ) { - sp_button_toggle_set_down( SP_BUTTON(dtw->guides_lock), TRUE ); - } - } g_signal_connect_after( G_OBJECT(dtw->guides_lock), "clicked", G_CALLBACK(update_guides_lock), dtw ); /* Horizontal ruler */ @@ -1006,7 +1000,15 @@ void SPDesktopWidget::updateNamedview() modified_connection = desktop->namedview->connectModified(sigc::mem_fun(*this, &SPDesktopWidget::namedviewModified)); namedviewModified(desktop->namedview, SP_OBJECT_MODIFIED_FLAG); - + SPDocument *doc = desktop->getDocument(); + SPNamedView *nv = desktop->getNamedView(); + Inkscape::XML::Node *repr = nv->getRepr(); + bool locked = desktop->namedview->lockguides; + if ( locked ) { + sp_button_toggle_set_down( SP_BUTTON(guides_lock), TRUE ); + //to reverse the callback + sp_namedview_toggle_guides_lock(doc, repr); + } updateTitle( desktop->doc()->getName() ); } @@ -1073,11 +1075,12 @@ void update_guides_lock( GtkWidget */*button*/, gpointer data ) SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(data); bool down = SP_BUTTON_IS_DOWN(dtw->guides_lock); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/options/guides/guides_lock", down); - if (down) { - dtw->setMessage (Inkscape::NORMAL_MESSAGE, _("Guides are locked")); - } + + SPDocument *doc = dtw->desktop->getDocument(); + SPNamedView *nv = dtw->desktop->getNamedView(); + Inkscape::XML::Node *repr = nv->getRepr(); + nv->lockguides = down; + sp_namedview_toggle_guides_lock(doc, repr); } #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) -- cgit v1.2.3 From 35f5bfbd935a155b16adc31408f820302fd2f040 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 6 Dec 2015 07:57:26 +0100 Subject: Remove leftover assert. (bzr r14506) --- src/libnrtype/Layout-TNG-Compute.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 6b2a6f622..1e8fb0fb1 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -1764,7 +1764,6 @@ bool Layout::Calculator::calculate() } while (span_pos.iter_span != para.unbroken_spans.end()); TRACE(("para %lu end\n\n", _flow._paragraphs.size() - 1)); - assert (_scanline_maker != NULL ); if (_scanline_maker != NULL) { bool is_empty_para = _flow._characters.empty() || _flow._characters.back().line(&_flow).in_paragraph != _flow._paragraphs.size() - 1; if ((is_empty_para && para_end_input_index + 1 >= _flow._input_stream.size()) -- cgit v1.2.3 From 049a747614778df4ee75bd07b71a8afe1688425f Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 6 Dec 2015 13:53:50 +0100 Subject: cppification: GSList replaced by vectors (mostly related to gradients and meshes) (bzr r14504.1.2) --- src/gradient-chemistry.cpp | 2 +- src/gradient-drag.cpp | 383 +++++++++++++++++++-------------------- src/gradient-drag.h | 23 ++- src/ui/tools/gradient-tool.cpp | 38 ++-- src/ui/tools/mesh-tool.cpp | 32 ++-- src/ui/tools/tool-base.cpp | 2 +- src/widgets/gradient-toolbar.cpp | 31 ++-- 7 files changed, 247 insertions(+), 264 deletions(-) (limited to 'src') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 886bf484d..29522d7b1 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -1592,7 +1592,7 @@ void sp_gradient_reverse_selected_gradients(SPDesktop *desktop) GrDrag *drag = ev->get_drag(); // First try selected dragger - if (drag && drag->selected) { + if (drag && !drag->selected.empty()) { drag->selected_reverse_vector(); } else { // If no drag or no dragger selected, act on selection (both fill and stroke gradients) const std::vector list=selection->itemList(); diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index f94ffb838..3e5fcd0f4 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -142,7 +142,7 @@ static int gr_drag_style_query(SPStyle *style, int property, gpointer data) return QUERY_STYLE_NOTHING; } - if (!drag->selected) { + if (drag->selected.empty()) { return QUERY_STYLE_NOTHING; } else { int ret = QUERY_STYLE_NOTHING; @@ -151,11 +151,10 @@ static int gr_drag_style_query(SPStyle *style, int property, gpointer data) cf[0] = cf[1] = cf[2] = cf[3] = 0; int count = 0; - - for (GList *i = drag->selected; i != NULL; i = i->next) { // for all selected draggers - GrDragger *d = (GrDragger *) i->data; - for (GSList const* j = d->draggables; j != NULL; j = j->next) { // for all draggables of dragger - GrDraggable *draggable = (GrDraggable *) j->data; + for(std::set::const_iterator it = drag->selected.begin(); it != drag->selected.end(); ++it) { //for all selected draggers + GrDragger *d = *it; + for(std::vector::const_iterator it2 = d->draggables.begin(); it2 != d->draggables.end(); ++it2 ) { //for all draggables of dragger + GrDraggable *draggable = *it2; if (ret == QUERY_STYLE_NOTHING) { ret = QUERY_STYLE_SINGLE; @@ -239,7 +238,7 @@ Glib::ustring GrDrag::makeStopSafeColor( gchar const *str, bool &isNull ) bool GrDrag::styleSet( const SPCSSAttr *css ) { - if (!selected) { + if (selected.empty()) { return false; } @@ -307,11 +306,10 @@ bool GrDrag::styleSet( const SPCSSAttr *css ) return false; } - for (GList const* sel = selected; sel != NULL; sel = sel->next) { // for all selected draggers - GrDragger* dragger = reinterpret_cast(sel->data); - for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger - GrDraggable *draggable = reinterpret_cast(i->data); - + for(std::set::const_iterator it = selected.begin(); it != selected.end(); ++it) { //for all selected draggers + GrDragger *d = *it; + for(std::vector::const_iterator it2 = d->draggables.begin(); it2 != d->draggables.end(); ++it2 ) { //for all draggables of dragger + GrDraggable *draggable = *it2; local_change = true; sp_item_gradient_stop_set_style(draggable->item, draggable->point_type, draggable->point_i, draggable->fill_or_stroke, stop); } @@ -324,17 +322,17 @@ bool GrDrag::styleSet( const SPCSSAttr *css ) guint32 GrDrag::getColor() { - if (!selected) return 0; + if (selected.empty()) return 0; float cf[4]; cf[0] = cf[1] = cf[2] = cf[3] = 0; int count = 0; - for (GList *i = selected; i != NULL; i = i->next) { // for all selected draggers - GrDragger *d = (GrDragger *) i->data; - for (GSList const* j = d->draggables; j != NULL; j = j->next) { // for all draggables of dragger - GrDraggable *draggable = (GrDraggable *) j->data; + for(std::set::const_iterator it = selected.begin(); it != selected.end(); ++it) { //for all selected draggers + GrDragger *d = *it; + for(std::vector::const_iterator it2 = d->draggables.begin(); it2 != d->draggables.end(); ++it2 ) { //for all draggables of dragger + GrDraggable *draggable = *it2; guint32 c = sp_item_gradient_stop_query_style (draggable->item, draggable->point_type, draggable->point_i, draggable->fill_or_stroke); cf[0] += SP_RGBA32_R_F (c); @@ -580,15 +578,15 @@ bool GrDrag::dropColor(SPItem */*item*/, gchar const *c, Geom::Point p) Glib::ustring toUse = makeStopSafeColor( c, stopIsNull ); // first, see if we can drop onto one of the existing draggers - for (GList *i = draggers; i != NULL; i = i->next) { // for all draggables of dragger - GrDragger *d = (GrDragger *) i->data; + for(std::vector::const_iterator i = draggers.begin(); i != draggers.end(); ++i) { //for all draggers + GrDragger *d = *i ; if (Geom::L2(p - d->point)*desktop->current_zoom() < 5) { SPCSSAttr *stop = sp_repr_css_attr_new (); sp_repr_css_set_property( stop, "stop-color", stopIsNull ? 0 : toUse.c_str() ); sp_repr_css_set_property( stop, "stop-opacity", "1" ); - for (GSList *j = d->draggables; j != NULL; j = j->next) { // for all draggables of dragger - GrDraggable *draggable = (GrDraggable *) j->data; + for(std::vector::const_iterator j = d->draggables.begin(); j != d->draggables.end(); ++j) { //for all draggables of dragger + GrDraggable *draggable = *j; local_change = true; sp_item_gradient_stop_set_style (draggable->item, draggable->point_type, draggable->point_i, draggable->fill_or_stroke, stop); } @@ -599,9 +597,9 @@ bool GrDrag::dropColor(SPItem */*item*/, gchar const *c, Geom::Point p) // now see if we're over line and create a new stop bool over_line = false; - if (lines) { - for (GSList *l = lines; (l != NULL) && (!over_line); l = l->next) { - SPCtrlLine *line = (SPCtrlLine*) l->data; + if (!lines.empty()) { + for (std::vector::const_iterator l = lines.begin(); l != lines.end() && (!over_line); ++l) { + SPCtrlLine *line = *l; Geom::LineSegment ls(line->s, line->e); Geom::Point nearest = ls.pointAt(ls.nearestTime(p)); double dist_screen = Geom::L2(p - nearest) * desktop->current_zoom(); @@ -623,7 +621,6 @@ bool GrDrag::dropColor(SPItem */*item*/, gchar const *c, Geom::Point p) GrDrag::GrDrag(SPDesktop *desktop) : - selected(0), keep_selection(false), local_change(false), desktop(desktop), @@ -676,8 +673,8 @@ GrDrag::~GrDrag() this->style_set_connection.disconnect(); this->style_query_connection.disconnect(); - if (this->selected) { - GrDraggable *draggable = (GrDraggable *) ((GrDragger*)this->selected->data)->draggables->data; + if (! this->selected.empty()) { + GrDraggable *draggable = (*(this->selected.begin()))->draggables[0]; desktop->gr_item = draggable->item; desktop->gr_point_type = draggable->point_type; desktop->gr_point_i = draggable->point_i; @@ -690,18 +687,16 @@ GrDrag::~GrDrag() } deselect_all(); - for (GList *l = this->draggers; l != NULL; l = l->next) { - delete ((GrDragger *) l->data); + for (std::vector::const_iterator it = this->draggers.begin(); it != this->draggers.end(); ++it) { + delete (*it); } - g_list_free (this->draggers); - this->draggers = NULL; - this->selected = NULL; + this->draggers.clear(); + this->selected.clear(); - for (GSList *l = this->lines; l != NULL; l = l->next) { - sp_canvas_item_destroy(SP_CANVAS_ITEM(l->data)); + for (std::vector::const_iterator it = this->lines.begin(); it != this->lines.end(); ++it) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(*it)); } - g_slist_free (this->lines); - this->lines = NULL; + this->lines.clear(); } GrDraggable::GrDraggable(SPItem *item, GrPointType point_type, guint point_i, Inkscape::PaintTarget fill_or_stroke) : @@ -751,39 +746,43 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui if (state & GDK_SHIFT_MASK) { // with Shift; unsnap if we carry more than one draggable - if (dragger->draggables && dragger->draggables->next) { + if (dragger->draggables.size()>1) { // create a new dragger GrDragger *dr_new = new GrDragger (dragger->parent, dragger->point, NULL); - dragger->parent->draggers = g_list_prepend (dragger->parent->draggers, dr_new); + dragger->parent->draggers.insert(dragger->parent->draggers.begin(), dr_new); // relink to it all but the first draggable in the list - for (GSList const* i = dragger->draggables->next; i != NULL; i = i->next) { - GrDraggable *draggable = (GrDraggable *) i->data; + std::vector::const_iterator i = dragger->draggables.begin(); + for ( ++i ; i != dragger->draggables.end(); ++i ) { + GrDraggable *draggable = *i; dr_new->addDraggable (draggable); } dr_new->updateKnotShape(); - g_slist_free (dragger->draggables->next); - dragger->draggables->next = NULL; + if(dragger->draggables.size()>1){ + GrDraggable *tmp = dragger->draggables[0]; + dragger->draggables.clear(); + dragger->draggables.push_back(tmp); + } dragger->updateKnotShape(); dragger->updateTip(); } } else if (!(state & GDK_CONTROL_MASK)) { // without Shift or Ctrl; see if we need to snap to another dragger - for (GList *di = dragger->parent->draggers; di != NULL; di = di->next) { - GrDragger *d_new = (GrDragger *) di->data; + for (std::vector::const_iterator di = dragger->parent->draggers.begin(); di != dragger->parent->draggers.end() ; ++di) { + GrDragger *d_new = *di; if (dragger->mayMerge(d_new) && Geom::L2 (d_new->point - p) < snap_dist) { // Merge draggers: - for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger - GrDraggable *draggable = (GrDraggable *) i->data; + for (std::vector::const_iterator i = dragger->draggables.begin(); i != dragger->draggables.end(); ++i) { + GrDraggable *draggable = *i; // copy draggable to d_new: GrDraggable *da_new = new GrDraggable (draggable->item, draggable->point_type, draggable->point_i, draggable->fill_or_stroke); d_new->addDraggable (da_new); } // unlink and delete this dragger - dragger->parent->draggers = g_list_remove (dragger->parent->draggers, dragger); - d_new->parent->draggers = g_list_remove (d_new->parent->draggers, dragger); - d_new->parent->selected = g_list_remove (d_new->parent->selected, dragger); + dragger->parent->draggers.erase(std::remove(dragger->parent->draggers.begin(),dragger->parent->draggers.end(), dragger),dragger->parent->draggers.end()); + d_new->parent->draggers.erase(std::remove(d_new->parent->draggers.begin(),d_new->parent->draggers.end(), dragger),d_new->parent->draggers.end()); + d_new->parent->selected.erase(dragger); delete dragger; // throw out delayed snap context @@ -817,14 +816,14 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui unsigned snaps = abs(prefs->getInt("/options/rotationsnapsperpi/value", 12)); /* 0 means no snapping. */ - for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { - GrDraggable *draggable = (GrDraggable *) i->data; + for (std::vector::const_iterator i = dragger->draggables.begin(); i != dragger->draggables.end(); ++i) { + GrDraggable *draggable = *i; Geom::Point dr_snap(Geom::infinity(), Geom::infinity()); if (draggable->point_type == POINT_LG_BEGIN || draggable->point_type == POINT_LG_END) { - for (GList *di = dragger->parent->draggers; di != NULL; di = di->next) { - GrDragger *d_new = (GrDragger *) di->data; + for (std::vector::const_iterator di = dragger->parent->draggers.begin() ; di != dragger->parent->draggers.end() ; ++di) { + GrDragger *d_new = *di; if (d_new == dragger) continue; if (d_new->isA (draggable->item, @@ -842,8 +841,8 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui } } } else if (draggable->point_type == POINT_RG_R1 || draggable->point_type == POINT_RG_R2 || draggable->point_type == POINT_RG_FOCUS) { - for (GList *di = dragger->parent->draggers; di != NULL; di = di->next) { - GrDragger *d_new = (GrDragger *) di->data; + for (std::vector::const_iterator di = dragger->parent->draggers.begin(); di != dragger->parent->draggers.end(); ++di) { + GrDragger *d_new = *di; if (d_new == dragger) continue; if (d_new->isA (draggable->item, @@ -896,7 +895,7 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui knot->moveto(p); } - drag->keep_selection = (bool) g_list_find(drag->selected, dragger); + drag->keep_selection = (drag->selected.find(dragger)!=drag->selected.end()); bool scale_radial = (state & GDK_CONTROL_MASK) && (state & GDK_SHIFT_MASK); if (drag->keep_selection) { @@ -912,16 +911,16 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui } -static void gr_midpoint_limits(GrDragger *dragger, SPObject *server, Geom::Point *begin, Geom::Point *end, Geom::Point *low_lim, Geom::Point *high_lim, GSList **moving) +static void gr_midpoint_limits(GrDragger *dragger, SPObject *server, Geom::Point *begin, Geom::Point *end, Geom::Point *low_lim, Geom::Point *high_lim, std::vector &moving) { GrDrag *drag = dragger->parent; // a midpoint dragger can (logically) only contain one GrDraggable - GrDraggable *draggable = (GrDraggable *) dragger->draggables->data; + GrDraggable *draggable = dragger->draggables[0]; // get begin and end points between which dragging is allowed: // the draglimits are between knot(lowest_i - 1) and knot(highest_i + 1) - *moving = g_slist_append(*moving, dragger); + moving.push_back(dragger); guint lowest_i = draggable->point_i; guint highest_i = draggable->point_i; @@ -932,9 +931,9 @@ static void gr_midpoint_limits(GrDragger *dragger, SPObject *server, Geom::Point while ( true ) { d_add = drag->getDraggerFor(draggable->item, draggable->point_type, lowest_i - 1, draggable->fill_or_stroke); - if ( d_add && g_list_find(drag->selected, d_add) ) { + if ( d_add && drag->selected.find(d_add)!=drag->selected.end() ) { lowest_i = lowest_i - 1; - *moving = g_slist_prepend(*moving, d_add); + moving.insert(moving.begin(),d_add); lowest_dragger = d_add; } else { break; @@ -944,9 +943,9 @@ static void gr_midpoint_limits(GrDragger *dragger, SPObject *server, Geom::Point while ( true ) { d_add = drag->getDraggerFor(draggable->item, draggable->point_type, highest_i + 1, draggable->fill_or_stroke); - if ( d_add && g_list_find(drag->selected, d_add) ) { + if ( d_add && drag->selected.find(d_add)!=drag->selected.end() ) { highest_i = highest_i + 1; - *moving = g_slist_append(*moving, d_add); + moving.push_back(d_add); highest_dragger = d_add; } else { break; @@ -1002,7 +1001,7 @@ static void gr_knot_moved_midpoint_handler(SPKnot */*knot*/, Geom::Point const & GrDragger *dragger = (GrDragger *) data; GrDrag *drag = dragger->parent; // a midpoint dragger can (logically) only contain one GrDraggable - GrDraggable *draggable = (GrDraggable *) dragger->draggables->data; + GrDraggable *draggable = dragger->draggables[0]; // FIXME: take from prefs double snap_fraction = 0.1; @@ -1013,8 +1012,8 @@ static void gr_knot_moved_midpoint_handler(SPKnot */*knot*/, Geom::Point const & SPObject *server = draggable->getServer(); - GSList *moving = NULL; - gr_midpoint_limits(dragger, server, &begin, &end, &low_lim, &high_lim, &moving); + std::vector moving; + gr_midpoint_limits(dragger, server, &begin, &end, &low_lim, &high_lim, moving); if (state & GDK_CONTROL_MASK) { Geom::LineSegment ls(low_lim, high_lim); @@ -1033,8 +1032,8 @@ static void gr_knot_moved_midpoint_handler(SPKnot */*knot*/, Geom::Point const & } Geom::Point displacement = p - dragger->point; - for (GSList const* i = moving; i != NULL; i = i->next) { - GrDragger *drg = (GrDragger*) i->data; + for (std::vector::const_iterator i = moving.begin(); i!= moving.end(); ++i ) { + GrDragger *drg = *i; SPKnot *drgknot = drg->knot; Geom::Point this_move = displacement; if (state & GDK_MOD1_MASK) { @@ -1054,8 +1053,6 @@ static void gr_knot_moved_midpoint_handler(SPKnot */*knot*/, Geom::Point const & drg->updateDependencies(false); } - g_slist_free(moving); - drag->keep_selection = dragger->isSelected(); } @@ -1085,12 +1082,11 @@ static void gr_knot_ungrabbed_handler(SPKnot *knot, unsigned int state, gpointer dragger->fireDraggables (true); } dragger->updateHandles( dragger->point_original, MG_NODE_NO_SCALE ); - - for (GList *i = dragger->parent->selected; i != NULL; i = i->next) { - GrDragger *d = (GrDragger *) i->data; - if (d == dragger) + + for (std::set::const_iterator it = dragger->parent->selected.begin(); it != dragger->parent->selected.end() ; ++it ) { + if (*it == dragger) continue; - d->fireDraggables (true); + (*it)->fireDraggables (true); } // make this dragger selected @@ -1112,7 +1108,7 @@ static void gr_knot_ungrabbed_handler(SPKnot *knot, unsigned int state, gpointer static void gr_knot_clicked_handler(SPKnot */*knot*/, guint state, gpointer data) { GrDragger *dragger = (GrDragger *) data; - GrDraggable *draggable = (GrDraggable *) dragger->draggables->data; + GrDraggable *draggable = dragger->draggables[0]; if (!draggable) return; if ( (state & GDK_CONTROL_MASK) && (state & GDK_MOD1_MASK ) ) { @@ -1185,7 +1181,7 @@ static void gr_knot_doubleclicked_handler(SPKnot */*knot*/, guint /*state*/, gpo dragger->point_original = dragger->point; - if (dragger->draggables == NULL) + if (dragger->draggables.empty()) return; /* @@ -1200,8 +1196,8 @@ static void gr_knot_doubleclicked_handler(SPKnot */*knot*/, guint /*state*/, gpo */ void GrDragger::fireDraggables(bool write_repr, bool scale_radial, bool merging_focus) { - for (GSList const* i = this->draggables; i != NULL; i = i->next) { - GrDraggable *draggable = (GrDraggable *) i->data; + for (std::vector::const_iterator i = this->draggables.begin(); i != this->draggables.end(); ++i) { + GrDraggable *draggable = *i; // set local_change flag so that selection_changed callback does not regenerate draggers this->parent->local_change = true; @@ -1221,8 +1217,8 @@ void GrDragger::fireDraggables(bool write_repr, bool scale_radial, bool merging_ */ bool GrDragger::isA(GrPointType point_type) { - for (GSList const* i = this->draggables; i != NULL; i = i->next) { - GrDraggable *draggable = reinterpret_cast(i->data); + for (std::vector::const_iterator i = this->draggables.begin(); i != this->draggables.end(); ++i) { + GrDraggable *draggable = *i; if (draggable->point_type == point_type) { return true; } @@ -1235,8 +1231,8 @@ bool GrDragger::isA(GrPointType point_type) */ bool GrDragger::isA(SPItem *item, GrPointType point_type, gint point_i, Inkscape::PaintTarget fill_or_stroke) { - for (GSList const* i = this->draggables; i != NULL; i = i->next) { - GrDraggable *draggable = (GrDraggable *) i->data; + for (std::vector::const_iterator i = this->draggables.begin(); i != this->draggables.end(); ++i) { + GrDraggable *draggable = *i; if ( (draggable->point_type == point_type) && (draggable->point_i == point_i) && (draggable->item == item) && (draggable->fill_or_stroke == fill_or_stroke) ) { return true; } @@ -1249,8 +1245,8 @@ bool GrDragger::isA(SPItem *item, GrPointType point_type, gint point_i, Inkscape */ bool GrDragger::isA(SPItem *item, GrPointType point_type, Inkscape::PaintTarget fill_or_stroke) { - for (GSList const* i = this->draggables; i != NULL; i = i->next) { - GrDraggable *draggable = (GrDraggable *) i->data; + for (std::vector::const_iterator i = this->draggables.begin(); i != this->draggables.end(); ++i) { + GrDraggable *draggable = *i; if ( (draggable->point_type == point_type) && (draggable->item == item) && (draggable->fill_or_stroke == fill_or_stroke) ) { return true; } @@ -1282,10 +1278,10 @@ bool GrDragger::mayMerge(GrDragger *other) if (this == other) return false; - for (GSList const* i = this->draggables; i != NULL; i = i->next) { // for all draggables of this - GrDraggable *da1 = (GrDraggable *) i->data; - for (GSList const* j = other->draggables; j != NULL; j = j->next) { // for all draggables of other - GrDraggable *da2 = (GrDraggable *) j->data; + for (std::vector::const_iterator i = this->draggables.begin(); i != this->draggables.end(); ++i) { + GrDraggable *da1 = *i; + for (std::vector::const_iterator j = other->draggables.begin(); j != other->draggables.end(); ++j) { + GrDraggable *da2 = *j; if (!da1->mayMerge(da2)) return false; } @@ -1295,8 +1291,8 @@ bool GrDragger::mayMerge(GrDragger *other) bool GrDragger::mayMerge(GrDraggable *da2) { - for (GSList const* i = this->draggables; i != NULL; i = i->next) { // for all draggables of this - GrDraggable *da1 = (GrDraggable *) i->data; + for (std::vector::const_iterator i = this->draggables.begin(); i != this->draggables.end(); ++i) { + GrDraggable *da1 = *i; if (!da1->mayMerge(da2)) return false; } @@ -1339,10 +1335,10 @@ GrDragger::updateHandles ( Geom::Point pc_old, MeshNodeOperation op ) bool scale = false; if( scale == true ) { - for ( GList *i = drag->selected; i != NULL; i = i->next ) { - GrDragger *dragger = (GrDragger *) i->data; - for ( GSList *j = dragger->draggables; j != NULL; j = j->next ) { - GrDraggable *draggable = (GrDraggable *) j->data; + for( std::set::const_iterator it = drag->selected.begin(); it != drag->selected.end(); ++it ) { + GrDragger *dragger = *it; + for (std::vector::const_iterator it2 = dragger->draggables.begin(); it2 != dragger->draggables.end(); ++it2 ) { + GrDraggable *draggable = *it2; // Check draggable is of type POINT_MG_CORNER (don't allow selection of POINT_MG_HANDLE) if( draggable->point_type != POINT_MG_CORNER ) continue; @@ -1360,8 +1356,8 @@ GrDragger::updateHandles ( Geom::Point pc_old, MeshNodeOperation op ) // Loop over all draggables in moved corner std::map > dragger_corners; - for ( GSList *j = draggables; j != NULL; j = j->next ) { - GrDraggable *draggable = (GrDraggable *) j->data; + for (std::vector::const_iterator j = draggables.begin(); j != draggables.end(); ++j ) { + GrDraggable *draggable = *j; SPItem *item = draggable->item; gint point_type = draggable->point_type; @@ -1417,8 +1413,8 @@ void GrDragger::updateTip() this->knot->tip = NULL; } - if (g_slist_length (this->draggables) == 1) { - GrDraggable *draggable = (GrDraggable *) this->draggables->data; + if (this->draggables.size() == 1) { + GrDraggable *draggable = this->draggables[0]; char *item_desc = draggable->item->detailedDescription(); switch (draggable->point_type) { case POINT_LG_MID: @@ -1439,10 +1435,10 @@ void GrDragger::updateTip() break; } g_free(item_desc); - } else if (g_slist_length (draggables) == 2 && isA (POINT_RG_CENTER) && isA (POINT_RG_FOCUS)) { + } else if (draggables.size() == 2 && isA (POINT_RG_CENTER) && isA (POINT_RG_FOCUS)) { this->knot->tip = g_strdup_printf ("%s", _("Radial gradient center and focus; drag with Shift to separate focus")); } else { - int length = g_slist_length (this->draggables); + int length = this->draggables.size(); this->knot->tip = g_strdup_printf (ngettext("Gradient point shared by %d gradient; drag with Shift to separate", "Gradient point shared by %d gradients; drag with Shift to separate", length), @@ -1455,9 +1451,9 @@ void GrDragger::updateTip() */ void GrDragger::updateKnotShape() { - if (!draggables) + if (draggables.empty()) return; - GrDraggable *last = (GrDraggable *) g_slist_last(draggables)->data; + GrDraggable *last = draggables.back(); g_object_set (G_OBJECT (this->knot->item), "shape", gr_knot_shapes[last->point_type], NULL); } @@ -1466,7 +1462,7 @@ void GrDragger::updateKnotShape() */ void GrDragger::addDraggable(GrDraggable *draggable) { - this->draggables = g_slist_prepend (this->draggables, draggable); + this->draggables.insert(this->draggables.begin(), draggable); this->updateTip(); } @@ -1477,18 +1473,18 @@ void GrDragger::addDraggable(GrDraggable *draggable) */ void GrDragger::moveThisToDraggable(SPItem *item, GrPointType point_type, gint point_i, Inkscape::PaintTarget fill_or_stroke, bool write_repr) { - GrDraggable *dr_first = reinterpret_cast(draggables->data); - if (!dr_first) { + if (draggables.empty()) return; - } + + GrDraggable *dr_first = draggables[0]; this->point = getGradientCoords(dr_first->item, dr_first->point_type, dr_first->point_i, dr_first->fill_or_stroke); this->point_original = this->point; this->knot->moveto(this->point); - for (GSList const* i = draggables; i != NULL; i = i->next) { - GrDraggable *da = (GrDraggable *) i->data; + for (std::vector::const_iterator j = draggables.begin(); j != draggables.end(); ++j ) { + GrDraggable *da = *j; if ( (da->item == item) && (point_type == -1 || da->point_type == point_type) && (point_i == -1 || da->point_i == point_i) && @@ -1531,8 +1527,8 @@ void GrDragger::updateMidstopDependencies(GrDraggable *draggable, bool write_rep */ void GrDragger::updateDependencies(bool write_repr) { - for (GSList const* i = this->draggables; i != NULL; i = i->next) { - GrDraggable *draggable = (GrDraggable *) i->data; + for (std::vector::const_iterator j = draggables.begin(); j != draggables.end(); ++j ) { + GrDraggable *draggable = *j; switch (draggable->point_type) { case POINT_LG_BEGIN: { @@ -1590,7 +1586,7 @@ GrDragger::GrDragger(GrDrag *parent, Geom::Point p, GrDraggable *draggable) : point(p), point_original(p) { - this->draggables = NULL; + this->draggables.clear(); this->parent = parent; @@ -1649,12 +1645,10 @@ GrDragger::~GrDragger() knot_unref(this->knot); // delete all draggables - for (GSList const* i = this->draggables; i != NULL; i = i->next) { - delete ((GrDraggable *) i->data); + for (std::vector::const_iterator j = this->draggables.begin(); j != this->draggables.end(); ++j ) { + delete (*j); } - - g_slist_free (this->draggables); - this->draggables = NULL; + this->draggables.clear(); } /** @@ -1662,10 +1656,10 @@ GrDragger::~GrDragger() */ GrDragger *GrDrag::getDraggerFor(SPItem *item, GrPointType point_type, gint point_i, Inkscape::PaintTarget fill_or_stroke) { - for (GList const* i = this->draggers; i != NULL; i = i->next) { - GrDragger *dragger = (GrDragger *) i->data; - for (GSList const* j = dragger->draggables; j != NULL; j = j->next) { - GrDraggable *da2 = (GrDraggable *) j->data; + for (std::vector::const_iterator i = this->draggers.begin(); i != this->draggers.end(); ++i ) { + GrDragger *dragger = *i; + for (std::vector::const_iterator j = dragger->draggables.begin(); j != dragger->draggables.end(); ++j ) { + GrDraggable *da2 = *j; if ( (da2->item == item) && (point_type == -1 || da2->point_type == point_type) && // -1 means this does not matter (point_i == -1 || da2->point_i == point_i) && // -1 means this does not matter @@ -1716,7 +1710,7 @@ void GrDragger::deselect() bool GrDragger::isSelected() { - return g_list_find (parent->selected, this); + return parent->selected.find(this) != parent->selected.end(); } /** @@ -1724,10 +1718,9 @@ GrDragger::isSelected() */ void GrDrag::deselect_all() { - while (selected) { - ( (GrDragger*) selected->data)->deselect(); - selected = g_list_remove(selected, selected->data); - } + for (std::set::const_iterator it = selected.begin(); it != selected.end(); ++it ) + (*it)->deselect(); + selected.clear(); } /** @@ -1744,8 +1737,8 @@ void GrDrag::deselectAll() */ void GrDrag::selectAll() { - for (GList *l = this->draggers; l != NULL; l = l->next) { - GrDragger *d = ((GrDragger *) l->data); + for (std::vector::const_iterator l = this->draggers.begin(); l != this->draggers.end(); ++l) { + GrDragger *d = *l; setSelected (d, true, true); } } @@ -1755,8 +1748,8 @@ void GrDrag::selectAll() */ void GrDrag::selectByCoords(std::vector coords) { - for (GList *l = this->draggers; l != NULL; l = l->next) { - GrDragger *d = ((GrDragger *) l->data); + for (std::vector::const_iterator l = this->draggers.begin(); l != this->draggers.end(); ++l) { + GrDragger *d = *l; for (guint k = 0; k < coords.size(); k++) { if (Geom::L2 (d->point - coords[k]) < 1e-4) { setSelected (d, true, true); @@ -1770,12 +1763,12 @@ void GrDrag::selectByCoords(std::vector coords) */ void GrDrag::selectByStop(SPStop *stop, bool add_to_selection, bool override ) { - for (GList *i = this->draggers; i != NULL; i = i->next) { + for (std::vector::const_iterator l = this->draggers.begin(); l != this->draggers.end(); ++l) { - GrDragger *dragger = (GrDragger *) i->data; - for (GSList const* j = dragger->draggables; j != NULL; j = j->next) { + GrDragger *dragger = *l; + for (std::vector::const_iterator j = dragger->draggables.begin(); j != dragger->draggables.end(); ++j) { - GrDraggable *d = (GrDraggable *) j->data; + GrDraggable *d = *j; SPGradient *gradient = getGradient(d->item, d->fill_or_stroke); SPGradient *vector = gradient->getVector(false); SPStop *stop_i = sp_get_stop_i(vector, d->point_i); @@ -1791,8 +1784,8 @@ void GrDrag::selectByStop(SPStop *stop, bool add_to_selection, bool override ) */ void GrDrag::selectRect(Geom::Rect const &r) { - for (GList *l = this->draggers; l != NULL; l = l->next) { - GrDragger *d = ((GrDragger *) l->data); + for (std::vector::const_iterator l = this->draggers.begin(); l != this->draggers.end(); ++l) { + GrDragger *d = *l; if (r.contains(d->point)) { setSelected (d, true, true); } @@ -1816,20 +1809,18 @@ void GrDrag::setSelected(GrDragger *dragger, bool add_to_selection, bool overrid if (add_to_selection) { if (!dragger) return; if (override) { - if (!g_list_find(selected, dragger)) { - selected = g_list_prepend(selected, dragger); - } + selected.insert(dragger); dragger->select(); seldragger = dragger; } else { // toggle - if (g_list_find(selected, dragger)) { - selected = g_list_remove(selected, dragger); + if(selected.find(dragger)!=selected.end()) { + selected.erase(dragger); dragger->deselect(); - if (selected) { - seldragger = (GrDragger*) selected->data; // select the dragger that is first in the list + if (!selected.empty()) { + seldragger = *(selected.begin()); // select the dragger that is first in the list } } else { - selected = g_list_prepend(selected, dragger); + selected.insert(dragger); dragger->select(); seldragger = dragger; } @@ -1837,7 +1828,7 @@ void GrDrag::setSelected(GrDragger *dragger, bool add_to_selection, bool overrid } else { deselect_all(); if (dragger) { - selected = g_list_prepend(selected, dragger); + selected.insert(dragger); dragger->select(); seldragger = dragger; } @@ -1853,11 +1844,11 @@ void GrDrag::setSelected(GrDragger *dragger, bool add_to_selection, bool overrid */ void GrDrag::setDeselected(GrDragger *dragger) { - if (g_list_find(selected, dragger)) { - selected = g_list_remove(selected, dragger); + if (selected.find(dragger) != selected.end()) { + selected.erase(dragger); dragger->deselect(); } - this->desktop->emitToolSubselectionChanged((gpointer) (selected ? selected->data : NULL )); + this->desktop->emitToolSubselectionChanged((gpointer) (selected.empty() ? NULL :*(selected.begin()))); } @@ -1873,7 +1864,7 @@ void GrDrag::addLine(SPItem *item, Geom::Point p1, Geom::Point p2, Inkscape::Pai sp_canvas_item_move_to_z(line, 0); line->item = item; sp_canvas_item_show(line); - this->lines = g_slist_append(this->lines, line); + this->lines.push_back(line); } @@ -1889,7 +1880,7 @@ void GrDrag::addCurve(SPItem *item, Geom::Point p0, Geom::Point p1, Geom::Point sp_canvas_item_move_to_z(line, 0); line->item = item; sp_canvas_item_show (line); - this->lines = g_slist_append (this->lines, line); + this->lines.push_back(line); } @@ -1901,8 +1892,8 @@ void GrDrag::addDragger(GrDraggable *draggable) { Geom::Point p = getGradientCoords(draggable->item, draggable->point_type, draggable->point_i, draggable->fill_or_stroke); - for (GList *i = this->draggers; i != NULL; i = i->next) { - GrDragger *dragger = (GrDragger *) i->data; + for (std::vector::const_iterator l = this->draggers.begin(); l != this->draggers.end(); ++l) { + GrDragger *dragger = *l; if (dragger->mayMerge (draggable) && Geom::L2 (dragger->point - p) < MERGE_DIST) { // distance is small, merge this draggable into dragger, no need to create new dragger dragger->addDraggable (draggable); @@ -1913,7 +1904,7 @@ void GrDrag::addDragger(GrDraggable *draggable) GrDragger *new_dragger = new GrDragger(this, p, draggable); // fixme: draggers should be added AFTER the last one: this way tabbing through them will be from begin to end. - this->draggers = g_list_append (this->draggers, new_dragger); + this->draggers.push_back(new_dragger); } /** @@ -2071,15 +2062,12 @@ void GrDrag::grabKnot(SPItem *item, GrPointType point_type, gint point_i, Inksca */ void GrDrag::updateDraggers() { - while (selected) { - selected = g_list_remove(selected, selected->data); - } + selected.clear(); // delete old draggers - for (GList const* i = this->draggers; i != NULL; i = i->next) { - delete static_cast(i->data); + for (std::vector::const_iterator l = this->draggers.begin(); l != this->draggers.end(); ++l) { + delete (*l); } - g_list_free(this->draggers); - this->draggers = NULL; + this->draggers.clear(); g_return_if_fail(this->selection != NULL); std::vector list = this->selection->itemList(); @@ -2127,8 +2115,8 @@ void GrDrag::updateDraggers() */ bool GrDrag::mouseOver() { - for (GList const* i = this->draggers; i != NULL; i = i->next) { - GrDragger *d = (GrDragger *) i->data; + for (std::vector::const_iterator l = this->draggers.begin(); l != this->draggers.end(); ++l) { + GrDragger *d = *l; if (d->knot && (d->knot->flags & SP_KNOT_MOUSEOVER)) { return true; } @@ -2143,11 +2131,10 @@ bool GrDrag::mouseOver() void GrDrag::updateLines() { // delete old lines - for (GSList const *i = this->lines; i != NULL; i = i->next) { - sp_canvas_item_destroy(SP_CANVAS_ITEM(i->data)); + for (std::vector::const_iterator i = this->lines.begin(); i != this->lines.end(); ++i) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(*i)); } - g_slist_free(this->lines); - this->lines = NULL; + this->lines.clear(); g_return_if_fail(this->selection != NULL); @@ -2313,13 +2300,11 @@ void GrDrag::updateLevels() void GrDrag::selected_reverse_vector() { - if (selected == NULL) + if (selected.empty()) return; - for (GSList const* i = ( (GrDragger*) selected->data )->draggables; i != NULL; i = i->next) { - GrDraggable *draggable = (GrDraggable *) i->data; - - sp_item_gradient_reverse_vector (draggable->item, draggable->fill_or_stroke); + for(std::vector::const_iterator it = (*(selected.begin()))->draggables.begin(); it != (*(selected.begin()))->draggables.end(); ++it) { + sp_item_gradient_reverse_vector ((*it)->item, (*it)->fill_or_stroke); } } @@ -2330,13 +2315,13 @@ void GrDrag::selected_move_nowrite(double x, double y, bool scale_radial) void GrDrag::selected_move(double x, double y, bool write_repr, bool scale_radial) { - if (selected == NULL) + if (selected.empty()) return; bool did = false; - for (GList *i = selected; i != NULL; i = i->next) { - GrDragger *d = (GrDragger *) i->data; + for(std::set::const_iterator it = selected.begin(); it != selected.end(); ++it) { + GrDragger *d = *it; if (!d->isA(POINT_LG_MID) && !d->isA(POINT_RG_MID1) && !d->isA(POINT_RG_MID2)) { // if this is an endpoint, @@ -2347,12 +2332,12 @@ void GrDrag::selected_move(double x, double y, bool write_repr, bool scale_radia if (d->isA(POINT_RG_R1) || d->isA(POINT_RG_R2) || (d->isA(POINT_RG_FOCUS) && !d->isA(POINT_RG_CENTER))) { bool skip_radius_with_center = false; - for (GList *di = selected; di != NULL; di = di->next) { - GrDragger *d_new = (GrDragger *) di->data; - if (d_new->isA (((GrDraggable *) d->draggables->data)->item, + for(std::set::const_iterator di = selected.begin(); di != selected.end(); ++di) { + GrDragger *d_new = *di; + if (d_new->isA (( d->draggables[0])->item, POINT_RG_CENTER, 0, - ((GrDraggable *) d->draggables->data)->fill_or_stroke)) { + (d->draggables[0])->fill_or_stroke)) { // FIXME: here we take into account only the first draggable! skip_radius_with_center = true; } @@ -2382,23 +2367,23 @@ void GrDrag::selected_move(double x, double y, bool write_repr, bool scale_radia if (!did) { // none of the end draggers are selected, so let's try to move the mids - GrDragger *dragger = (GrDragger *) selected->data; + GrDragger *dragger = *(selected.begin()); // a midpoint dragger can (logically) only contain one GrDraggable - GrDraggable *draggable = (GrDraggable *) dragger->draggables->data; + GrDraggable *draggable = dragger->draggables[0]; Geom::Point begin(0,0), end(0,0); Geom::Point low_lim(0,0), high_lim(0,0); SPObject *server = draggable->getServer(); - GSList *moving = NULL; - gr_midpoint_limits(dragger, server, &begin, &end, &low_lim, &high_lim, &moving); + std::vector moving; + gr_midpoint_limits(dragger, server, &begin, &end, &low_lim, &high_lim, moving); Geom::LineSegment ls(low_lim, high_lim); Geom::Point p = ls.pointAt(ls.nearestTime(dragger->point + Geom::Point(x,y))); Geom::Point displacement = p - dragger->point; - for (GSList const* i = moving; i != NULL; i = i->next) { - GrDragger *drg = (GrDragger*) i->data; + for(std::vector::const_iterator i = moving.begin(); i!= moving.end();++i) { + GrDragger *drg = *i; SPKnot *drgknot = drg->knot; drg->point += displacement; drgknot->moveto(drg->point); @@ -2407,8 +2392,6 @@ void GrDrag::selected_move(double x, double y, bool write_repr, bool scale_radia did = true; } - g_slist_free(moving); - if (write_repr && did) { // we did an undoable action DocumentUndo::maybeDone(desktop->getDocument(), "grmovem", SP_VERB_CONTEXT_GRADIENT, @@ -2432,11 +2415,11 @@ void GrDrag::selected_move_screen(double x, double y) GrDragger *GrDrag::select_next() { GrDragger *d = NULL; - if (selected == NULL || g_list_find(draggers, selected->data)->next == NULL) { - if (draggers) - d = (GrDragger *) draggers->data; + if (selected.empty() || (++find(draggers.begin(),draggers.end(),*(selected.begin())))==draggers.end()) { + if (!draggers.empty()) + d = draggers[0]; } else { - d = (GrDragger *) g_list_find(draggers, selected->data)->next->data; + d = *(++find(draggers.begin(),draggers.end(),*(selected.begin()))); } if (d) setSelected (d); @@ -2449,11 +2432,11 @@ GrDragger *GrDrag::select_next() GrDragger *GrDrag::select_prev() { GrDragger *d = NULL; - if (selected == NULL || g_list_find(draggers, selected->data)->prev == NULL) { - if (draggers) - d = (GrDragger *) g_list_last (draggers)->data; + if (selected.empty() || draggers[0] == (*(selected.begin()))) { + if (!draggers.empty()) + d = draggers[draggers.size()-1]; } else { - d = (GrDragger *) g_list_find(draggers, selected->data)->prev->data; + d = *(--find(draggers.begin(),draggers.end(),*(selected.begin()))); } if (d) setSelected (d); @@ -2464,7 +2447,7 @@ GrDragger *GrDrag::select_prev() // FIXME: i.m.o. an ugly function that I just made to work, but... aargh! (Johan) void GrDrag::deleteSelected(bool just_one) { - if (!selected) return; + if (selected.empty()) return; SPDocument *document = NULL; @@ -2477,10 +2460,10 @@ void GrDrag::deleteSelected(bool just_one) GSList *midstoplist = NULL; // list of stops that must be deleted (will be deleted first) GSList *endstoplist = NULL; // list of stops that must be deleted - while (selected) { - GrDragger *dragger = (GrDragger*) selected->data; - for (GSList * drgble = dragger->draggables; drgble != NULL; drgble = drgble->next) { - GrDraggable *draggable = (GrDraggable*) drgble->data; + while (!selected.empty()) { + GrDragger *dragger = *(selected.begin()); + for(std::vector::const_iterator drgble = dragger->draggables.begin(); drgble != dragger->draggables.end(); ++drgble) { + GrDraggable *draggable = *drgble; SPGradient *gradient = getGradient(draggable->item, draggable->fill_or_stroke); SPGradient *vector = sp_gradient_get_forked_vector_if_necessary (gradient, false); @@ -2538,7 +2521,7 @@ void GrDrag::deleteSelected(bool just_one) break; } } - selected = g_list_remove(selected, dragger); + selected.erase(dragger); if ( just_one ) break; // iterate once if just_one is set. } while (midstoplist) { diff --git a/src/gradient-drag.h b/src/gradient-drag.h index da264b4bb..72ec62572 100644 --- a/src/gradient-drag.h +++ b/src/gradient-drag.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -86,7 +87,7 @@ struct GrDragger { // position of the knot before it began to drag; updated when released Geom::Point point_original; - GSList *draggables; + std::vector draggables; void addDraggable(GrDraggable *draggable); @@ -123,6 +124,7 @@ private: sigc::connection _ungrabbed_connection; }; +class SPCtrlLine; /** This is the root class of the gradient dragging machinery. It holds lists of GrDraggers and of lines (simple canvas items). It also remembers one of the draggers as selected. @@ -133,20 +135,21 @@ public: // FIXME: make more of this private! GrDrag(SPDesktop *desktop); virtual ~GrDrag(); - bool isNonEmpty() {return (draggers != NULL);} - bool hasSelection() {return (selected != NULL);} - guint numSelected() {return (selected? g_list_length(selected) : 0);} - guint numDraggers() {return (draggers? g_list_length(draggers) : 0);} + bool isNonEmpty() {return !draggers.empty();} + bool hasSelection() {return !selected.empty();} + guint numSelected() {return selected.size();} + guint numDraggers() {return draggers.size();} guint singleSelectedDraggerNumDraggables() { - return (selected? g_slist_length(( static_cast(selected->data))->draggables) : 0); + return (selected.empty()? 0 : (*(selected.begin()))->draggables.size() ); } guint singleSelectedDraggerSingleDraggableType() { - return (selected? (static_cast((static_cast(selected->data))->draggables->data))->point_type : 0);} + return (selected.empty() ? 0 : ((*(selected.begin()))->draggables[0]->point_type)); + } // especially the selection must be private, fix gradient-context to remove direct access to it - GList *selected; // list of GrDragger* + std::set selected; // list of GrDragger* void setSelected(GrDragger *dragger, bool add_to_selection = false, bool override = true); void setDeselected(GrDragger *dragger); void deselectAll(); @@ -178,8 +181,8 @@ public: // FIXME: make more of this private! std::vector hor_levels; std::vector vert_levels; - GList *draggers; - GSList *lines; + std::vector draggers; + std::vector lines; void updateDraggers(); void updateLines(); diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp index bcb0b12b7..9d8101cc4 100644 --- a/src/ui/tools/gradient-tool.cpp +++ b/src/ui/tools/gradient-tool.cpp @@ -225,13 +225,13 @@ sp_gradient_context_get_stop_intervals (GrDrag *drag, GSList **these_stops, GSLi std::vector coords; // for all selected draggers - for (GList *i = drag->selected; i != NULL; i = i->next) { - GrDragger *dragger = (GrDragger *) i->data; + for (std::set::const_iterator i = drag->selected.begin(); i != drag->selected.end() ; ++i ) { + GrDragger *dragger = *i; // remember the coord of the dragger to reselect it later coords.push_back(dragger->point); // for all draggables of dragger - for (GSList const* j = dragger->draggables; j != NULL; j = j->next) { - GrDraggable *d = (GrDraggable *) j->data; + for (std::vector::const_iterator j = dragger->draggables.begin(); j != dragger->draggables.end(); ++j) { + GrDraggable *d = *j; // find the gradient SPGradient *gradient = getGradient(d->item, d->fill_or_stroke); @@ -315,9 +315,9 @@ sp_gradient_context_add_stops_between_selected_stops (GradientTool *rc) if (g_slist_length(these_stops) == 0 && drag->numSelected() == 1) { // if a single stop is selected, add between that stop and the next one - GrDragger *dragger = (GrDragger *) drag->selected->data; - for (GSList const* j = dragger->draggables; j != NULL; j = j->next) { - GrDraggable *d = (GrDraggable *) j->data; + GrDragger *dragger = *(drag->selected.begin()); + for (std::vector::const_iterator j = dragger->draggables.begin(); j != dragger->draggables.end(); ++j) { + GrDraggable *d = *j; if (d->point_type == POINT_RG_FOCUS) { /* * There are 2 draggables at the center (start) of a radial gradient @@ -482,9 +482,9 @@ bool GradientTool::root_handler(GdkEvent* event) { bool over_line = false; SPCtrlLine *line = NULL; - if (drag->lines) { - for (GSList *l = drag->lines; (l != NULL) && (!over_line); l = l->next) { - line = (SPCtrlLine*) l->data; + if (!drag->lines.empty()) { + for (std::vector::const_iterator l = drag->lines.begin(); l != drag->lines.end() && (!over_line); ++l) { + line = *l; over_line |= sp_gradient_context_is_over_line (this, (SPItem*) line, Geom::Point(event->motion.x, event->motion.y)); } } @@ -588,9 +588,9 @@ bool GradientTool::root_handler(GdkEvent* event) { bool over_line = false; - if (drag->lines) { - for (GSList *l = drag->lines; l != NULL; l = l->next) { - over_line |= sp_gradient_context_is_over_line (this, (SPItem*) l->data, Geom::Point(event->motion.x, event->motion.y)); + if (!drag->lines.empty()) { + for (std::vector::const_iterator l = drag->lines.begin(); l != drag->lines.end(); ++l) { + over_line |= sp_gradient_context_is_over_line (this, (SPItem*) (*l), Geom::Point(event->motion.x, event->motion.y)); } } @@ -613,12 +613,10 @@ bool GradientTool::root_handler(GdkEvent* event) { bool over_line = false; SPCtrlLine *line = NULL; - if (drag->lines) { - for (GSList *l = drag->lines; (l != NULL) && (!over_line); l = l->next) { - line = (SPCtrlLine*) l->data; + if (!drag->lines.empty()) { + for (std::vector::const_iterator l = drag->lines.begin(); l != drag->lines.end() && (!over_line); ++l) { + line = *l; over_line = sp_gradient_context_is_over_line (this, (SPItem*) line, Geom::Point(event->motion.x, event->motion.y)); - if (over_line) - break; } } @@ -663,7 +661,7 @@ bool GradientTool::root_handler(GdkEvent* event) { } } else { // click in an empty space; do the same as Esc - if (drag->selected) { + if (!drag->selected.empty()) { drag->deselectAll(); } else { selection->clear(); @@ -719,7 +717,7 @@ bool GradientTool::root_handler(GdkEvent* event) { break; case GDK_KEY_Escape: - if (drag->selected) { + if (!drag->selected.empty()) { drag->deselectAll(); } else { Inkscape::SelectionHelper::selectNone(desktop); diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index 794296329..e000307ee 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -332,11 +332,11 @@ sp_mesh_context_corner_operation (MeshTool *rc, MeshCornerOperation operation ) // Get list of selected draggers for each mesh. // For all selected draggers - for (GList *i = drag->selected; i != NULL; i = i->next) { - GrDragger *dragger = (GrDragger *) i->data; + for (std::set::const_iterator i = drag->selected.begin(); i != drag->selected.end(); ++i) { + GrDragger *dragger = *i; // For all draggables of dragger - for (GSList const* j = dragger->draggables; j != NULL; j = j->next) { - GrDraggable *d = (GrDraggable *) j->data; + for (std::vector::const_iterator j = dragger->draggables.begin(); j != dragger->draggables.end() ; ++j) { + GrDraggable *d = *j; // Only mesh corners if( d->point_type != POINT_MG_CORNER ) continue; @@ -457,9 +457,9 @@ bool MeshTool::root_handler(GdkEvent* event) { bool over_line = false; SPCtrlCurve *line = NULL; - if (drag->lines) { - for (GSList *l = drag->lines; (l != NULL) && (!over_line); l = l->next) { - line = (SPCtrlCurve*) l->data; + if (! drag->lines.empty()) { + for (std::vector::const_iterator l = drag->lines.begin(); l != drag->lines.end() && (!over_line); l++) { + line = (SPCtrlCurve*) (*l); over_line |= sp_mesh_context_is_over_line (this, (SPItem*) line, Geom::Point(event->motion.x, event->motion.y)); } } @@ -593,9 +593,9 @@ bool MeshTool::root_handler(GdkEvent* event) { // Change cursor shape if over line bool over_line = false; - if (drag->lines) { - for (GSList *l = drag->lines; l != NULL; l = l->next) { - over_line |= sp_mesh_context_is_over_line (this, (SPItem*) l->data, Geom::Point(event->motion.x, event->motion.y)); + if (!drag->lines.empty()) { + for (std::vector::const_iterator l = drag->lines.begin(); l != drag->lines.end() ; l++) { + over_line |= sp_mesh_context_is_over_line (this, (SPItem*)(*l), Geom::Point(event->motion.x, event->motion.y)); } } @@ -624,9 +624,9 @@ bool MeshTool::root_handler(GdkEvent* event) { bool over_line = false; SPCtrlLine *line = NULL; - if (drag->lines) { - for (GSList *l = drag->lines; (l != NULL) && (!over_line); l = l->next) { - line = (SPCtrlLine*) l->data; + if (!drag->lines.empty()) { + for (std::vector::const_iterator l = drag->lines.begin(); l != drag->lines.end() && (!over_line); l++) { + line = (SPCtrlLine*)(*l); over_line = sp_mesh_context_is_over_line (this, (SPItem*) line, Geom::Point(event->motion.x, event->motion.y)); if (over_line) { @@ -678,7 +678,7 @@ bool MeshTool::root_handler(GdkEvent* event) { } } else { // click in an empty space; do the same as Esc - if (drag->selected) { + if (!drag->selected.empty()) { drag->deselectAll(); } else { selection->clear(); @@ -724,7 +724,7 @@ bool MeshTool::root_handler(GdkEvent* event) { break; case GDK_KEY_Escape: - if (drag->selected) { + if (!drag->selected.empty()) { drag->deselectAll(); } else { selection->clear(); @@ -841,7 +841,7 @@ bool MeshTool::root_handler(GdkEvent* event) { case GDK_KEY_Delete: case GDK_KEY_KP_Delete: case GDK_KEY_BackSpace: - if ( drag->selected ) { + if ( !drag->selected.empty() ) { std::cout << "Deleting mesh stops not implemented yet" << std::endl; ret = TRUE; } diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index bf7b61b61..abac2c091 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -924,7 +924,7 @@ void ToolBase::enableGrDrag(bool enable) { */ bool ToolBase::deleteSelectedDrag(bool just_one) { - if (_grdrag && _grdrag->selected) { + if (_grdrag && !_grdrag->selected.empty()) { _grdrag->deleteSelected(just_one); return TRUE; } diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp index b24615126..e8ad09cd4 100644 --- a/src/widgets/gradient-toolbar.cpp +++ b/src/widgets/gradient-toolbar.cpp @@ -106,10 +106,10 @@ void gr_apply_gradient(Inkscape::Selection *selection, GrDrag *drag, SPGradient // GRADIENTFIXME: make this work for multiple selected draggers. // First try selected dragger - if (drag && drag->selected) { - GrDragger *dragger = static_cast(drag->selected->data); - for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger - GrDraggable *draggable = static_cast(i->data); + if (drag && !drag->selected.empty()) { + GrDragger *dragger = *(drag->selected.begin()); + for(std::vector::const_iterator i = dragger->draggables.begin(); i != dragger->draggables.end(); ++i) { //for all draggables of dragger + GrDraggable *draggable = *i; gr_apply_gradient_to_item(draggable->item, gr, initialType, initialMode, draggable->fill_or_stroke); } return; @@ -255,11 +255,11 @@ void gr_read_selection( Inkscape::Selection *selection, SPGradientSpread &spr_selected, bool &spr_multi ) { - if (drag && drag->selected) { + if (drag && !drag->selected.empty()) { // GRADIENTFIXME: make this work for more than one selected dragger? - GrDragger *dragger = static_cast(drag->selected->data); - for (GSList const* i = dragger->draggables; i; i = i->next) { // for all draggables of dragger - GrDraggable *draggable = static_cast(i->data); + GrDragger *dragger = *(drag->selected.begin()); + for(std::vector::const_iterator i = dragger->draggables.begin(); i != dragger->draggables.end(); ++i) { //for all draggables of dragger + GrDraggable *draggable = *i; SPGradient *gradient = sp_item_gradient_get_vector(draggable->item, draggable->fill_or_stroke); SPGradientSpread spread = sp_item_gradient_get_spread(draggable->item, draggable->fill_or_stroke); @@ -394,10 +394,10 @@ static void gr_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointe } InkAction *add = (InkAction *) g_object_get_data(G_OBJECT(widget), "gradient_stops_add_action"); - gtk_action_set_sensitive(GTK_ACTION(add), (gr_selected && !gr_multi && drag && drag->selected)); + gtk_action_set_sensitive(GTK_ACTION(add), (gr_selected && !gr_multi && drag && !drag->selected.empty())); InkAction *del = (InkAction *) g_object_get_data(G_OBJECT(widget), "gradient_stops_delete_action"); - gtk_action_set_sensitive(GTK_ACTION(del), (gr_selected && !gr_multi && drag && drag->selected)); + gtk_action_set_sensitive(GTK_ACTION(del), (gr_selected && !gr_multi && drag && !drag->selected.empty())); InkAction *reverse = (InkAction *) g_object_get_data(G_OBJECT(widget), "gradient_stops_reverse_action"); gtk_action_set_sensitive(GTK_ACTION(reverse), (gr_selected!= NULL)); @@ -649,7 +649,7 @@ static void select_stop_by_drag(GtkWidget *combo_box, SPGradient *gradient, Tool GrDrag *drag = ev->get_drag(); - if (!drag || !drag->selected) { + if (!drag || drag->selected.empty()) { blocked = TRUE; gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box) , 0); gr_stop_set_offset(GTK_COMBO_BOX(combo_box), data); @@ -660,11 +660,10 @@ static void select_stop_by_drag(GtkWidget *combo_box, SPGradient *gradient, Tool gint n = 0; // for all selected draggers - for (GList *i = drag->selected; i != NULL; i = i->next) { - GrDragger *dragger = static_cast(i->data); - // for all draggables of dragger - for (GSList const* j = dragger->draggables; j != NULL; j = j->next) { - GrDraggable *draggable = static_cast(j->data); + for(std::set::const_iterator i = drag->selected.begin(); i != drag->selected.end(); ++i) { //for all draggables of dragger + GrDragger *dragger = *i; + for(std::vector::const_iterator j = dragger->draggables.begin(); j != dragger->draggables.end(); ++j) { //for all draggables of dragger + GrDraggable *draggable = *j; if (draggable->point_type != POINT_RG_FOCUS) { n++; -- cgit v1.2.3 From 05e90b229e833b64bee150810953cf1328621b99 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 6 Dec 2015 15:01:35 +0100 Subject: cppification: GSList replaced by vectors (vanishing points) (bzr r14504.1.3) --- src/vanishing-point.cpp | 66 ++++++++++++++++++++++--------------------------- src/vanishing-point.h | 6 ++--- 2 files changed, 32 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp index 553e3a31d..295854787 100644 --- a/src/vanishing-point.cpp +++ b/src/vanishing-point.cpp @@ -137,8 +137,8 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g if (!(state & GDK_SHIFT_MASK)) { // without Shift; see if we need to snap to another dragger - for (GList *di = dragger->parent->draggers; di != NULL; di = di->next) { - VPDragger *d_new = (VPDragger *) di->data; + for (std::vector::const_iterator di = dragger->parent->draggers.begin(); di != dragger->parent->draggers.end(); ++di) { + VPDragger *d_new = *di; if ((d_new != dragger) && (Geom::L2 (d_new->point - p) < snap_dist)) { if (have_VPs_of_same_perspective (dragger, d_new)) { // this would result in degenerate boxes, which we disallow for the time being @@ -155,7 +155,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g d_new->vps.merge(dragger->vps); // ... delete old dragger ... - drag->draggers = g_list_remove (drag->draggers, dragger); + drag->draggers.erase(std::remove(drag->draggers.begin(), drag->draggers.end(), dragger),drag->draggers.end()); delete dragger; dragger = NULL; @@ -494,8 +494,6 @@ VPDrag::VPDrag (SPDocument *document) this->document = document; this->selection = SP_ACTIVE_DESKTOP->getSelection(); - this->draggers = NULL; - this->lines = NULL; this->show_lines = true; this->front_or_rear_lines = 0x1; @@ -522,17 +520,15 @@ VPDrag::~VPDrag() this->sel_changed_connection.disconnect(); this->sel_modified_connection.disconnect(); - for (GList *l = this->draggers; l != NULL; l = l->next) { - delete ((VPDragger *) l->data); + for (std::vector::const_iterator i = this->draggers.begin(); i != this->draggers.end(); ++i) { + delete (*i); } - g_list_free (this->draggers); - this->draggers = NULL; + this->draggers.clear(); - for (GSList const *i = this->lines; i != NULL; i = i->next) { - sp_canvas_item_destroy(SP_CANVAS_ITEM(i->data)); + for (std::vector::const_iterator i = this->lines.begin(); i != this->lines.end(); ++i) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(*i)); } - g_slist_free (this->lines); - this->lines = NULL; + this->lines.clear(); } /** @@ -541,8 +537,8 @@ VPDrag::~VPDrag() VPDragger * VPDrag::getDraggerFor (VanishingPoint const &vp) { - for (GList const* i = this->draggers; i != NULL; i = i->next) { - VPDragger *dragger = (VPDragger *) i->data; + for (std::vector::const_iterator i = this->draggers.begin(); i != this->draggers.end(); ++i) { + VPDragger *dragger = *i; for (std::list::iterator j = dragger->vps.begin(); j != dragger->vps.end(); ++j) { // TODO: Should we compare the pointers or the VPs themselves!?!?!?! if (*j == vp) { @@ -557,8 +553,8 @@ void VPDrag::printDraggers () { g_print ("=== VPDrag info: =================================\n"); - for (GList const* i = this->draggers; i != NULL; i = i->next) { - ((VPDragger *) i->data)->printVPs(); + for (std::vector::const_iterator i = this->draggers.begin(); i != this->draggers.end(); ++i) { + (*i)->printVPs(); g_print ("========\n"); } g_print ("=================================================\n"); @@ -573,11 +569,10 @@ VPDrag::updateDraggers () if (this->dragging) return; // delete old draggers - for (GList const* i = this->draggers; i != NULL; i = i->next) { - delete ((VPDragger *) i->data); + for (std::vector::const_iterator i = this->draggers.begin(); i != this->draggers.end(); ++i) { + delete (*i); } - g_list_free (this->draggers); - this->draggers = NULL; + this->draggers.clear(); g_return_if_fail (this->selection != NULL); @@ -603,11 +598,10 @@ void VPDrag::updateLines () { // delete old lines - for (GSList const *i = this->lines; i != NULL; i = i->next) { - sp_canvas_item_destroy(SP_CANVAS_ITEM(i->data)); + for (std::vector::const_iterator i = this->lines.begin(); i != this->lines.end(); ++i) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(*i)); } - g_slist_free (this->lines); - this->lines = NULL; + this->lines.clear(); // do nothing if perspective lines are currently disabled if (this->show_lines == 0) return; @@ -651,8 +645,8 @@ VPDrag::updateBoxHandles () void VPDrag::updateBoxReprs () { - for (GList *i = this->draggers; i != NULL; i = i->next) { - VPDragger *dragger = (VPDragger *) i->data; + for (std::vector::const_iterator i = this->draggers.begin(); i != this->draggers.end(); ++i) { + VPDragger *dragger = *i; for (std::list::iterator i = dragger->vps.begin(); i != dragger->vps.end(); ++i) { (*i).updateBoxReprs(); } @@ -662,8 +656,8 @@ VPDrag::updateBoxReprs () void VPDrag::updateBoxDisplays () { - for (GList *i = this->draggers; i != NULL; i = i->next) { - VPDragger *dragger = (VPDragger *) i->data; + for (std::vector::const_iterator i = this->draggers.begin(); i != this->draggers.end(); ++i) { + VPDragger *dragger = *i; for (std::list::iterator i = dragger->vps.begin(); i != dragger->vps.end(); ++i) { (*i).updateBoxDisplays(); } @@ -758,8 +752,8 @@ VPDrag::addDragger (VanishingPoint &vp) } Geom::Point p = vp.get_pos(); - for (GList *i = this->draggers; i != NULL; i = i->next) { - VPDragger *dragger = (VPDragger *) i->data; + for (std::vector::const_iterator i = this->draggers.begin(); i != this->draggers.end(); ++i) { + VPDragger *dragger = *i; if (Geom::L2 (dragger->point - p) < MERGE_DIST) { // distance is small, merge this draggable into dragger, no need to create new dragger dragger->addVP (vp); @@ -769,16 +763,16 @@ VPDrag::addDragger (VanishingPoint &vp) VPDragger *new_dragger = new VPDragger(this, p, vp); // fixme: draggers should be added AFTER the last one: this way tabbing through them will be from begin to end. - this->draggers = g_list_append (this->draggers, new_dragger); + this->draggers.push_back(new_dragger); } void VPDrag::swap_perspectives_of_VPs(Persp3D *persp2, Persp3D *persp1) { // iterate over all VP in all draggers and replace persp2 with persp1 - for (GList *i = this->draggers; i != NULL; i = i->next) { - for (std::list::iterator j = ((VPDragger *) (i->data))->vps.begin(); - j != ((VPDragger *) (i->data))->vps.end(); ++j) { + for (std::vector::const_iterator i = this->draggers.begin(); i != this->draggers.end(); ++i) { + for (std::list::iterator j = (*i)->vps.begin(); + j != (*i)->vps.end(); ++j) { if ((*j).get_perspective() == persp2) { (*j).set_perspective(persp1); } @@ -790,7 +784,7 @@ void VPDrag::addLine(Geom::Point const &p1, Geom::Point const &p2, Inkscape::Ctr { SPCtrlLine *line = ControlManager::getManager().createControlLine(SP_ACTIVE_DESKTOP->getControls(), p1, p2, type); sp_canvas_item_show(line); - this->lines = g_slist_append(this->lines, line); + this->lines.push_back(line); } } // namespace Box3D diff --git a/src/vanishing-point.h b/src/vanishing-point.h index 7242a94ee..e967096e5 100644 --- a/src/vanishing-point.h +++ b/src/vanishing-point.h @@ -23,8 +23,6 @@ #include "ui/control-manager.h" // TODO break enums out separately class SPBox3D; -typedef struct _GList GList; -typedef struct _GSList GSList; namespace Box3D { @@ -173,8 +171,8 @@ public: bool dragging; SPDocument *document; - GList *draggers; - GSList *lines; + std::vector draggers; + std::vector lines; void printDraggers(); // convenience for debugging /* -- cgit v1.2.3 From aa7d5349b46a07f5e667817aa904f1b19c8db621 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 6 Dec 2015 16:34:47 +0100 Subject: cppification: GSList replaced by vectors (select tool cycling to 'select under') (bzr r14504.1.4) --- src/ui/tools/select-tool.cpp | 94 +++++++++++++++++--------------------------- src/ui/tools/select-tool.h | 8 ++-- 2 files changed, 41 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp index f06b03d91..2b85216d2 100644 --- a/src/ui/tools/select-tool.cpp +++ b/src/ui/tools/select-tool.cpp @@ -89,10 +89,6 @@ SelectTool::SelectTool() , button_press_shift(false) , button_press_ctrl(false) , button_press_alt(false) - , cycling_items(NULL) - , cycling_items_cmp(NULL) - , cycling_items_selected_before(NULL) - , cycling_cur_item(NULL) , cycling_wrap(true) , item(NULL) , grabbed(NULL) @@ -390,16 +386,16 @@ bool SelectTool::item_handler(SPItem* item, GdkEvent* event) { } void SelectTool::sp_select_context_cycle_through_items(Inkscape::Selection *selection, GdkEventScroll *scroll_event, bool shift_pressed) { - if (!this->cycling_cur_item) { + if (this->cycling_cur_item == this->cycling_items.end()) { return; } Inkscape::DrawingItem *arenaitem; - SPItem *item = dynamic_cast(static_cast(cycling_cur_item->data)); + SPItem *item = *cycling_cur_item; g_assert(item != NULL); // Deactivate current item - if (!g_list_find(this->cycling_items_selected_before, item) && selection->includes(item)) { + if (std::find(cycling_items_selected_before.begin(), cycling_items_selected_before.end(), item) == cycling_items_selected_before.end() && selection->includes(item)) { selection->remove(item); } @@ -407,20 +403,20 @@ void SelectTool::sp_select_context_cycle_through_items(Inkscape::Selection *sele arenaitem->setOpacity(0.3); // Find next item and activate it - GList *next; + std::vector::iterator next = this->cycling_cur_item; if (scroll_event->direction == GDK_SCROLL_UP) { - next = this->cycling_cur_item->next; - if (next == NULL && this->cycling_wrap) - next = this->cycling_items; + next++; + if (next == this->cycling_items.end() && this->cycling_wrap) + next = this->cycling_items.begin(); } else { - next = this->cycling_cur_item->prev; - if (next == NULL && this->cycling_wrap) - next = g_list_last(this->cycling_items); + if(next == this->cycling_items.begin()) + next = this->cycling_items.end(); + next--; } - if (next) { + if (next!=this->cycling_items.end()) { this->cycling_cur_item = next; - item = dynamic_cast(static_cast(this->cycling_cur_item->data)); + item = *next; g_assert(item != NULL); } @@ -435,8 +431,8 @@ void SelectTool::sp_select_context_cycle_through_items(Inkscape::Selection *sele } void SelectTool::sp_select_context_reset_opacities() { - for (GList *l = this->cycling_items; l != NULL; l = g_list_next(l)) { - SPItem *item = dynamic_cast(static_cast(l->data)); + for (std::vector::const_iterator l = this->cycling_items.begin(); l != this->cycling_items.end(); ++l ) { + SPItem *item = *l; if (item) { Inkscape::DrawingItem *arenaitem = item->get_arenaitem(desktop->dkey); arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(item->style->opacity.value)); @@ -445,14 +441,10 @@ void SelectTool::sp_select_context_reset_opacities() { } } - g_list_free(this->cycling_items); - g_list_free(this->cycling_items_selected_before); - g_list_free(this->cycling_items_cmp); - - this->cycling_items = NULL; - this->cycling_items_selected_before = NULL; - this->cycling_cur_item = NULL; - this->cycling_items_cmp = NULL; + this->cycling_items.clear(); + this->cycling_items_selected_before.clear(); + this->cycling_cur_item = this->cycling_items.end(); + this->cycling_items_cmp.clear(); } bool SelectTool::root_handler(GdkEvent* event) { @@ -819,70 +811,57 @@ bool SelectTool::root_handler(GdkEvent* event) { SPItem *item = desktop->getItemAtPoint(p, true, NULL); // Save pointer to current cycle-item so that we can find it again later, in the freshly built list - SPItem *tmp_cur_item = this->cycling_cur_item ? dynamic_cast(static_cast(this->cycling_cur_item->data)) : NULL; - g_list_free(this->cycling_items); - this->cycling_items = NULL; - this->cycling_cur_item = NULL; - + SPItem *tmp_cur_item = this->cycling_cur_item!=this->cycling_items.end() ? (*(this->cycling_cur_item)) : NULL; + this->cycling_items.clear(); + this->cycling_cur_item = this->cycling_items.end(); while(item != NULL) { - this->cycling_items = g_list_append(this->cycling_items, item); + this->cycling_items.push_back(item); item = desktop->getItemAtPoint(p, true, item); } /* Compare current item list with item list during previous scroll ... */ - GList *l1, *l2; - bool item_lists_differ = false; - - // Note that we can do an 'or' comparison in the loop because it is safe to call g_list_next with a NULL pointer. - for (l1 = this->cycling_items, l2 = this->cycling_items_cmp; l1 != NULL || l2 != NULL; l1 = g_list_next(l1), l2 = g_list_next(l2)) { - if ((l1 !=NULL && l2 == NULL) || (l1 == NULL && l2 != NULL) || (l1->data != l2->data)) { - item_lists_differ = true; - break; - } - } + bool item_lists_differ = this->cycling_items != this->cycling_items_cmp; /* If list of items under mouse pointer hasn't changed ... */ if (!item_lists_differ) { // ... find current item in the freshly built list and continue cycling ... // TODO: This wouldn't be necessary if cycling_cur_item pointed to an element of cycling_items_cmp instead - this->cycling_cur_item = g_list_find(this->cycling_items, tmp_cur_item); - g_assert(this->cycling_cur_item != NULL || this->cycling_items == NULL); + this->cycling_cur_item = std::find(this->cycling_items.begin(), this->cycling_items.end(), tmp_cur_item); + g_assert(this->cycling_cur_item != this->cycling_items.end() || this->cycling_items.empty()); } else { // ... otherwise reset opacities for outdated items ... Inkscape::DrawingItem *arenaitem; - for(GList *l = this->cycling_items_cmp; l != NULL; l = l->next) { - SPItem *item = dynamic_cast(static_cast(l->data)); + for (std::vector::const_iterator l = this->cycling_items_cmp.begin(); l != this->cycling_items_cmp.end(); ++l) { + SPItem *item = *l; if (item) { arenaitem = item->get_arenaitem(desktop->dkey); arenaitem->setOpacity(1.0); //if (!shift_pressed && !g_list_find(this->cycling_items_selected_before, item) && selection->includes(item)) - if (!g_list_find(this->cycling_items_selected_before, item) && selection->includes(item)) { + if (std::find(this->cycling_items_selected_before.begin(),this->cycling_items_selected_before.end(), item)==this->cycling_items_selected_before.end() && selection->includes(item)) { selection->remove(item); } } } // ... clear the lists ... - g_list_free(this->cycling_items_cmp); - g_list_free(this->cycling_items_selected_before); - this->cycling_items_cmp = NULL; - this->cycling_items_selected_before = NULL; - this->cycling_cur_item = NULL; + this->cycling_items_cmp.clear(); + this->cycling_items_selected_before.clear(); + this->cycling_cur_item = this->cycling_items.end(); // ... and rebuild them with the new items. - this->cycling_items_cmp = g_list_copy(this->cycling_items); + this->cycling_items_cmp = (this->cycling_items); - for(GList *l = this->cycling_items; l != NULL; l = l->next) { - SPItem *item = dynamic_cast(static_cast(l->data)); + for(std::vector::const_iterator l = this->cycling_items.begin(); l != this->cycling_items.end(); ++l) { + SPItem *item =*l; if (item) { arenaitem = item->get_arenaitem(desktop->dkey); arenaitem->setOpacity(0.3); if (selection->includes(item)) { // already selected items are stored separately, too - this->cycling_items_selected_before = g_list_append(this->cycling_items_selected_before, item); + this->cycling_items_selected_before.push_back(item); } } else { g_assert_not_reached(); @@ -890,7 +869,8 @@ bool SelectTool::root_handler(GdkEvent* event) { } // set the current item to the bottommost one so that the cycling step below re-starts at the top - this->cycling_cur_item = g_list_last(this->cycling_items); + this->cycling_cur_item = this->cycling_items.end(); + this->cycling_cur_item--; } this->cycling_wrap = prefs->getBool("/options/selection/cycleWrap", true); diff --git a/src/ui/tools/select-tool.h b/src/ui/tools/select-tool.h index 5af99a56a..af183b1ca 100644 --- a/src/ui/tools/select-tool.h +++ b/src/ui/tools/select-tool.h @@ -40,10 +40,10 @@ public: bool button_press_ctrl; bool button_press_alt; - GList *cycling_items; - GList *cycling_items_cmp; - GList *cycling_items_selected_before; - GList *cycling_cur_item; + std::vector cycling_items; + std::vector cycling_items_cmp; + std::vector cycling_items_selected_before; + std::vector::iterator cycling_cur_item; bool cycling_wrap; SPItem *item; -- cgit v1.2.3 From 266cd1e5c43e6a46cd37f7db5138270b80d0944e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 6 Dec 2015 22:39:31 +0100 Subject: Fixes UX pointed in suv review (bzr r14500.1.9) --- src/desktop-events.cpp | 3 ++ src/desktop.cpp | 5 +++ src/desktop.h | 2 + src/menus-skeleton.h | 1 + src/sp-namedview.cpp | 3 +- src/sp-namedview.h | 2 +- src/ui/interface.cpp | 3 ++ src/ui/view/edit-widget-interface.h | 3 ++ src/verbs.cpp | 13 +++--- src/verbs.h | 2 +- src/widgets/desktop-widget.cpp | 81 ++++++++++++++++++++----------------- src/widgets/desktop-widget.h | 6 ++- 12 files changed, 75 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp index 6968a19f8..99bc4f7ae 100644 --- a/src/desktop-events.cpp +++ b/src/desktop-events.cpp @@ -525,6 +525,9 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) if ((event->crossing.state & GDK_SHIFT_MASK) && (drag_type != SP_DRAG_MOVE_ORIGIN)) { GdkCursor *guide_cursor; guide_cursor = gdk_cursor_new (GDK_EXCHANGE); + if(guide->getLocked()){ + guide_cursor = sp_cursor_new_from_xpm(cursor_select_xpm , 1, 1); + } gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), guide_cursor); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(guide_cursor); diff --git a/src/desktop.cpp b/src/desktop.cpp index 7b20bcb9f..ae92c058a 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -1467,6 +1467,11 @@ void SPDesktop::toggleColorProfAdjust() _widget->toggleColorProfAdjust(); } +void SPDesktop::toggleGuidesLock() +{ + _widget->toggleGuidesLock(); +} + bool SPDesktop::colorProfAdjustEnabled() { return _widget->colorProfAdjustEnabled(); diff --git a/src/desktop.h b/src/desktop.h index 754e09766..f1444ba7b 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -383,6 +383,8 @@ public: void clearWaitingCursor(); bool isWaitingCursor() const { return waiting_cursor; }; + void toggleGuidesLock(); + void toggleColorProfAdjust(); bool colorProfAdjustEnabled(); diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index da78f99f1..11070d390 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -86,6 +86,7 @@ static char const menus_skeleton[] = " \n" " \n" " \n" +" \n" " \n" " \n" " \n" diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 9b34a3760..22effd93c 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -1002,7 +1002,7 @@ void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr) doc->setModifiedSinceSave(); } -void sp_namedview_toggle_guides_lock(SPDocument *doc, Inkscape::XML::Node *repr) +void sp_namedview_guides_toggle_lock(SPDocument *doc, Inkscape::XML::Node *repr) { unsigned int v; unsigned int set = sp_repr_get_boolean(repr, "inkscape:lockguides", &v); @@ -1016,7 +1016,6 @@ void sp_namedview_toggle_guides_lock(SPDocument *doc, Inkscape::XML::Node *repr) DocumentUndo::setUndoSensitive(doc, false); sp_repr_set_boolean(repr, "inkscape:lockguides", v); DocumentUndo::setUndoSensitive(doc, saved); - doc->setModifiedSinceSave(); } diff --git a/src/sp-namedview.h b/src/sp-namedview.h index a586ea71c..d95da1254 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -123,7 +123,7 @@ void sp_namedview_document_from_window(SPDesktop *desktop); void sp_namedview_update_layers_from_document (SPDesktop *desktop); void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr); -void sp_namedview_toggle_guides_lock(SPDocument *doc, Inkscape::XML::Node *repr); +void sp_namedview_guides_toggle_lock(SPDocument *doc, Inkscape::XML::Node *repr); void sp_namedview_show_grids(SPNamedView *namedview, bool show, bool dirty_document); Inkscape::CanvasGrid * sp_namedview_get_first_enabled_grid(SPNamedView *namedview); diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 0f719b40f..dc49283d5 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -577,6 +577,9 @@ static gboolean checkitem_update(GtkWidget *widget, GdkEventExpose * /*event*/, if (!strcmp(action->id, "ToggleGrid")) { ison = dt->gridsEnabled(); } + else if (!strcmp(action->id, "EditGuidesToggleLock")) { + ison = dt->namedview->lockguides; + } else if (!strcmp(action->id, "ToggleGuides")) { ison = dt->namedview->getGuides(); } diff --git a/src/ui/view/edit-widget-interface.h b/src/ui/view/edit-widget-interface.h index 55683871d..fcba0c6da 100644 --- a/src/ui/view/edit-widget-interface.h +++ b/src/ui/view/edit-widget-interface.h @@ -116,6 +116,9 @@ struct EditWidgetInterface /// Toggle CMS on/off and set preference value accordingly virtual void toggleColorProfAdjust() = 0; + /// Toggle lock guides on/off and set namedview value accordingly + virtual void toggleGuidesLock() = 0; + /// Is CMS on/off virtual bool colorProfAdjustEnabled() = 0; diff --git a/src/verbs.cpp b/src/verbs.cpp index afcc37bc4..ed4b1ceb0 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -952,6 +952,10 @@ void EditVerb::perform(SPAction *action, void *data) g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); + SPDocument *doc = dt->getDocument(); + + Inkscape::XML::Node *repr = dt->namedview->getRepr(); + switch (reinterpret_cast(data)) { case SP_VERB_EDIT_UNDO: sp_undo(dt, dt->getDocument()); @@ -1079,10 +1083,12 @@ void EditVerb::perform(SPAction *action, void *data) case SP_VERB_EDIT_DELETE_ALL_GUIDES: sp_guide_delete_all_guides(dt); break; + case SP_VERB_EDIT_GUIDES_TOGGLE_LOCK: + dt->toggleGuidesLock(); + break; case SP_VERB_EDIT_GUIDES_AROUND_PAGE: sp_guide_create_guides_around_page(dt); break; - case SP_VERB_EDIT_NEXT_PATHEFFECT_PARAMETER: sp_selection_next_patheffect_param(dt); break; @@ -1938,9 +1944,6 @@ void ZoomVerb::perform(SPAction *action, void *data) case SP_VERB_TOGGLE_GUIDES: sp_namedview_toggle_guides(doc, repr); break; - case SP_VERB_TOGGLE_GUIDES_LOCK: - sp_namedview_toggle_guides_lock(doc, repr); - break; case SP_VERB_TOGGLE_SNAPPING: dt->toggleSnapGlobal(); break; @@ -2543,6 +2546,7 @@ Verb *Verb::_base_verbs[] = { N_("Deselect any selected objects or nodes"), INKSCAPE_ICON("edit-select-none")), new EditVerb(SP_VERB_EDIT_DELETE_ALL_GUIDES, "EditRemoveAllGuides", N_("Delete All Guides"), N_("Delete all the guides in the document"), NULL), + new EditVerb(SP_VERB_EDIT_GUIDES_TOGGLE_LOCK, "EditGuidesToggleLock", N_("Lock All Guides"), N_("Toggle lock of all guides in the document"), NULL), new EditVerb(SP_VERB_EDIT_GUIDES_AROUND_PAGE, "EditGuidesAroundPage", N_("Create _Guides Around the Page"), N_("Create four guides aligned with the page borders"), NULL), new EditVerb(SP_VERB_EDIT_NEXT_PATHEFFECT_PARAMETER, "EditNextPathEffectParameter", N_("Next path effect parameter"), @@ -2831,7 +2835,6 @@ Verb *Verb::_base_verbs[] = { new ZoomVerb(SP_VERB_TOGGLE_SCROLLBARS, "ToggleScrollbars", N_("Scroll_bars"), N_("Show or hide the canvas scrollbars"), NULL), new ZoomVerb(SP_VERB_TOGGLE_GRID, "ToggleGrid", N_("Page _Grid"), N_("Show or hide the page grid"), INKSCAPE_ICON("show-grid")), new ZoomVerb(SP_VERB_TOGGLE_GUIDES, "ToggleGuides", N_("G_uides"), N_("Show or hide guides (drag from a ruler to create a guide)"), INKSCAPE_ICON("show-guides")), - new ZoomVerb(SP_VERB_TOGGLE_GUIDES_LOCK, "ToggleGuidesLook", N_("Gui_des Lock"), N_("Lock or unlock all guides"), INKSCAPE_ICON("object-locked")), new ZoomVerb(SP_VERB_TOGGLE_SNAPPING, "ToggleSnapGlobal", N_("Snap"), N_("Enable snapping"), INKSCAPE_ICON("snap")), new ZoomVerb(SP_VERB_TOGGLE_COMMANDS_TOOLBAR, "ToggleCommandsToolbar", N_("_Commands Bar"), N_("Show or hide the Commands bar (under the menu)"), NULL), new ZoomVerb(SP_VERB_TOGGLE_SNAP_TOOLBAR, "ToggleSnapToolbar", N_("Sn_ap Controls Bar"), N_("Show or hide the snapping controls"), NULL), diff --git a/src/verbs.h b/src/verbs.h index e1249684b..e16acb2d1 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -107,6 +107,7 @@ enum { SP_VERB_EDIT_SELECT_PREV, SP_VERB_EDIT_DESELECT, SP_VERB_EDIT_DELETE_ALL_GUIDES, + SP_VERB_EDIT_GUIDES_TOGGLE_LOCK, SP_VERB_EDIT_GUIDES_AROUND_PAGE, SP_VERB_EDIT_NEXT_PATHEFFECT_PARAMETER, /* Selection */ @@ -249,7 +250,6 @@ enum { SP_VERB_TOGGLE_SCROLLBARS, SP_VERB_TOGGLE_GRID, SP_VERB_TOGGLE_GUIDES, - SP_VERB_TOGGLE_GUIDES_LOCK, SP_VERB_TOGGLE_SNAPPING, SP_VERB_TOGGLE_COMMANDS_TOOLBAR, SP_VERB_TOGGLE_SNAP_TOOLBAR, diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 901b4d328..fd2847506 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -107,7 +107,7 @@ static void sp_desktop_widget_realize (GtkWidget *widget); static gint sp_desktop_widget_event (GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw); static void sp_dtw_color_profile_event(EgeColorProfTracker *widget, SPDesktopWidget *dtw); -static void update_guides_lock( GtkWidget *button, gpointer data ); +static void sp_update_guides_lock( GtkWidget *button, gpointer data ); #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) static void cms_adjust_toggled( GtkWidget *button, gpointer data ); #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -392,20 +392,20 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) ToolboxFactory::setOrientation( dtw->tool_toolbox, GTK_ORIENTATION_VERTICAL ); gtk_box_pack_start( GTK_BOX(dtw->hbox), dtw->tool_toolbox, FALSE, TRUE, 0 ); /* Lock all guides */ - gchar const* tip = ""; - Inkscape::Verb* verb = Inkscape::Verb::get( SP_VERB_TOGGLE_GUIDES_LOCK ); - if ( verb ) { - SPAction *act = verb->get_action( Inkscape::ActionContext( dtw->viewwidget.view ) ); - if ( act && act->tip ) { - tip = act->tip; - } - } +#if GTK_CHECK_VERSION(3,0,0) + dtw->lock_and_hruler = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); +#else + dtw->lock_and_hruler = gtk_hbox_new (FALSE, 0); +#endif + // Lock guides button dtw->guides_lock = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION, SP_BUTTON_TYPE_TOGGLE, NULL, INKSCAPE_ICON("object-locked"), - tip ); - g_signal_connect_after( G_OBJECT(dtw->guides_lock), "clicked", G_CALLBACK(update_guides_lock), dtw ); + _("Toggle lock of all guides in the document")); + + gtk_box_pack_start (GTK_BOX (dtw->lock_and_hruler), dtw->guides_lock, FALSE, FALSE, 0); + g_signal_connect (G_OBJECT (dtw->guides_lock), "toggled", G_CALLBACK (sp_update_guides_lock), dtw); /* Horizontal ruler */ GtkWidget *eventbox = gtk_event_box_new (); @@ -414,11 +414,8 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) Inkscape::Util::Unit const *pt = unit_table.getUnit("pt"); sp_ruler_set_unit(SP_RULER(dtw->hruler), pt); gtk_widget_set_tooltip_text (dtw->hruler_box, gettext(pt->name_plural.c_str())); - /* Lock all guides */ - dtw->hruler_box = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start( GTK_BOX(dtw->hruler_box), dtw->guides_lock, FALSE, FALSE, 0 ); - gtk_box_pack_start( GTK_BOX(dtw->hruler_box), dtw->hruler, true, true, 1 ); - gtk_container_add (GTK_CONTAINER (eventbox), dtw->hruler_box); + gtk_container_add (GTK_CONTAINER (eventbox), dtw->hruler); + gtk_container_add (GTK_CONTAINER (dtw->lock_and_hruler), eventbox); g_signal_connect (G_OBJECT (eventbox), "button_press_event", G_CALLBACK (sp_dt_hruler_event), dtw); g_signal_connect (G_OBJECT (eventbox), "button_release_event", G_CALLBACK (sp_dt_hruler_event), dtw); g_signal_connect (G_OBJECT (eventbox), "motion_notify_event", G_CALLBACK (sp_dt_hruler_event), dtw); @@ -427,13 +424,13 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) GtkWidget *tbl = gtk_grid_new(); dtw->canvas_tbl = gtk_grid_new(); - gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), eventbox, 0, 0, 1, 1); + gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), dtw->lock_and_hruler, 0, 0, 1, 1); #else GtkWidget *tbl = gtk_table_new(2, 3, FALSE); dtw->canvas_tbl = gtk_table_new(3, 3, FALSE); gtk_table_attach(GTK_TABLE(dtw->canvas_tbl), - eventbox, + dtw->lock_and_hruler, 0, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0); @@ -512,8 +509,8 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) 0, 0); #endif - tip = ""; - verb = Inkscape::Verb::get( SP_VERB_VIEW_CMS_TOGGLE ); + gchar const* tip = ""; + Inkscape::Verb* verb = Inkscape::Verb::get( SP_VERB_VIEW_CMS_TOGGLE ); if ( verb ) { SPAction *act = verb->get_action( Inkscape::ActionContext( dtw->viewwidget.view ) ); if ( act && act->tip ) { @@ -1000,15 +997,7 @@ void SPDesktopWidget::updateNamedview() modified_connection = desktop->namedview->connectModified(sigc::mem_fun(*this, &SPDesktopWidget::namedviewModified)); namedviewModified(desktop->namedview, SP_OBJECT_MODIFIED_FLAG); - SPDocument *doc = desktop->getDocument(); - SPNamedView *nv = desktop->getNamedView(); - Inkscape::XML::Node *repr = nv->getRepr(); - bool locked = desktop->namedview->lockguides; - if ( locked ) { - sp_button_toggle_set_down( SP_BUTTON(guides_lock), TRUE ); - //to reverse the callback - sp_namedview_toggle_guides_lock(doc, repr); - } + updateTitle( desktop->doc()->getName() ); } @@ -1070,7 +1059,7 @@ void sp_dtw_color_profile_event(EgeColorProfTracker */*tracker*/, SPDesktopWidge } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) -void update_guides_lock( GtkWidget */*button*/, gpointer data ) +void sp_update_guides_lock( GtkWidget */*button*/, gpointer data ) { SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(data); @@ -1079,8 +1068,16 @@ void update_guides_lock( GtkWidget */*button*/, gpointer data ) SPDocument *doc = dtw->desktop->getDocument(); SPNamedView *nv = dtw->desktop->getNamedView(); Inkscape::XML::Node *repr = nv->getRepr(); - nv->lockguides = down; - sp_namedview_toggle_guides_lock(doc, repr); + + if ( down != nv->lockguides ) { + nv->lockguides = down; + sp_namedview_guides_toggle_lock(doc, repr); + if (down) { + dtw->setMessage (Inkscape::NORMAL_MESSAGE, _("Locked all guides")); + } else { + dtw->setMessage (Inkscape::NORMAL_MESSAGE, _("Unlocked all guides")); + } + } } #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -1596,10 +1593,10 @@ void SPDesktopWidget::layoutWidgets() } if (!prefs->getBool(pref_root + "rulers/state", true)) { - gtk_widget_hide (dtw->hruler); + gtk_widget_hide (dtw->lock_and_hruler); gtk_widget_hide (dtw->vruler); } else { - gtk_widget_show_all (dtw->hruler); + gtk_widget_show_all (dtw->lock_and_hruler); gtk_widget_show_all (dtw->vruler); } } @@ -1731,6 +1728,7 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) /* Once desktop is set, we can update rulers */ sp_desktop_widget_update_rulers (dtw); + sp_button_toggle_set_down( SP_BUTTON(dtw->guides_lock), namedview->lockguides ); sp_view_widget_set_view (SP_VIEW_WIDGET (dtw), dtw->desktop); @@ -2086,12 +2084,12 @@ void sp_desktop_widget_toggle_rulers (SPDesktopWidget *dtw) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (gtk_widget_get_visible (dtw->hruler)) { - gtk_widget_hide (dtw->hruler); + if (gtk_widget_get_visible (dtw->lock_and_hruler)) { + gtk_widget_hide (dtw->lock_and_hruler); gtk_widget_hide (dtw->vruler); prefs->setBool(dtw->desktop->is_fullscreen() ? "/fullscreen/rulers/state" : "/window/rulers/state", false); } else { - gtk_widget_show_all (dtw->hruler); + gtk_widget_show_all (dtw->lock_and_hruler); gtk_widget_show_all (dtw->vruler); prefs->setBool(dtw->desktop->is_fullscreen() ? "/fullscreen/rulers/state" : "/window/rulers/state", true); } @@ -2122,7 +2120,6 @@ bool sp_desktop_widget_color_prof_adj_enabled( SPDesktopWidget *dtw ) void sp_desktop_widget_toggle_color_prof_adj( SPDesktopWidget *dtw ) { - if ( gtk_widget_get_sensitive( dtw->cms_adjust ) ) { if ( SP_BUTTON_IS_DOWN(dtw->cms_adjust) ) { sp_button_toggle_set_down( SP_BUTTON(dtw->cms_adjust), FALSE ); @@ -2132,6 +2129,14 @@ void sp_desktop_widget_toggle_color_prof_adj( SPDesktopWidget *dtw ) } } +void sp_desktop_widget_toggle_guides_lock( SPDesktopWidget *dtw ) +{ + if ( SP_BUTTON_IS_DOWN(dtw->guides_lock) ) { + sp_button_toggle_set_down( SP_BUTTON(dtw->guides_lock), FALSE ); + } else { + sp_button_toggle_set_down( SP_BUTTON(dtw->guides_lock), TRUE ); + } +} /* Unused void sp_spw_toggle_menubar (SPDesktopWidget *dtw, bool is_fullscreen) diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h index ef3bd9a38..bb5834165 100644 --- a/src/widgets/desktop-widget.h +++ b/src/widgets/desktop-widget.h @@ -49,6 +49,7 @@ void sp_desktop_widget_toggle_rulers (SPDesktopWidget *dtw); void sp_desktop_widget_toggle_scrollbars (SPDesktopWidget *dtw); void sp_desktop_widget_update_scrollbars (SPDesktopWidget *dtw, double scale); void sp_desktop_widget_toggle_color_prof_adj( SPDesktopWidget *dtw ); +void sp_desktop_widget_toggle_guides_lock( SPDesktopWidget *dtw ); bool sp_desktop_widget_color_prof_adj_enabled( SPDesktopWidget *dtw ); void sp_dtw_desktop_activate (SPDesktopWidget *dtw); @@ -77,8 +78,6 @@ struct SPDesktopWidget { GtkWidget *hbox; - GtkWidget *hrulerbox; - GtkWidget *menubar, *statusbar; Inkscape::UI::Dialogs::SwatchesPanel *panels; @@ -90,6 +89,7 @@ struct SPDesktopWidget { GtkWidget *hruler_box, *vruler_box; // eventboxes for setting tooltips GtkWidget *guides_lock; + GtkWidget *lock_and_hruler; GtkWidget *sticky_zoom; GtkWidget *cms_adjust; GtkWidget *coord_status; @@ -184,6 +184,8 @@ struct SPDesktopWidget { { sp_desktop_widget_toggle_scrollbars (_dtw); } virtual void toggleColorProfAdjust() { sp_desktop_widget_toggle_color_prof_adj(_dtw); } + virtual void toggleGuidesLock() + { sp_desktop_widget_toggle_guides_lock(_dtw); } virtual bool colorProfAdjustEnabled() { return sp_desktop_widget_color_prof_adj_enabled(_dtw); } virtual void updateZoom() -- cgit v1.2.3 From a3bca843ba05effdf01143bf4413c5603504948c Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 7 Dec 2015 16:17:31 +0100 Subject: Set minimum line height to "strut" height per CSS. Prevent possible infinite loops with empty lines. (bzr r14507) --- src/libnrtype/Layout-TNG-Compute.cpp | 56 ++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 1e8fb0fb1..e862f0657 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -255,7 +255,8 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ UnbrokenSpanPosition const &start_span_pos, ScanlineMaker::ScanRun const &scan_run, std::vector *chunk_info, - FontMetrics *line_height) const; + FontMetrics *line_height, + FontMetrics const *strut_height) const; /** computes the width of a single UnbrokenSpan (pointed to by span->start.iter_span) and outputs its vital statistics into the other fields of \a span. @@ -1456,34 +1457,25 @@ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, std::vector *chunk_info, FontMetrics *line_box_height) { - TRACE((" begin _findChunksForLine: chunks: %lu\n", chunk_info->size())); - // init the initial line_box_height - if (start_span_pos->iter_span == para.unbroken_spans.end()) { - if (_flow._spans.empty()) { - // empty first para: create a font for the sole purpose of measuring it - InputStreamTextSource const *text_source = static_cast(_flow._input_stream.front()); - font_instance *font = text_source->styleGetFontInstance(); - if (font) { - double multiplier = _computeFontLineHeight(text_source->style); - line_box_height->set( font ); - *line_box_height *= text_source->style->font_size.computed; - font->Unref(); - line_box_height->computeEffective( multiplier ); - TRACE((" initial next line top_of_line_box: %f\n", _scanline_maker->yCoordinate() - line_box_height->ascent )); - _scanline_maker->setNewYCoordinate(_scanline_maker->yCoordinate() - line_box_height->ascent); - } - } - // else empty subsequent para: keep the old line height + TRACE((" begin _findChunksForLine: chunks: %lu, em size: %f\n", chunk_info->size(), line_box_height->emSize() )); + + // CSS 2.1 dictates that the minimum line height (i.e. the strut height) is found from the block element. This, + // however, is not what the browsers seem to be doing. Instead, find the height from the first text source. + InputStreamTextSource const *text_source = static_cast(_flow._input_stream.front()); + font_instance *font = text_source->styleGetFontInstance(); + if (font) { + double multiplier = _computeFontLineHeight(text_source->style); + line_box_height->set( font ); + *line_box_height *= text_source->style->font_size.computed; + font->Unref(); + line_box_height->computeEffective( multiplier ); } else { - if (_flow._input_wrap_shapes.empty()) { - // if we're not wrapping set the line_box_height big and negative so we can use negative line height - line_box_height->ascent = -1.0e10; - line_box_height->descent = -1.0e10; - } - else - line_box_height->setZero(); + std::cerr << "Layout::Calculator::_findChunksForLine: Font not found." << std::endl; } - TRACE((" initial line_box_height: %f\n", line_box_height->emSize() )); + TRACE((" initial line_box_height (em size): %f\n", line_box_height->emSize() )); + + // Save strut height for use when recalculating line height after backing out chunks that don't fit. + FontMetrics strut_height = *line_box_height; UnbrokenSpanPosition span_pos; for( ; ; ) { @@ -1502,7 +1494,7 @@ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, unsigned scan_run_index; span_pos = *start_span_pos; for (scan_run_index = 0 ; scan_run_index < scan_runs.size() ; scan_run_index++) { - if (!_buildChunksInScanRun(para, span_pos, scan_runs[scan_run_index], chunk_info, line_box_height)) + if (!_buildChunksInScanRun(para, span_pos, scan_runs[scan_run_index], chunk_info, line_box_height, &strut_height)) break; if (!chunk_info->empty() && !chunk_info->back().broken_spans.empty()) span_pos = chunk_info->back().broken_spans.back().end; @@ -1533,9 +1525,11 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, UnbrokenSpanPosition const &start_span_pos, ScanlineMaker::ScanRun const &scan_run, std::vector *chunk_info, - FontMetrics *line_height) const + FontMetrics *line_height, + FontMetrics const *strut_height) const { - TRACE((" begin _buildChunksInScanRun: chunks: %lu\n", chunk_info->size())); + TRACE((" begin _buildChunksInScanRun: chunks: %lu, em size: %f\n", chunk_info->size(), line_height->emSize() )); + ChunkInfo new_chunk; new_chunk.text_width = 0.0; new_chunk.whitespace_count = 0; @@ -1641,7 +1635,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, } // Recalculate line_box_height after backing out chunks - line_height->setZero(); + *line_height = *strut_height; for (std::vector::const_iterator it_chunk = chunk_info->begin() ; it_chunk != chunk_info->end() ; it_chunk++) { for (std::vector::const_iterator it_span = it_chunk->broken_spans.begin() ; it_span != it_chunk->broken_spans.end() ; it_span++) { TRACE((" brokenspan line_height: %f\n", it_span->start.iter_span->line_height.emSize() )); -- cgit v1.2.3 From 21c7070f90ef59fb5b6782e7adabd3d0f79e174d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Dec 2015 19:58:44 +0100 Subject: Add Martin Owens radious patch (bzr r14500.1.11) --- src/display/guideline.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 2df0b3f26..e1a115353 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -178,6 +178,11 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, gl->affine = affine; + if (gl->locked) { + gl->origin->radius = 1; + } else { + gl->origin->radius = 3; + } sp_ctrlpoint_set_coords(gl->origin, gl->point_on_line); sp_canvas_item_request_update(SP_CANVAS_ITEM (gl->origin)); @@ -190,6 +195,7 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, //TODO: labels in angled guidelines are not showing up for some reason. sp_canvas_update_bbox (item, -1000000, -1000000, 1000000, 1000000); } + } // Returns 0.0 if point is on the guideline -- cgit v1.2.3 From 351afb17c6a579d3d1bb03500433b92b00123c03 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Dec 2015 20:59:06 +0100 Subject: Add rect to SP Control point on locked guides (bzr r14500.1.13) --- src/display/guideline.cpp | 6 ++++-- src/display/sp-ctrlpoint.cpp | 28 +++++++++++++++++++--------- src/display/sp-ctrlpoint.h | 6 ++++-- src/ui/control-manager.cpp | 2 +- 4 files changed, 28 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index e1a115353..4b7ea59ab 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -179,9 +179,11 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, gl->affine = affine; if (gl->locked) { - gl->origin->radius = 1; + sp_ctrlpoint_set_circle(gl->origin, false); + sp_ctrlpoint_set_lenght(gl->origin, 6); } else { - gl->origin->radius = 3; + sp_ctrlpoint_set_circle(gl->origin, true); + sp_ctrlpoint_set_lenght(gl->origin, 4); } sp_ctrlpoint_set_coords(gl->origin, gl->point_on_line); sp_canvas_item_request_update(SP_CANVAS_ITEM (gl->origin)); diff --git a/src/display/sp-ctrlpoint.cpp b/src/display/sp-ctrlpoint.cpp index 1082cb1b3..19dbbc130 100644 --- a/src/display/sp-ctrlpoint.cpp +++ b/src/display/sp-ctrlpoint.cpp @@ -42,7 +42,8 @@ sp_ctrlpoint_init (SPCtrlPoint *ctrlpoint) ctrlpoint->rgba = 0x0000ff7f; ctrlpoint->pt[Geom::X] = ctrlpoint->pt[Geom::Y] = 0.0; ctrlpoint->item=NULL; - ctrlpoint->radius = 2; + ctrlpoint->lenght = 4; + ctrlpoint->is_circle = true; } static void sp_ctrlpoint_destroy(SPCanvasItem *object) @@ -75,8 +76,11 @@ sp_ctrlpoint_render (SPCanvasItem *item, SPCanvasBuf *buf) cairo_new_path(buf->ct); Geom::Point pt = cp->pt * cp->affine; - - cairo_arc(buf->ct, pt[Geom::X] - buf->rect.left(), pt[Geom::Y] - buf->rect.top(), cp->radius, 0.0, 2 * M_PI); + if( cp->is_circle ) { + cairo_arc(buf->ct, pt[Geom::X] - buf->rect.left(), pt[Geom::Y] - buf->rect.top(), cp->lenght/2.0, 0.0, 2 * M_PI); + } else { + cairo_rectangle(buf->ct, pt[Geom::X] - buf->rect.left() - cp->lenght/2.0, pt[Geom::Y] - buf->rect.top() - cp->lenght/2.0 , cp->lenght, cp->lenght); + } cairo_stroke(buf->ct); } @@ -96,10 +100,10 @@ static void sp_ctrlpoint_update(SPCanvasItem *item, Geom::Affine const &affine, Geom::Point pt = cp->pt * affine; - item->x1 = pt[Geom::X] - cp->radius; - item->y1 = pt[Geom::Y] - cp->radius; - item->x2 = pt[Geom::X] + cp->radius; - item->y2 = pt[Geom::Y] + cp->radius; + item->x1 = pt[Geom::X] - cp->lenght; + item->y1 = pt[Geom::Y] - cp->lenght; + item->x2 = pt[Geom::X] + cp->lenght; + item->y2 = pt[Geom::Y] + cp->lenght; item->canvas->requestRedraw((int)item->x1 - 15, (int)item->y1 - 15, (int)item->x1 + 15, (int)item->y1 + 15); @@ -142,9 +146,15 @@ sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const Geom::Point pt) } void -sp_ctrlpoint_set_radius (SPCtrlPoint *cp, const double r) +sp_ctrlpoint_set_lenght (SPCtrlPoint *cp, const double r) +{ + cp->lenght = r; +} + +void +sp_ctrlpoint_set_circle (SPCtrlPoint *cp, const bool circle) { - cp->radius = r; + cp->is_circle = circle; } /* diff --git a/src/display/sp-ctrlpoint.h b/src/display/sp-ctrlpoint.h index a7a5475b7..02e61caf0 100644 --- a/src/display/sp-ctrlpoint.h +++ b/src/display/sp-ctrlpoint.h @@ -25,7 +25,8 @@ struct SPCtrlPoint : public SPCanvasItem { guint32 rgba; Geom::Point pt; Geom::Affine affine; - double radius; + double lenght; + bool is_circle; }; struct SPCtrlPointClass : public SPCanvasItemClass{}; @@ -34,7 +35,8 @@ GType sp_ctrlpoint_get_type (void); void sp_ctrlpoint_set_color (SPCtrlPoint *cp, guint32 rgba); void sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const gdouble x, const gdouble y); void sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const Geom::Point pt); -void sp_ctrlpoint_set_radius (SPCtrlPoint *cp, const double r); +void sp_ctrlpoint_set_lenght (SPCtrlPoint *cp, const double r); +void sp_ctrlpoint_set_circle (SPCtrlPoint *cp, const bool circle); diff --git a/src/ui/control-manager.cpp b/src/ui/control-manager.cpp index 5a3c5a496..10190a6a7 100644 --- a/src/ui/control-manager.cpp +++ b/src/ui/control-manager.cpp @@ -298,7 +298,7 @@ void ControlManagerImpl::updateItem(SPCanvasItem *item) double target = _sizeTable[item->ctrlType][_size - 1]; if ((item->ctrlType == CTRL_TYPE_ORIGIN) && SP_IS_CTRLPOINT(item)) { - sp_ctrlpoint_set_radius(SP_CTRLPOINT(item), target / 2.0); + sp_ctrlpoint_set_lenght(SP_CTRLPOINT(item), target ); } else { if (_sizeChangers.count(item->ctrlType) && _manager.isSelected(item)) { target += 2; -- cgit v1.2.3 From ddc6177836028eca89fb701ad2e5e923cb94ae87 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Mon, 7 Dec 2015 21:18:04 +0100 Subject: static code analysis (bzr r14508) --- src/helper/png-write.cpp | 6 +++--- src/sp-marker.cpp | 22 +++++++++++++--------- src/sp-star.cpp | 13 +++++++------ src/ui/uxmanager.cpp | 9 +++++---- src/widgets/toolbox.cpp | 18 +++++++++--------- 5 files changed, 37 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/helper/png-write.cpp b/src/helper/png-write.cpp index fc365c435..9430feeff 100644 --- a/src/helper/png-write.cpp +++ b/src/helper/png-write.cpp @@ -128,6 +128,9 @@ sp_png_write_rgba_striped(SPDocument *doc, int (* get_rows)(guchar const **rows, void **to_free, int row, int num_rows, void *data), void *data) { + g_return_val_if_fail(filename != NULL, false); + g_return_val_if_fail(data != NULL, false); + struct SPEBP *ebp = (struct SPEBP *) data; FILE *fp; png_structp png_ptr; @@ -135,9 +138,6 @@ sp_png_write_rgba_striped(SPDocument *doc, png_color_8 sig_bit; png_uint_32 r; - g_return_val_if_fail(filename != NULL, false); - g_return_val_if_fail(data != NULL, false); - /* open the file */ Inkscape::IO::dump_fopen_call(filename, "M"); diff --git a/src/sp-marker.cpp b/src/sp-marker.cpp index 9334614dc..88dfbe04e 100644 --- a/src/sp-marker.cpp +++ b/src/sp-marker.cpp @@ -43,14 +43,18 @@ public: std::vector items; }; -SPMarker::SPMarker() : SPGroup(), SPViewBox() { - - this->markerUnits = 0; - this->markerUnits_set = 0; - - this->orient_mode = MARKER_ORIENT_ANGLE; - this->orient_set = 0; - this->orient = 0; +SPMarker::SPMarker() : SPGroup(), SPViewBox(), + markerUnits_set(0), + markerUnits(0), + refX(), + refY(), + markerWidth(), + markerHeight(), + orient_set(0), + orient_mode(MARKER_ORIENT_ANGLE) +{ + // cppcheck-suppress useInitializationList + orient = 0; } /** @@ -442,7 +446,7 @@ const gchar *generate_marker(std::vector &reprs, Geom::Rec const gchar *mark_id = repr->attribute("id"); SPObject *mark_object = document->getObjectById(mark_id); - for (std::vector::const_iterator i=reprs.begin();i!=reprs.end();i++){ + for (std::vector::const_iterator i=reprs.begin();i!=reprs.end();++i){ Inkscape::XML::Node *node = *i; SPItem *copy = SP_ITEM(mark_object->appendChildRepr(node)); diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 51d5e6254..8a1956e3b 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -32,15 +32,16 @@ #include "sp-star.h" -SPStar::SPStar() : SPPolygon() { - this->sides = 5; - this->center = Geom::Point(0, 0); +SPStar::SPStar() : SPPolygon() , + sides(5), + center(0, 0), + flatsided(0), + rounded(0.0), + randomized(0.0) +{ this->r[0] = 1.0; this->r[1] = 0.001; this->arg[0] = this->arg[1] = 0.0; - this->flatsided = 0; - this->rounded = 0.0; - this->randomized = 0.0; } SPStar::~SPStar() { diff --git a/src/ui/uxmanager.cpp b/src/ui/uxmanager.cpp index 051df691e..036659661 100644 --- a/src/ui/uxmanager.cpp +++ b/src/ui/uxmanager.cpp @@ -244,12 +244,13 @@ void UXManagerImpl::delTrack( SPDesktopWidget* dtw ) void UXManagerImpl::connectToDesktop( vector const & toolboxes, SPDesktop *desktop ) { - TrackItem &tracker = trackedBoxes[desktop]; - vector& tracked = tracker.boxes; - if (desktop) + if (!desktop) { - tracker.destroyConn = desktop->connectDestroy(&desktopDestructHandler); + return; } + TrackItem &tracker = trackedBoxes[desktop]; + vector& tracked = tracker.boxes; + tracker.destroyConn = desktop->connectDestroy(&desktopDestructHandler); for (vector::const_iterator it = toolboxes.begin(); it != toolboxes.end(); ++it ) { GtkWidget* toolbox = *it; diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index c3f301c52..b75cdb4be 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -943,8 +943,12 @@ static Glib::RefPtr create_or_fetch_actions( SPDesktop* deskto }; Inkscape::IconSize toolboxSize = ToolboxFactory::prefToSize("/toolbox/small"); - Glib::RefPtr mainActions; + if (desktop == NULL) + { + return mainActions; + } + if ( groups.find(desktop) != groups.end() ) { mainActions = groups[desktop]; } @@ -952,10 +956,7 @@ static Glib::RefPtr create_or_fetch_actions( SPDesktop* deskto if ( !mainActions ) { mainActions = Gtk::ActionGroup::create("main"); groups[desktop] = mainActions; - if (desktop) - { - desktop->connectDestroy(&desktopDestructHandler); - } + desktop->connectDestroy(&desktopDestructHandler); } for ( guint i = 0; i < G_N_ELEMENTS(verbsToUse); i++ ) { @@ -1558,13 +1559,12 @@ static void toggle_snap_callback(GtkToggleAction *act, gpointer data) //data poi SPDesktop *dt = reinterpret_cast(ptr); SPNamedView *nv = dt->getNamedView(); - SPDocument *doc = nv->document; - - if (dt == NULL || nv == NULL) { - g_warning("No desktop or namedview specified (in toggle_snap_callback)!"); + if (nv == NULL) { + g_warning("No namedview specified (in toggle_snap_callback)!"); return; } + SPDocument *doc = nv->document; Inkscape::XML::Node *repr = nv->getRepr(); if (repr == NULL) { -- cgit v1.2.3 From c54db8d887cae2bd6dd326a10f976c726f905e7d Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Mon, 7 Dec 2015 21:19:14 +0100 Subject: static code analysis (bzr r14509) --- src/seltrans.cpp | 10 +++++----- src/snapper.h | 2 +- src/sp-conn-end.cpp | 2 +- src/sp-defs.cpp | 2 +- src/sp-item-group.cpp | 20 ++++++++++---------- src/sp-lpe-item.cpp | 10 +++++----- src/sp-switch.cpp | 4 ++-- src/text-chemistry.cpp | 16 ++++++++-------- src/text-editing.cpp | 2 +- src/vanishing-point.cpp | 8 ++++---- 10 files changed, 38 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 17d704975..f010a687d 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -241,7 +241,7 @@ void Inkscape::SelTrans::setCenter(Geom::Point const &p) // Write the new center position into all selected items std::vector items=_desktop->selection->itemList(); - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { + for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { SPItem *it = SP_ITEM(*iter); it->setCenter(p); // only set the value; updating repr and document_done will be done once, on ungrab @@ -271,7 +271,7 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s } std::vector items=_desktop->selection->itemList(); - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { + for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { SPItem *it = static_cast(sp_object_ref(*iter, NULL)); _items.push_back(it); _items_const.push_back(it); @@ -493,7 +493,7 @@ void Inkscape::SelTrans::ungrab() if (_center_is_set) { // we were dragging center; update reprs and commit undoable action std::vector items=_desktop->selection->itemList(); - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { + for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { SPItem *it = *iter; it->updateRepr(); } @@ -534,7 +534,7 @@ void Inkscape::SelTrans::stamp() _stamp_cache = l; } - for(std::vector::const_iterator x=l.begin();x!=l.end();x++) { + for(std::vector::const_iterator x=l.begin();x!=l.end(); ++x) { SPItem *original_item = *x; Inkscape::XML::Node *original_repr = original_item->getRepr(); @@ -712,7 +712,7 @@ void Inkscape::SelTrans::handleClick(SPKnot */*knot*/, guint state, SPSelTransHa if (state & GDK_SHIFT_MASK) { // Unset the center position for all selected items std::vector items=_desktop->selection->itemList(); - for ( std::vector::const_iterator iter=items.begin();iter!=items.end();iter++ ) { + for ( std::vector::const_iterator iter=items.begin();iter!=items.end(); ++iter) { SPItem *it = *iter; it->unsetCenter(); it->updateRepr(); diff --git a/src/snapper.h b/src/snapper.h index 24f9b9442..6c7995045 100644 --- a/src/snapper.h +++ b/src/snapper.h @@ -77,7 +77,7 @@ public: // Constructs a linear constraint SnapConstraint(Geom::Point const &p, Geom::Point const &d) : _point(p), _direction(d), _radius(0), _type(LINE) {} // Orthogonal version - SnapConstraint(Geom::Point const &p, Geom::Dim2 const &d) : _point(p), _radius(0), _type(LINE) {_direction = Geom::Point(); _direction[d] = 1.;} + SnapConstraint(Geom::Point const &p, Geom::Dim2 const &d) : _point(p), _direction(), _radius(0), _type(LINE) {_direction[d] = 1.;} SnapConstraint(Geom::Line const &l) : _point(l.origin()), _direction(l.versor()), _radius(0), _type(LINE) {} // Constructs a circular constraint SnapConstraint(Geom::Point const &p, Geom::Point const &d, Geom::Coord const &r) : _point(p), _direction(d), _radius(r), _type(CIRCLE) {} diff --git a/src/sp-conn-end.cpp b/src/sp-conn-end.cpp index fa5a57529..75cce4374 100644 --- a/src/sp-conn-end.cpp +++ b/src/sp-conn-end.cpp @@ -51,7 +51,7 @@ static bool try_get_intersect_point_with_item_recursive(Geom::PathVector& conn_p // consider all first-order children double child_pos = 0.0; std::vector g = sp_item_group_item_list(group); - for (std::vector::const_iterator i = g.begin();i!=g.end();i++) { + for (std::vector::const_iterator i = g.begin();i!=g.end();++i) { SPItem* child_item = *i; try_get_intersect_point_with_item_recursive(conn_pv, child_item, item_transform * child_item->transform, child_pos); diff --git a/src/sp-defs.cpp b/src/sp-defs.cpp index 2e341d3c6..dd779c0da 100644 --- a/src/sp-defs.cpp +++ b/src/sp-defs.cpp @@ -37,7 +37,7 @@ void SPDefs::update(SPCtx *ctx, guint flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; std::vector l(this->childList(true)); - for(std::vector::const_iterator i=l.begin();i!=l.end();i++){ + for(std::vector::const_iterator i=l.begin();i!=l.end();++i){ SPObject *child = *i; if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { child->updateDisplay(ctx, flags); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 5d96899b1..8cd0bf8d3 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -162,7 +162,7 @@ void SPGroup::update(SPCtx *ctx, unsigned int flags) { } childflags &= SP_OBJECT_MODIFIED_CASCADE; std::vector l=this->childList(true, SPObject::ActionUpdate); - for(std::vector ::const_iterator i=l.begin();i!=l.end();i++){ + for(std::vector ::const_iterator i=l.begin();i!=l.end();++i){ SPObject *child = *i; if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { @@ -206,7 +206,7 @@ void SPGroup::modified(guint flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; std::vector l=this->childList(true); - for(std::vector::const_iterator i=l.begin();i!=l.end();i++){ + for(std::vector::const_iterator i=l.begin();i!=l.end();++i){ SPObject *child = *i; if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { @@ -280,7 +280,7 @@ Geom::OptRect SPGroup::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox // TODO CPPIFY: replace this const_cast later std::vector l = const_cast(this)->childList(false, SPObject::ActionBBox); - for(std::vector::const_iterator i=l.begin();i!=l.end();i++){ + for(std::vector::const_iterator i=l.begin();i!=l.end();++i){ SPObject *o = *i; SPItem *item = dynamic_cast(o); if (item && !item->isHidden()) { @@ -294,7 +294,7 @@ Geom::OptRect SPGroup::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox void SPGroup::print(SPPrintContext *ctx) { std::vector l=this->childList(false); - for(std::vector::const_iterator i=l.begin();i!=l.end();i++){ + for(std::vector::const_iterator i=l.begin();i!=l.end();++i){ SPObject *o = *i; SPItem *item = dynamic_cast(o); if (item) { @@ -348,7 +348,7 @@ Inkscape::DrawingItem *SPGroup::show (Inkscape::Drawing &drawing, unsigned int k void SPGroup::hide (unsigned int key) { std::vector l=this->childList(false, SPObject::ActionShow); - for(std::vector::const_iterator i=l.begin();i!=l.end();i++){ + for(std::vector::const_iterator i=l.begin();i!=l.end();++i){ SPObject *o = *i; SPItem *item = dynamic_cast(o); @@ -373,7 +373,7 @@ void SPGroup::snappoints(std::vector &p, Inkscape: void sp_item_group_ungroup_handle_clones(SPItem *parent, Geom::Affine const g) { - for(std::list::const_iterator refd=parent->hrefList.begin();refd!=parent->hrefList.end();refd++){ + for(std::list::const_iterator refd=parent->hrefList.begin();refd!=parent->hrefList.end();++refd){ SPItem *citem = dynamic_cast(*refd); if (citem && !citem->cloned) { SPUse *useitem = dynamic_cast(citem); @@ -781,7 +781,7 @@ gint SPGroup::getItemCount() const { void SPGroup::_showChildren (Inkscape::Drawing &drawing, Inkscape::DrawingItem *ai, unsigned int key, unsigned int flags) { Inkscape::DrawingItem *ac = NULL; std::vector l=this->childList(false, SPObject::ActionShow); - for(std::vector::const_iterator i=l.begin();i!=l.end();i++){ + for(std::vector::const_iterator i=l.begin();i!=l.end();++i){ SPObject *o = *i; SPItem * child = dynamic_cast(o); if (child) { @@ -800,7 +800,7 @@ void SPGroup::update_patheffect(bool write) { std::vector const item_list = sp_item_group_item_list(this); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *subitem = *iter; SPLPEItem *lpeItem = dynamic_cast(subitem); @@ -810,7 +810,7 @@ void SPGroup::update_patheffect(bool write) { } if (hasPathEffect() && pathEffectsEnabled()) { - for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); it++) + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) { LivePathEffectObject *lpeobj = (*it)->lpeobject; @@ -828,7 +828,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) { std::vector const item_list = sp_item_group_item_list(group); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *subitem = *iter; SPGroup *subGroup = dynamic_cast(subitem); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 9befd2a2b..98b77cfe8 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -354,7 +354,7 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) } if (SP_IS_GROUP(lpeitem)) { std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *subitem = *iter; if (SP_IS_LPE_ITEM(subitem)) { sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(subitem)); @@ -388,7 +388,7 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) } } std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *subitem = *iter; if (SP_IS_LPE_ITEM(subitem)) { sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem)); @@ -681,7 +681,7 @@ SPLPEItem::apply_to_clippath(SPItem *item) } if(SP_IS_GROUP(item)){ std::vector item_list = sp_item_group_item_list(SP_GROUP(item)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *subitem = *iter; apply_to_clippath(SP_ITEM(subitem)); } @@ -733,7 +733,7 @@ SPLPEItem::apply_to_mask(SPItem *item) } if(SP_IS_GROUP(item)){ std::vector item_list = sp_item_group_item_list(SP_GROUP(item)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *subitem = *iter; apply_to_mask(SP_ITEM(subitem)); } @@ -747,7 +747,7 @@ SPLPEItem::apply_to_clip_or_mask_group(SPItem *group, SPItem *item) return; } std::vector item_list = sp_item_group_item_list(SP_GROUP(group)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();iter++) { + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *subitem = *iter; if (SP_IS_GROUP(subitem)) { apply_to_clip_or_mask_group(SP_ITEM(subitem), item); diff --git a/src/sp-switch.cpp b/src/sp-switch.cpp index cfc0e7d8b..d2dcde15d 100644 --- a/src/sp-switch.cpp +++ b/src/sp-switch.cpp @@ -97,7 +97,7 @@ void SPSwitch::_reevaluate(bool /*add_to_drawing*/) { _releaseLastItem(_cached_item); std::vector item_list = _childList(false, SPObject::ActionShow); - for ( std::vector::const_reverse_iterator iter=item_list.rbegin();iter!=item_list.rend();iter++) { + for ( std::vector::const_reverse_iterator iter=item_list.rbegin();iter!=item_list.rend();++iter) { SPObject *o = *iter; if ( !SP_IS_ITEM (o) ) { continue; @@ -132,7 +132,7 @@ void SPSwitch::_showChildren (Inkscape::Drawing &drawing, Inkscape::DrawingItem std::vector l = this->_childList(false, SPObject::ActionShow); - for ( std::vector::const_reverse_iterator iter=l.rbegin();iter!=l.rend();iter++) { + for ( std::vector::const_reverse_iterator iter=l.rbegin();iter!=l.rend();++iter) { SPObject *o = *iter; if (SP_IS_ITEM (o)) { diff --git a/src/text-chemistry.cpp b/src/text-chemistry.cpp index 9fc862ad2..fbbbe5807 100644 --- a/src/text-chemistry.cpp +++ b/src/text-chemistry.cpp @@ -44,7 +44,7 @@ static SPItem * flowtext_in_selection(Inkscape::Selection *selection) { std::vector items = selection->itemList(); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end();++i){ if (SP_IS_FLOWTEXT(*i)) return *i; } @@ -55,7 +55,7 @@ static SPItem * text_or_flowtext_in_selection(Inkscape::Selection *selection) { std::vector items = selection->itemList(); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end();++i){ if (SP_IS_TEXT(*i) || SP_IS_FLOWTEXT(*i)) return *i; } @@ -66,7 +66,7 @@ static SPItem * shape_in_selection(Inkscape::Selection *selection) { std::vector items = selection->itemList(); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end();++i){ if (SP_IS_SHAPE(*i)) return *i; } @@ -197,7 +197,7 @@ text_remove_from_path() bool did = false; std::vector items(selection->itemList()); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end();++i){ SPObject *obj = *i; if (SP_IS_TEXT_TEXTPATH(obj)) { @@ -261,7 +261,7 @@ text_remove_all_kerns() bool did = false; std::vector items = selection->itemList(); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end();++i){ SPObject *obj = *i; if (!SP_IS_TEXT(obj) && !SP_IS_TSPAN(obj) && !SP_IS_FLOWTEXT(obj)) { @@ -321,7 +321,7 @@ text_flow_into_shape() /* Add clones */ std::vector items = selection->itemList(); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end();++i){ SPItem *item = *i; if (SP_IS_SHAPE(item)){ Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); @@ -396,7 +396,7 @@ text_unflow () GSList *old_objs = NULL; std::vector items = selection->itemList(); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end();++i){ if (!SP_IS_FLOWTEXT(*i)) { continue; @@ -481,7 +481,7 @@ flowtext_to_text() std::vector reprs; std::vector items(selection->itemList()); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end();++i){ SPItem *item = *i; diff --git a/src/text-editing.cpp b/src/text-editing.cpp index d9cebc625..057523b1e 100644 --- a/src/text-editing.cpp +++ b/src/text-editing.cpp @@ -68,7 +68,7 @@ void te_update_layout_now_recursive(SPItem *item) { if (SP_IS_GROUP(item)) { std::vector item_list = sp_item_group_item_list(SP_GROUP(item)); - for(std::vector::const_iterator i=item_list.begin();i!=item_list.end();i++){ + for(std::vector::const_iterator i=item_list.begin();i!=item_list.end();++i){ SPItem* list_item = *i; te_update_layout_now_recursive(list_item); } diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp index 553e3a31d..19750bd37 100644 --- a/src/vanishing-point.cpp +++ b/src/vanishing-point.cpp @@ -259,7 +259,7 @@ std::list VanishingPoint::selectedBoxes(Inkscape::Selection *sel) { std::list sel_boxes; std::vector itemlist=sel->itemList(); - for (std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++) { + for (std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i) { SPItem *item = *i; SPBox3D *box = dynamic_cast(item); if (box && this->hasBox(box)) { @@ -399,7 +399,7 @@ VPDragger::VPsOfSelectedBoxes() { // FIXME: Should we take the selection from the parent VPDrag? I guess it shouldn't make a difference. Inkscape::Selection *sel = SP_ACTIVE_DESKTOP->getSelection(); std::vector itemlist=sel->itemList(); - for (std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++) { + for (std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i) { SPItem *item = *i; SPBox3D *box = dynamic_cast(item); if (box) { @@ -582,7 +582,7 @@ VPDrag::updateDraggers () g_return_if_fail (this->selection != NULL); std::vector itemlist=this->selection->itemList(); - for (std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++) { + for (std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i) { SPItem *item = *i; SPBox3D *box = dynamic_cast(item); if (box) { @@ -615,7 +615,7 @@ VPDrag::updateLines () g_return_if_fail (this->selection != NULL); std::vector itemlist=this->selection->itemList(); - for (std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++) { + for (std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i) { SPItem *item = *i; SPBox3D *box = dynamic_cast(item); if (box) { -- cgit v1.2.3 From 25fbd2cc032dd472c3f85468c957b52e2a10d446 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Mon, 7 Dec 2015 21:20:33 +0100 Subject: static code analysis (bzr r14510) --- src/extension/implementation/script.cpp | 2 +- src/extension/internal/bitmap/imagemagick.cpp | 2 +- src/extension/internal/cairo-render-context.cpp | 6 +++--- src/live_effects/lpe-knot.cpp | 2 +- src/live_effects/parameter/originalpatharray.cpp | 2 +- src/trace/trace.cpp | 2 +- src/ui/clipboard.cpp | 4 ++-- src/ui/dialog/grid-arrange-tab.cpp | 2 +- src/ui/interface.cpp | 4 ++-- src/ui/tools/measure-tool.cpp | 4 ++-- src/ui/tools/mesh-tool.cpp | 4 ++-- src/ui/tools/node-tool.cpp | 2 +- 12 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index e07a3963c..52cc7a2ca 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -691,7 +691,7 @@ void Script::effect(Inkscape::Extension::Effect *module, std::vector selected = desktop->getSelection()->itemList(); //desktop should not be NULL since doc was checked and desktop is a casted pointer - for(std::vector::const_iterator x = selected.begin(); x != selected.end(); x++){ + for(std::vector::const_iterator x = selected.begin(); x != selected.end(); ++x){ Glib::ustring selected_id; selected_id += "--id="; selected_id += (*x)->getId(); diff --git a/src/extension/internal/bitmap/imagemagick.cpp b/src/extension/internal/bitmap/imagemagick.cpp index bc0dd8e33..40d548a24 100644 --- a/src/extension/internal/bitmap/imagemagick.cpp +++ b/src/extension/internal/bitmap/imagemagick.cpp @@ -79,7 +79,7 @@ ImageMagickDocCache::ImageMagickDocCache(Inkscape::UI::View::View * view) : _imageItems = new SPItem*[selectCount]; // Loop through selected items - for (std::vector::const_iterator i = selectedItemList.begin(); i != selectedItemList.end(); i++) { + for (std::vector::const_iterator i = selectedItemList.begin(); i != selectedItemList.end(); ++i) { SPItem *item = *i; Inkscape::XML::Node *node = reinterpret_cast(item->getRepr()); if (!strcmp(node->name(), "image") || !strcmp(node->name(), "svg:image")) diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index c3e416184..97b84606f 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -1182,7 +1182,7 @@ CairoRenderContext::_createHatchPainter(SPPaintServer const *const paintserver, std::vector children(evil->hatchPaths()); for (int i = 0; i < overflow_steps; i++) { - for (std::vector::iterator iter = children.begin(); iter != children.end(); iter++) { + for (std::vector::iterator iter = children.begin(); iter != children.end(); ++iter) { SPHatchPath *path = *iter; _renderer->renderHatchPath(pattern_ctx, *path, dkey); } @@ -1677,8 +1677,8 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const &font_ma cairo_save(_cr); cairo_set_font_face(_cr, font_face); - if (fc_pattern && FcPatternGetDouble(fc_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch) - size = 12.0; + //if (fc_pattern && FcPatternGetDouble(fc_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch) + // size = 12.0; // set the given font matrix cairo_matrix_t matrix; diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index c3000fe0d..bf84e645d 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -507,7 +507,7 @@ static void collectPathsAndWidths (SPLPEItem const *lpeitem, Geom::PathVector &paths, std::vector &stroke_widths){ if (SP_IS_GROUP(lpeitem)) { std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); - for ( std::vector::const_iterator iter = item_list.begin(); iter != item_list.end(); iter++) { + for ( std::vector::const_iterator iter = item_list.begin(); iter != item_list.end(); ++iter) { SPObject *subitem = *iter; if (SP_IS_LPE_ITEM(subitem)) { collectPathsAndWidths(SP_LPE_ITEM(subitem), paths, stroke_widths); diff --git a/src/live_effects/parameter/originalpatharray.cpp b/src/live_effects/parameter/originalpatharray.cpp index 9e03e2c02..7e3a6f5fe 100644 --- a/src/live_effects/parameter/originalpatharray.cpp +++ b/src/live_effects/parameter/originalpatharray.cpp @@ -245,7 +245,7 @@ void OriginalPathArrayParam::on_down_button_click() if (*iter == row[_model->_colObject]) { std::vector::iterator niter = _vector.erase(iter); if (niter != _vector.end()) { - niter++; + ++niter; i++; } _vector.insert(niter, row[_model->_colObject]); diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp index 91c230920..18f03aa1b 100644 --- a/src/trace/trace.cpp +++ b/src/trace/trace.cpp @@ -74,7 +74,7 @@ SPImage *Tracer::getSelectedSPImage() them as bottom-to-top so that we can discover the image and any SPItems above it */ - for (std::vector::const_iterator i=list.begin() ; list.end()!=i ; i++) + for (std::vector::const_iterator i=list.begin() ; list.end()!=i ; ++i) { if (!SP_IS_ITEM(*i)) { diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 354fa45dc..f04d8a591 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -682,11 +682,11 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) //remove already copied elements from cloned_elements std::vectortr; - for(std::set::iterator it = cloned_elements.begin();it!=cloned_elements.end();it++){ + for(std::set::iterator it = cloned_elements.begin();it!=cloned_elements.end();++it){ if(std::find(sorted_items.begin(),sorted_items.end(),*it)!=sorted_items.end()) tr.push_back(*it); } - for(std::vector::iterator it = tr.begin();it!=tr.end();it++){ + for(std::vector::iterator it = tr.begin();it!=tr.end();++it){ cloned_elements.erase(*it); } diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp index 53c25c3d5..639e463ea 100644 --- a/src/ui/dialog/grid-arrange-tab.cpp +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -305,7 +305,7 @@ g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_h GSList *current_row = NULL; col_cnt = 0; - for(;it!=sorted.end()&&col_cnt::iterator it = types.begin() ; it != types.end() ; it++) { + for (std::vector::iterator it = types.begin() ; it != types.end() ; ++it) { completeDropTargets[pos].target = *it; completeDropTargets[pos].flags = 0; completeDropTargets[pos].info = IMAGE_DATA; @@ -2070,7 +2070,7 @@ void ContextMenu::ImageEdit(void) #endif std::vector itemlist=_desktop->selection->itemList(); - for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ Inkscape::XML::Node *ir = (*i)->getRepr(); const gchar *href = ir->attribute("xlink:href"); diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 06f32ba5c..4d17a7ed5 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -1108,7 +1108,7 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N r->stop(); } std::vector intersection_times; - for (std::vector::const_iterator i=items.begin(); i!=items.end(); i++) { + for (std::vector::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); @@ -1155,7 +1155,7 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N std::vector intersections; std::sort(intersection_times.begin(), intersection_times.end()); - for (std::vector::iterator iter_t = intersection_times.begin(); iter_t != intersection_times.end(); iter_t++) { + for (std::vector::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)); } diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index 794296329..56ba08789 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -471,7 +471,7 @@ bool MeshTool::root_handler(GdkEvent* event) { } else { // Create a new gradient with default coordinates. std::vector items=selection->itemList(); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end();++i){ SPItem *item = *i; SPGradientType new_type = SP_GRADIENT_TYPE_MESH; Inkscape::PaintTarget fsmode = (prefs->getInt("/tools/gradient/newfillorstroke", 1) != 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE; @@ -956,7 +956,7 @@ static void sp_mesh_end_drag(MeshTool &rc) { sp_repr_css_set_property(css, "fill-opacity", "1.0"); std::vector items=selection->itemList(); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end();++i){ //FIXME: see above sp_repr_css_change_recursive((*i)->getRepr(), css, "style"); diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index 6a6ca0b26..cceaca7cb 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -413,7 +413,7 @@ void NodeTool::selection_changed(Inkscape::Selection *sel) { std::set shapes; std::vector items=sel->itemList(); - for(std::vector::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector::const_iterator i=items.begin();i!=items.end();++i){ SPObject *obj = *i; if (SP_IS_ITEM(obj)) { -- cgit v1.2.3 From d0e818f6aab594de812e51550a8b81838f3f783d Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Mon, 7 Dec 2015 21:38:35 +0100 Subject: static code analysis (bzr r14511) --- src/knot-holder-entity.h | 5 ++++- src/sp-flowtext.cpp | 6 ++++-- src/sp-item-group.cpp | 14 +++++++------- 3 files changed, 15 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/knot-holder-entity.h b/src/knot-holder-entity.h index 43ab25e5c..63a068cab 100644 --- a/src/knot-holder-entity.h +++ b/src/knot-holder-entity.h @@ -44,7 +44,10 @@ public: item(NULL), desktop(NULL), parent_holder(NULL), - my_counter(0) + my_counter(0), + handler_id(0), + _click_handler_id(0), + _ungrab_handler_id(0) {} virtual ~KnotHolderEntity(); diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index cac3cc61d..b87507e18 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -34,8 +34,10 @@ #include "display/drawing-text.h" -SPFlowtext::SPFlowtext() : SPItem() { - this->par_indent = 0; +SPFlowtext::SPFlowtext() : SPItem(), + par_indent(0), + _optimizeScaledText(false) +{ } SPFlowtext::~SPFlowtext() { diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 8cd0bf8d3..83d67cf5a 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -58,8 +58,11 @@ using Inkscape::DocumentUndo; static void sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write); -SPGroup::SPGroup() : SPLPEItem() { - this->_layer_mode = SPGroup::GROUP; +SPGroup::SPGroup() : SPLPEItem(), + _expanded(false), + _insertBottom(false), + _layer_mode(SPGroup::GROUP) +{ } SPGroup::~SPGroup() { @@ -90,10 +93,9 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) if ( item ) { /* TODO: this should be moved into SPItem somehow */ SPItemView *v; - Inkscape::DrawingItem *ac; for (v = this->display; v != NULL; v = v->next) { - ac = item->invoke_show (v->arenaitem->drawing(), v->key, v->flags); + Inkscape::DrawingItem *ac = item->invoke_show (v->arenaitem->drawing(), v->key, v->flags); if (ac) { v->arenaitem->appendChild(ac); @@ -105,12 +107,10 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) if ( item ) { /* TODO: this should be moved into SPItem somehow */ SPItemView *v; - Inkscape::DrawingItem *ac; - unsigned position = item->pos_in_parent(); for (v = this->display; v != NULL; v = v->next) { - ac = item->invoke_show (v->arenaitem->drawing(), v->key, v->flags); + Inkscape::DrawingItem *ac = item->invoke_show (v->arenaitem->drawing(), v->key, v->flags); if (ac) { v->arenaitem->prependChild(ac); -- cgit v1.2.3 From 93650897c928bfa9ca9b737cfbff55c25271d5d3 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Tue, 8 Dec 2015 00:34:32 +0100 Subject: cppification : GHashMaps replaced by stl maps. getResouceList now gives a std::set. Should give some performance improvements (quite a few linear lookups are now logarithmic) (bzr r14504.1.6) --- src/color-profile.cpp | 11 +++-- src/document-private.h | 11 +++-- src/document.cpp | 74 ++++++++++++++++----------------- src/document.h | 3 +- src/gradient-chemistry.cpp | 6 +-- src/gradient-drag.cpp | 6 +-- src/layer-manager.cpp | 20 ++++----- src/profile-manager.cpp | 8 ++-- src/resource-manager.cpp | 14 +++---- src/sp-guide.cpp | 7 ++-- src/ui/dialog/document-properties.cpp | 64 +++++++++++++--------------- src/ui/dialog/filter-effects-dialog.cpp | 7 ++-- src/ui/dialog/layers.cpp | 8 ---- src/ui/dialog/svg-fonts-dialog.cpp | 6 +-- src/ui/dialog/swatches.cpp | 27 ++++++------ src/ui/interface.cpp | 6 +-- src/ui/widget/color-icc-selector.cpp | 7 ++-- src/widgets/desktop-widget.cpp | 6 +-- src/widgets/gradient-toolbar.cpp | 32 +++++++------- src/widgets/gradient-vector.cpp | 8 ++-- src/widgets/paint-selector.cpp | 8 ++-- src/xml/rebase-hrefs.cpp | 6 +-- 22 files changed, 162 insertions(+), 183 deletions(-) (limited to 'src') diff --git a/src/color-profile.cpp b/src/color-profile.cpp index 690a72654..34f1b0155 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -488,18 +488,17 @@ static int getLcmsIntent( guint svgIntent ) static SPObject* bruteFind( SPDocument* document, gchar const* name ) { SPObject* result = 0; - const GSList * current = document->getResourceList("iccprofile"); - while ( current && !result ) { - if ( IS_COLORPROFILE(current->data) ) { - ColorProfile* prof = COLORPROFILE(current->data); + std::set current = document->getResourceList("iccprofile"); + for (std::set::const_iterator it = current.begin(); (!result) && (it != current.end()); ++it) { + if ( IS_COLORPROFILE(*it) ) { + ColorProfile* prof = COLORPROFILE(*it); if ( prof ) { if ( prof->name && (strcmp(prof->name, name) == 0) ) { - result = SP_OBJECT(current->data); + result = SP_OBJECT(*it); break; } } } - current = g_slist_next(current); } return result; diff --git a/src/document-private.h b/src/document-private.h index a5033b3c2..a4a2abd77 100644 --- a/src/document-private.h +++ b/src/document-private.h @@ -15,6 +15,8 @@ */ #include +#include +#include #include #include #include "xml/event-fns.h" @@ -40,8 +42,10 @@ struct SPDocumentPrivate { typedef std::map IDChangedSignalMap; typedef std::map ResourcesChangedSignalMap; - GHashTable *iddef; /**< Dictionary of id -> SPObject mappings */ - GHashTable *reprdef; /**< Dictionary of Inkscape::XML::Node -> SPObject mappings */ + std::map iddef; + std::map reprdef; + //GHashTable *iddef; /**< Dictionary of id -> SPObject mappings */ + //GHashTable *reprdef; /**< Dictionary of Inkscape::XML::Node -> SPObject mappings */ unsigned long serial; @@ -50,7 +54,8 @@ struct SPDocumentPrivate { /* Resources */ /* It is GHashTable of GSLists */ - GHashTable *resources; + std::map > resources; + //GHashTable *resources; ResourcesChangedSignalMap resources_changed_signals; sigc::signal destroySignal; diff --git a/src/document.cpp b/src/document.cpp index 23d99d78c..8c160be38 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -119,11 +119,6 @@ SPDocument::SPDocument() : p->serial = next_serial++; - p->iddef = g_hash_table_new(g_direct_hash, g_direct_equal); - p->reprdef = g_hash_table_new(g_direct_hash, g_direct_equal); - - p->resources = g_hash_table_new(g_str_hash, g_str_equal); - p->sensitive = false; p->partial = NULL; p->history_size = 0; @@ -177,17 +172,10 @@ SPDocument::~SPDocument() { root = NULL; } - if (priv->iddef) g_hash_table_destroy(priv->iddef); - if (priv->reprdef) g_hash_table_destroy(priv->reprdef); - if (rdoc) Inkscape::GC::release(rdoc); /* Free resources */ - g_hash_table_foreach_remove(priv->resources, sp_document_resource_list_free, this); - g_hash_table_destroy(priv->resources); - - delete priv; - priv = NULL; + priv->resources.clear(); } cr_cascade_unref(style_cascade); @@ -1008,11 +996,15 @@ void SPDocument::bindObjectToId(gchar const *id, SPObject *object) { GQuark idq = g_quark_from_string(id); if (object) { - g_assert(g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)) == NULL); - g_hash_table_insert(priv->iddef, GINT_TO_POINTER(idq), object); + g_assert(priv->iddef.find(id)==priv->iddef.end()); + priv->iddef[id] = object; + //g_assert(g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)) == NULL); + //g_hash_table_insert(priv->iddef, GINT_TO_POINTER(idq), object); } else { - g_assert(g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)) != NULL); - g_hash_table_remove(priv->iddef, GINT_TO_POINTER(idq)); + g_assert(priv->iddef.find(id)!=priv->iddef.end()); + priv->iddef.erase(id); + //g_assert(g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)) != NULL); + //g_hash_table_remove(priv->iddef, GINT_TO_POINTER(idq)); } SPDocumentPrivate::IDChangedSignalMap::iterator pos; @@ -1047,15 +1039,16 @@ SPObject *SPDocument::getObjectById(Glib::ustring const &id) const SPObject *SPDocument::getObjectById(gchar const *id) const { g_return_val_if_fail(id != NULL, NULL); - if (!priv || !priv->iddef) { + if (!priv || priv->iddef.empty()) { return NULL; } GQuark idq = g_quark_from_string(id); - gpointer rv = g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)); - if(rv != NULL) + std::map::iterator rv = priv->iddef.find(id); + //gpointer rv = g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)); + if(rv != priv->iddef.end()) { - return static_cast(rv); + return (rv->second); } else { @@ -1072,18 +1065,22 @@ sigc::connection SPDocument::connectIdChanged(gchar const *id, void SPDocument::bindObjectToRepr(Inkscape::XML::Node *repr, SPObject *object) { if (object) { - g_assert(g_hash_table_lookup(priv->reprdef, repr) == NULL); - g_hash_table_insert(priv->reprdef, repr, object); + g_assert(priv->reprdef.find(repr)==priv->reprdef.end()); + priv->reprdef[repr] = object; } else { - g_assert(g_hash_table_lookup(priv->reprdef, repr) != NULL); - g_hash_table_remove(priv->reprdef, repr); + g_assert(priv->reprdef.find(repr)!=priv->reprdef.end()); + priv->reprdef.erase(repr); } } SPObject *SPDocument::getObjectByRepr(Inkscape::XML::Node *repr) const { g_return_val_if_fail(repr != NULL, NULL); - return static_cast(g_hash_table_lookup(priv->reprdef, repr)); + std::map::iterator rv = priv->reprdef.find(repr); + if(rv != priv->reprdef.end()) + return (rv->second); + else + return NULL; } Glib::ustring SPDocument::getLanguage() const @@ -1528,10 +1525,9 @@ bool SPDocument::addResource(gchar const *key, SPObject *object) bool result = false; if ( !object->cloned ) { - GSList *rlist = (GSList*)g_hash_table_lookup(priv->resources, key); - g_return_val_if_fail(!g_slist_find(rlist, object), false); - rlist = g_slist_prepend(rlist, object); - g_hash_table_insert(priv->resources, (gpointer) key, rlist); + std::set rlist = priv->resources[key]; + g_return_val_if_fail(rlist.find(object) == rlist.end(), false); + rlist.insert(object); GQuark q = g_quark_from_string(key); @@ -1560,11 +1556,10 @@ bool SPDocument::removeResource(gchar const *key, SPObject *object) bool result = false; if ( !object->cloned ) { - GSList *rlist = (GSList*)g_hash_table_lookup(priv->resources, key); - g_return_val_if_fail(rlist != NULL, false); - g_return_val_if_fail(g_slist_find(rlist, object), false); - rlist = g_slist_remove(rlist, object); - g_hash_table_insert(priv->resources, (gpointer) key, rlist); + std::set rlist = priv->resources[key]; + g_return_val_if_fail(!rlist.empty(), false); + g_return_val_if_fail(rlist.find(object) != rlist.end(), false); + rlist.erase(object); GQuark q = g_quark_from_string(key); priv->resources_changed_signals[q].emit(); @@ -1575,12 +1570,13 @@ bool SPDocument::removeResource(gchar const *key, SPObject *object) return result; } -GSList const *SPDocument::getResourceList(gchar const *key) const +std::set const SPDocument::getResourceList(gchar const *key) const { - g_return_val_if_fail(key != NULL, NULL); - g_return_val_if_fail(*key != '\0', NULL); + std::set emptyset; + g_return_val_if_fail(key != NULL, emptyset); + g_return_val_if_fail(*key != '\0', emptyset); - return (GSList*)g_hash_table_lookup(this->priv->resources, key); + return this->priv->resources[key]; } sigc::connection SPDocument::connectResourcesChanged(gchar const *key, diff --git a/src/document.h b/src/document.h index be3f106d8..c7d3abf90 100644 --- a/src/document.h +++ b/src/document.h @@ -27,6 +27,7 @@ #include #include #include +#include namespace Avoid { class Router; @@ -258,7 +259,7 @@ public: int ensureUpToDate(); bool addResource(char const *key, SPObject *object); bool removeResource(char const *key, SPObject *object); - const GSList *getResourceList(char const *key) const; + const std::set getResourceList(char const *key) const; std::vector getItemsInBox(unsigned int dkey, Geom::Rect const &box) const; std::vector getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box) const; SPItem *getItemAtPoint(unsigned int key, Geom::Point const &p, bool into_groups, SPItem *upto = NULL) const; diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 29522d7b1..9f2d030d4 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -1612,9 +1612,9 @@ void sp_gradient_unset_swatch(SPDesktop *desktop, std::string id) SPDocument *doc = desktop ? desktop->doc() : 0; if (doc) { - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); + const std::set gradients = doc->getResourceList("gradient"); + for (std::set::const_iterator i = gradients.begin(); i != gradients.end(); ++i) { + SPGradient* grad = SP_GRADIENT(*i); if ( id == grad->getId() ) { grad->setSwatch(false); DocumentUndo::done(doc, SP_VERB_CONTEXT_GRADIENT, diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index 3e5fcd0f4..8fd997121 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -208,9 +208,9 @@ Glib::ustring GrDrag::makeStopSafeColor( gchar const *str, bool &isNull ) Glib::ustring::size_type pos = colorStr.find("url(#"); if ( pos != Glib::ustring::npos ) { Glib::ustring targetName = colorStr.substr(pos + 5, colorStr.length() - 6); - const GSList *gradients = desktop->doc()->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); + std::set gradients = desktop->doc()->getResourceList("gradient"); + for (std::set::const_iterator it = gradients.begin(); it != gradients.end(); ++it) { + SPGradient* grad = SP_GRADIENT(*it); if ( targetName == grad->getId() ) { SPGradient *vect = grad->getVector(); SPStop *firstStop = (vect) ? vect->getFirstStop() : grad->getFirstStop(); diff --git a/src/layer-manager.cpp b/src/layer-manager.cpp index 3bbc831d5..5dae5f20a 100644 --- a/src/layer-manager.cpp +++ b/src/layer-manager.cpp @@ -191,15 +191,12 @@ Glib::ustring LayerManager::getNextLayerName( SPObject* obj, gchar const *label) } std::set currentNames; - GSList const *layers=_document->getResourceList("layer"); + std::set layers = _document->getResourceList("layer"); SPObject *root=_desktop->currentRoot(); if ( root ) { - for ( GSList const *iter=layers ; iter ; iter = iter->next ) { - SPObject *layer=static_cast(iter->data); - if ( layer != obj ) { - currentNames.insert( layer->label() ? Glib::ustring(layer->label()) : Glib::ustring() ); - } - } + std::set::iterator iter = layers.find(obj); + if (iter != layers.end()) + currentNames.insert( (*iter)->label() ? Glib::ustring((*iter)->label()) : Glib::ustring() ); } // Not sure if we need to cap it, but we'll just be paranoid for the moment @@ -262,15 +259,16 @@ void LayerManager::_rebuild() { if (!_document) // http://sourceforge.net/mailarchive/forum.php?thread_name=5747bce9a7ed077c1b4fc9f0f4f8a5e0%40localhost&forum_name=inkscape-devel return; - GSList const *layers = _document->getResourceList("layer"); + std::set layers = _document->getResourceList("layer"); + SPObject *root=_desktop->currentRoot(); if ( root ) { _addOne(root); std::set layersToAdd; - for ( GSList const *iter = layers; iter; iter = iter->next ) { - SPObject *layer = static_cast(iter->data); + for ( std::set::const_iterator iter = layers.begin(); iter != layers.end(); ++iter ) { + SPObject *layer = *iter; // Debug::EventTracker tracker(Util::format("Examining %s", layer->label())); bool needsAdd = false; std::set additional; @@ -282,7 +280,7 @@ void LayerManager::_rebuild() { SPGroup* group = SP_GROUP(curr); if ( group->layerMode() == SPGroup::LAYER ) { // If we have a layer-group as the one or a parent, ensure it is listed as a valid layer. - needsAdd &= ( g_slist_find(const_cast(layers), curr) != NULL ); + needsAdd &= ( layers.find(curr) != layers.end() ); // XML Tree being used here directly while it shouldn't be... if ( (!(group->getRepr())) || (!(group->getRepr()->parent())) ) { needsAdd = false; diff --git a/src/profile-manager.cpp b/src/profile-manager.cpp index 90b124195..035aa6051 100644 --- a/src/profile-manager.cpp +++ b/src/profile-manager.cpp @@ -34,11 +34,9 @@ void ProfileManager::_resourcesChanged() { std::vector newList; if (_doc) { - const GSList *current = _doc->getResourceList( "iccprofile" ); - while ( current ) { - newList.push_back(SP_OBJECT(current->data)); - current = g_slist_next(current); - } + std::set current = _doc->getResourceList( "iccprofile" ); + for (std::set::const_iterator i = current.begin(); i != current.end(); ++i) + newList.push_back(*i); } sort( newList.begin(), newList.end() ); diff --git a/src/resource-manager.cpp b/src/resource-manager.cpp index dbff27827..18d7c6ba2 100644 --- a/src/resource-manager.cpp +++ b/src/resource-manager.cpp @@ -179,9 +179,9 @@ std::vector ResourceManagerImpl::findBrokenLinks( SPDocument *doc std::set uniques; if ( doc ) { - GSList const *images = doc->getResourceList("image"); - for (GSList const *it = images; it; it = it->next) { - Inkscape::XML::Node *ir = static_cast(it->data)->getRepr(); + std::set images = doc->getResourceList("image"); + for (std::set::const_iterator it = images.begin(); it != images.end(); ++it) { + Inkscape::XML::Node *ir = (*it)->getRepr(); gchar const *href = ir->attribute("xlink:href"); if ( href && ( uniques.find(href) == uniques.end() ) ) { @@ -305,10 +305,10 @@ bool ResourceManagerImpl::fixupBrokenLinks(SPDocument *doc) bool savedUndoState = DocumentUndo::getUndoSensitive(doc); DocumentUndo::setUndoSensitive(doc, true); - - GSList const *images = doc->getResourceList("image"); - for (GSList const *it = images; it; it = it->next) { - Inkscape::XML::Node *ir = static_cast(it->data)->getRepr(); + + std::set images = doc->getResourceList("image"); + for (std::set::const_iterator it = images.begin(); it != images.end(); ++it) { + Inkscape::XML::Node *ir = (*it)->getRepr(); gchar const *href = ir->attribute("xlink:href"); if ( href ) { diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 06eaee001..6038860f8 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -255,10 +255,11 @@ void sp_guide_create_guides_around_page(SPDesktop *dt) void sp_guide_delete_all_guides(SPDesktop *dt) { SPDocument *doc=dt->getDocument(); - const GSList *current; - while ( (current = doc->getResourceList("guide")) ) { - SPGuide* guide = SP_GUIDE(current->data); + std::set current = doc->getResourceList("guide"); + while (!current.empty()){ + SPGuide* guide = SP_GUIDE(*(current.begin())); sp_guide_remove(guide); + current = doc->getResourceList("guide"); } DocumentUndo::done(doc, SP_VERB_NONE, _("Delete All Guides")); diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 5b63d14e1..8af744fd3 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -511,17 +511,16 @@ void DocumentProperties::linkSelectedProfile() void DocumentProperties::populate_linked_profiles_box() { _LinkedProfilesListStore->clear(); - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "iccprofile" ); - if (current) { - _emb_profiles_observer.set(SP_OBJECT(current->data)->parent); + std::set current = SP_ACTIVE_DOCUMENT->getResourceList( "iccprofile" ); + if (! current.empty()) { + _emb_profiles_observer.set((*(current.begin()))->parent); } - while ( current ) { - SPObject* obj = SP_OBJECT(current->data); + for (std::set::const_iterator it = current.begin(); it != current.end(); ++it) { + SPObject* obj = *it; Inkscape::ColorProfile* prof = reinterpret_cast(obj); Gtk::TreeModel::Row row = *(_LinkedProfilesListStore->append()); row[_LinkedProfilesListColumns.nameColumn] = prof->name; // row[_LinkedProfilesListColumns.previewColumn] = "Color Preview"; - current = g_slist_next(current); } } @@ -594,10 +593,9 @@ void DocumentProperties::removeSelectedProfile(){ return; } } - - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "iccprofile" ); - while ( current ) { - SPObject* obj = SP_OBJECT(current->data); + std::set current = SP_ACTIVE_DOCUMENT->getResourceList( "iccprofile" ); + for (std::set::const_iterator it = current.begin(); it != current.end(); ++it) { + SPObject* obj = *it; Inkscape::ColorProfile* prof = reinterpret_cast(obj); if (!name.compare(prof->name)){ @@ -606,7 +604,6 @@ void DocumentProperties::removeSelectedProfile(){ DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_COLOR_PROFILE, _("Remove linked color profile")); break; // removing the color profile likely invalidates part of the traversed list, stop traversing here. } - current = g_slist_next(current); } populate_linked_profiles_box(); @@ -722,9 +719,9 @@ void DocumentProperties::build_cms() _LinkedProfilesList.signal_button_release_event().connect_notify(sigc::mem_fun(*this, &DocumentProperties::linked_profiles_list_button_release)); cms_create_popup_menu(_LinkedProfilesList, sigc::mem_fun(*this, &DocumentProperties::removeSelectedProfile)); - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "defs" ); - if (current) { - _emb_profiles_observer.set(SP_OBJECT(current->data)->parent); + std::set current = SP_ACTIVE_DOCUMENT->getResourceList( "defs" ); + if (!current.empty()) { + _emb_profiles_observer.set((*(current.begin()))->parent); } _emb_profiles_observer.signal_changed().connect(sigc::mem_fun(*this, &DocumentProperties::populate_linked_profiles_box)); onColorProfileSelectRow(); @@ -959,9 +956,9 @@ void DocumentProperties::build_scripting() #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) //TODO: review this observers code: - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); - if (current) { - _scripts_observer.set(SP_OBJECT(current->data)->parent); + std::set current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); + if (! current.empty()) { + _scripts_observer.set((*(current.begin()))->parent); } _scripts_observer.signal_changed().connect(sigc::mem_fun(*this, &DocumentProperties::populate_script_lists)); onEmbeddedScriptSelectRow(); @@ -1174,9 +1171,9 @@ void DocumentProperties::removeExternalScript(){ } } - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); - while ( current ) { - SPObject* obj = reinterpret_cast(current->data); + std::set current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); + for (std::set::const_iterator it = current.begin(); it != current.end(); ++it) { + SPObject* obj = *it; if (obj) { SPScript* script = dynamic_cast(obj); if (script && (name == script->xlinkhref)) { @@ -1191,7 +1188,6 @@ void DocumentProperties::removeExternalScript(){ } } } - current = g_slist_next(current); } populate_script_lists(); @@ -1253,9 +1249,9 @@ void DocumentProperties::changeEmbeddedScript(){ } bool voidscript=true; - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); - while ( current ) { - SPObject* obj = SP_OBJECT(current->data); + std::set current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); + for (std::set::const_iterator it = current.begin(); it != current.end(); ++it) { + SPObject* obj = *it; if (id == obj->getId()){ int count=0; @@ -1279,7 +1275,6 @@ void DocumentProperties::changeEmbeddedScript(){ } } } - current = g_slist_next(current); } if (voidscript) @@ -1299,9 +1294,9 @@ void DocumentProperties::editEmbeddedScript(){ } Inkscape::XML::Document *xml_doc = SP_ACTIVE_DOCUMENT->getReprDoc(); - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); - while ( current ) { - SPObject* obj = SP_OBJECT(current->data); + std::set current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); + for (std::set::const_iterator it = current.begin(); it != current.end(); ++it) { + SPObject* obj = *it; if (id == obj->getId()){ //XML Tree being used directly here while it shouldn't be. @@ -1317,21 +1312,20 @@ void DocumentProperties::editEmbeddedScript(){ DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_EMBEDDED_SCRIPT, _("Edit embedded script")); } } - current = g_slist_next(current); } } void DocumentProperties::populate_script_lists(){ _ExternalScriptsListStore->clear(); _EmbeddedScriptsListStore->clear(); - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); - if (current) { - SPObject *obj = reinterpret_cast(current->data); + std::set current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); + if (!current.empty()) { + SPObject *obj = *(current.begin()); g_assert(obj != NULL); _scripts_observer.set(obj->parent); } - while ( current ) { - SPObject* obj = reinterpret_cast(current->data); + for (std::set::const_iterator it = current.begin(); it != current.end(); ++it) { + SPObject* obj = *it; SPScript* script = dynamic_cast(obj); g_assert(script != NULL); if (script->xlinkhref) @@ -1344,8 +1338,6 @@ void DocumentProperties::populate_script_lists(){ Gtk::TreeModel::Row row = *(_EmbeddedScriptsListStore->append()); row[_EmbeddedScriptsListColumns.idColumn] = obj->getId(); } - - current = g_slist_next(current); } } diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 08a58291d..e3196bf59 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -1589,13 +1589,14 @@ void FilterEffectsDialog::FilterModifier::update_filters() { SPDesktop* desktop = _dialog.getDesktop(); SPDocument* document = desktop->getDocument(); - const GSList* filters = document->getResourceList("filter"); + + std::set filters = document->getResourceList( "filter" ); _model->clear(); - for(const GSList *l = filters; l; l = l->next) { + for (std::set::const_iterator it = filters.begin(); it != filters.end(); ++it) { Gtk::TreeModel::Row row = *_model->append(); - SPFilter* f = SP_FILTER(l->data); + SPFilter* f = SP_FILTER(*it); row[_columns.filter] = f; const gchar* lbl = f->label(); const gchar* id = f->getId(); diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp index 3f5e80f8d..f4152e556 100644 --- a/src/ui/dialog/layers.cpp +++ b/src/ui/dialog/layers.cpp @@ -1040,14 +1040,6 @@ void LayersPanel::setDesktop( SPDesktop* desktop ) _layersChanged(); } } -/* - GSList const *layers = _desktop->doc()->getResourceList( "layer" ); - g_message( "layers list starts at %p", layers ); - for ( GSList const *iter=layers ; iter ; iter = iter->next ) { - SPObject *layer=static_cast(iter->data); - g_message(" {%s} [%s]", layer->id, layer->label() ); - } -*/ deskTrack.setBase(desktop); } diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index 12b423602..46e045c14 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -266,12 +266,12 @@ void SvgFontsDialog::update_fonts() { SPDesktop* desktop = this->getDesktop(); SPDocument* document = desktop->getDocument(); - const GSList* fonts = document->getResourceList("font"); + std::set fonts = document->getResourceList( "fonts" ); _model->clear(); - for(const GSList *l = fonts; l; l = l->next) { + for (std::set::const_iterator it = fonts.begin(); it != fonts.end(); ++it) { Gtk::TreeModel::Row row = *_model->append(); - SPFont* f = SP_FONT(l->data); + SPFont* f = SP_FONT(*it); row[_columns.spfont] = f; row[_columns.svgfont] = new SvgFont(f); const gchar* lbl = f->label(); diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 72677c07e..ed1cd2079 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -171,9 +171,9 @@ static void editGradient( GtkMenuItem */*menuitem*/, gpointer /*user_data*/ ) SPDocument *doc = desktop ? desktop->doc() : 0; if (doc) { std::string targetName(bounceTarget->def.descr); - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); + std::set gradients = doc->getResourceList("gradient"); + for (std::set::const_iterator item = gradients.begin(); item != gradients.end(); ++item) { + SPGradient* grad = SP_GRADIENT(*item); if ( targetName == grad->getId() ) { editGradientImpl( desktop, grad ); break; @@ -192,10 +192,10 @@ void SwatchesPanelHook::convertGradient( GtkMenuItem * /*menuitem*/, gpointer us gint index = GPOINTER_TO_INT(userData); if ( doc && (index >= 0) && (static_cast(index) < popupItems.size()) ) { Glib::ustring targetName = popupItems[index]; + std::set gradients = doc->getResourceList("gradient"); + for (std::set::const_iterator item = gradients.begin(); item != gradients.end(); ++item) { + SPGradient* grad = SP_GRADIENT(*item); - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); if ( targetName == grad->getId() ) { grad->setSwatch(); DocumentUndo::done(doc, SP_VERB_CONTEXT_GRADIENT, @@ -326,10 +326,10 @@ gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, g SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt); if ( dtw && dtw->desktop ) { // Pick up all gradients with vectors - const GSList *gradients = (dtw->desktop->doc())->getResourceList("gradient"); + std::set gradients = (dtw->desktop->doc())->getResourceList("gradient"); gint index = 0; - for (const GSList *curr = gradients; curr; curr = curr->next) { - SPGradient* grad = SP_GRADIENT(curr->data); + for (std::set::const_iterator item = gradients.begin(); item != gradients.end(); ++item) { + SPGradient* grad = SP_GRADIENT(*item); if ( grad->hasStops() && !grad->isSwatch() ) { //gl = g_slist_prepend(gl, curr->data); processed = true; @@ -923,12 +923,11 @@ static void recalcSwatchContents(SPDocument* doc, std::map &gradMappings) { std::vector newList; - - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); + std::set gradients = doc->getResourceList("gradient"); + for (std::set::const_iterator item = gradients.begin(); item != gradients.end(); ++item) { + SPGradient* grad = SP_GRADIENT(*item); if ( grad->isSwatch() ) { - newList.push_back(SP_GRADIENT(item->data)); + newList.push_back(SP_GRADIENT(*item)); } } diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 0f719b40f..9855b59a3 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -1113,9 +1113,9 @@ sp_ui_drag_data_received(GtkWidget *widget, unsigned int b = color.getB(); SPGradient* matches = 0; - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); + std::set gradients = doc->getResourceList("gradient"); + for (std::set::const_iterator item = gradients.begin(); item != gradients.end(); ++item) { + SPGradient* grad = SP_GRADIENT(*item); if ( color.descr == grad->getId() ) { if ( grad->hasStops() ) { matches = grad; diff --git a/src/ui/widget/color-icc-selector.cpp b/src/ui/widget/color-icc-selector.cpp index 1c31ae33a..2fe4a0704 100644 --- a/src/ui/widget/color-icc-selector.cpp +++ b/src/ui/widget/color-icc-selector.cpp @@ -676,9 +676,9 @@ void ColorICCSelectorImpl::_profilesChanged(std::string const &name) gtk_combo_box_set_active(combo, 0); int index = 1; - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList("iccprofile"); - while (current) { - SPObject *obj = SP_OBJECT(current->data); + std::set current = SP_ACTIVE_DOCUMENT->getResourceList("iccprofile"); + for (std::set::const_iterator it = current.begin(); it != current.end(); ++it) { + SPObject *obj = *it; Inkscape::ColorProfile *prof = reinterpret_cast(obj); gtk_list_store_append(store, &iter); @@ -690,7 +690,6 @@ void ColorICCSelectorImpl::_profilesChanged(std::string const &name) } index++; - current = g_slist_next(current); } g_signal_handler_unblock(G_OBJECT(_profileSel), _profChangedID); diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index e19f56e48..71a19d962 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1813,9 +1813,9 @@ bool SPDesktopWidget::onFocusInEvent(GdkEventFocus*) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/options/bitmapautoreload/value", true)) { - GSList const *imageList = (desktop->doc())->getResourceList("image"); - for (GSList const *p = imageList; p; p = p->next) { - SPImage* image = SP_IMAGE(p->data); + std::set imageList = (desktop->doc())->getResourceList("image"); + for (std::set::const_iterator it = imageList.begin(); it != imageList.end(); ++it) { + SPImage* image = SP_IMAGE(*it); sp_image_refresh_if_outdated( image ); } } diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp index e8ad09cd4..858aa05db 100644 --- a/src/widgets/gradient-toolbar.cpp +++ b/src/widgets/gradient-toolbar.cpp @@ -139,19 +139,18 @@ gboolean gr_vector_list(GtkWidget *combo_box, SPDesktop *desktop, bool selection /* Clear old list, if there is any */ gtk_list_store_clear(store); - GSList *gl = NULL; - const GSList *gradients = document->getResourceList("gradient"); - for (const GSList *i = gradients; i != NULL; i = i->next) { - SPGradient *grad = SP_GRADIENT(i->data); + std::vector gl; + std::set gradients = document->getResourceList( "gradient" ); + for (std::set::const_iterator it = gradients.begin(); it != gradients.end(); ++it) { + SPGradient *grad = SP_GRADIENT(*it); if ( grad->hasStops() && !grad->isSolid() ) { - gl = g_slist_prepend(gl, i->data); + gl.push_back(*it); } } - gl = g_slist_reverse(gl); guint pos = 0; - if (!gl) { + if (gl.empty()) { // The document has no gradients gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, _("No gradient"), 1, NULL, 2, NULL, -1); @@ -180,9 +179,8 @@ gboolean gr_vector_list(GtkWidget *combo_box, SPDesktop *desktop, bool selection } guint idx = 0; - while (gl) { - SPGradient *gradient = SP_GRADIENT(gl->data); - gl = g_slist_remove(gl, gradient); + for (std::vector::const_iterator it = gl.begin(); it != gl.end(); ++it) { + SPGradient *gradient = SP_GRADIENT(*it); Glib::ustring label = gr_prepare_label(gradient); GdkPixbuf *pixb = sp_gradient_to_pixbuf(gradient, 64, 16); @@ -765,25 +763,25 @@ static gboolean update_stop_list( GtkWidget *stop_combo, SPGradient *gradient, S } /* Populate the combobox store */ - GSList *sl = NULL; + std::vector sl; if ( gradient->hasStops() ) { for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) { if (SP_IS_STOP(ochild)) { - sl = g_slist_append(sl, ochild); + sl.push_back(ochild); } } } - if (!sl) { + if (sl.empty()) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, _("No stops in gradient"), 1, NULL, 2, NULL, -1); sensitive = FALSE; } else { - for (; sl != NULL; sl = sl->next){ - if (SP_IS_STOP(sl->data)){ - SPStop *stop = SP_STOP(sl->data); - Inkscape::XML::Node *repr = reinterpret_cast(sl->data)->getRepr(); + for (std::vector::const_iterator it = sl.begin(); it != sl.end(); ++it) { + if (SP_IS_STOP(*it)){ + SPStop *stop = SP_STOP(*it); + Inkscape::XML::Node *repr = reinterpret_cast(*it)->getRepr(); Inkscape::UI::Widget::ColorPreview *cpv = Gtk::manage(new Inkscape::UI::Widget::ColorPreview(stop->get_rgba32())); GdkPixbuf *pb = cpv->toPixbuf(32, 16); Glib::ustring label = gr_ellipsize_text(repr->attribute("id"), 25); diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index 8e92f589a..35c1e4a8d 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -298,11 +298,11 @@ static void sp_gvs_rebuild_gui_full(SPGradientVectorSelector *gvs) /* Pick up all gradients with vectors */ GSList *gl = NULL; if (gvs->gr) { - const GSList *gradients = gvs->gr->document->getResourceList("gradient"); - for (const GSList *curr = gradients; curr; curr = curr->next) { - SPGradient* grad = SP_GRADIENT(curr->data); + std::set gradients = gvs->gr->document->getResourceList("gradient"); + for (std::set::const_iterator it = gradients.begin(); it != gradients.end(); ++it) { + SPGradient* grad = SP_GRADIENT(*it); if ( grad->hasStops() && (grad->isSwatch() == gvs->swatched) ) { - gl = g_slist_prepend(gl, curr->data); + gl = g_slist_prepend(gl, *it); } } } diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index d8d314834..602cad3c3 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -844,10 +844,10 @@ ink_pattern_list_get (SPDocument *source) return NULL; GSList *pl = NULL; - GSList const *patterns = source->getResourceList("pattern"); - for (GSList *l = const_cast(patterns); l != NULL; l = l->next) { - if (SP_PATTERN(l->data) == SP_PATTERN(l->data)->rootPattern()) { // only if this is a root pattern - pl = g_slist_prepend(pl, l->data); + std::set patterns = source->getResourceList("pattern"); + for (std::set::const_iterator it = patterns.begin(); it != patterns.end(); ++it) { + if (SP_PATTERN(*it) == SP_PATTERN(*it)->rootPattern()) { // only if this is a root pattern + pl = g_slist_prepend(pl, *it); } } diff --git a/src/xml/rebase-hrefs.cpp b/src/xml/rebase-hrefs.cpp index 9d4f4f9fc..2bcae5d81 100644 --- a/src/xml/rebase-hrefs.cpp +++ b/src/xml/rebase-hrefs.cpp @@ -220,9 +220,9 @@ void Inkscape::XML::rebase_hrefs(SPDocument *const doc, gchar const *const new_b * * Note also that Inkscape only supports fragment hrefs (href="#pattern257") for many of these * cases. */ - GSList const *images = doc->getResourceList("image"); - for (GSList const *l = images; l != NULL; l = l->next) { - Inkscape::XML::Node *ir = static_cast(l->data)->getRepr(); + std::set images = doc->getResourceList("image"); + for (std::set::const_iterator it = images.begin(); it != images.end(); ++it) { + Inkscape::XML::Node *ir = (*it)->getRepr(); std::string uri; { -- cgit v1.2.3 From 5e6d4ac718a806bff5363a1b5ff06ac8160897c3 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Tue, 8 Dec 2015 01:07:44 +0100 Subject: fix crash (oops) (bzr r14504.1.8) --- src/document.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 8c160be38..fcbe5a809 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1527,7 +1527,7 @@ bool SPDocument::addResource(gchar const *key, SPObject *object) if ( !object->cloned ) { std::set rlist = priv->resources[key]; g_return_val_if_fail(rlist.find(object) == rlist.end(), false); - rlist.insert(object); + priv->resources[key].insert(object); GQuark q = g_quark_from_string(key); @@ -1559,7 +1559,7 @@ bool SPDocument::removeResource(gchar const *key, SPObject *object) std::set rlist = priv->resources[key]; g_return_val_if_fail(!rlist.empty(), false); g_return_val_if_fail(rlist.find(object) != rlist.end(), false); - rlist.erase(object); + priv->resources[key].erase(object); GQuark q = g_quark_from_string(key); priv->resources_changed_signals[q].emit(); -- cgit v1.2.3 From 98a465905236cf97e2b3d163ff3df4ee43635038 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 8 Dec 2015 13:56:49 +0100 Subject: Fix incorrect variable type in SPILength constructor. (bzr r14513) --- src/style-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/style-internal.h b/src/style-internal.h index 889292454..33096f257 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -342,7 +342,7 @@ public: computed(0) {} - SPILength( Glib::ustring const &name, unsigned value = 0 ) + SPILength( Glib::ustring const &name, float value = 0 ) : SPIBase( name ), unit(SP_CSS_UNIT_NONE), value(value), -- cgit v1.2.3 From f16ffd203a902204895281423322625d86be6144 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 8 Dec 2015 14:09:52 +0100 Subject: Fix incorrect variable type in SPILengthOrNormal constructor. (bzr r14514) --- src/style-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/style-internal.h b/src/style-internal.h index 33096f257..767552784 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -401,7 +401,7 @@ public: normal(true) {} - SPILengthOrNormal( Glib::ustring const &name, unsigned value = 0 ) + SPILengthOrNormal( Glib::ustring const &name, float value = 0 ) : SPILength( name, value ), normal(true) {} -- cgit v1.2.3 From 5ffdf79a6ed7d33ca03d7da3d78cf75389486477 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 8 Dec 2015 14:18:15 +0100 Subject: add negative values to bend and pattern along path whith knot (bzr r14516) --- src/live_effects/lpe-bendpath.cpp | 20 +++++++++++++++++--- src/live_effects/lpe-patternalongpath.cpp | 23 +++++++++++++++++++---- 2 files changed, 36 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 5c20a7f9e..874e23c4c 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -192,7 +192,21 @@ KnotHolderEntityWidthBendPath::knot_set(Geom::Point const &p, Geom::Point const& Geom::Point const s = snap_knot_position(p, state); Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); - lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); + Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in.curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints(ptA, (*cubic)[1]); + } + ray.setAngle(ray.angle() + Geom::deg_to_rad(90)); + Geom::Point knot_pos = this->knot->pos * item->i2dt_affine().inverse(); + Geom::Coord nearest_to_ray = ray.nearestTime(knot_pos); + if(nearest_to_ray == 0){ + lpe->prop_scale.param_set_value(-Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } else { + lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); } @@ -211,8 +225,8 @@ KnotHolderEntityWidthBendPath::knot_get() const if (cubic) { ray.setPoints(ptA,(*cubic)[1]); } - Geom::Angle first_curve_angle = ray.transformed(Geom::Rotate(Geom::deg_to_rad(90))).angle(); - Geom::Point result_point = Geom::Point::polar(first_curve_angle, (lpe->original_height * lpe->prop_scale)/2.0) + ptA; + ray.setAngle(ray.angle() + Geom::deg_to_rad(90)); + Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA; bp_helper_path.clear(); Geom::Path hp(result_point); diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index ed377e7f9..706091be9 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -291,7 +291,22 @@ KnotHolderEntityWidthPatternAlongPath::knot_set(Geom::Point const &p, Geom::Poin if (sp_shape) { Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); - lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); + Geom::Point B = path_in->pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in->curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints(ptA, (*cubic)[1]); + } + ray.setAngle(ray.angle() + Geom::deg_to_rad(90)); + Geom::Point knot_pos = this->knot->pos * item->i2dt_affine().inverse(); + Geom::Coord nearest_to_ray = ray.nearestTime(knot_pos); + if(nearest_to_ray == 0){ + lpe->prop_scale.param_set_value(-Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } else { + lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } + } sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); } @@ -310,10 +325,10 @@ KnotHolderEntityWidthPatternAlongPath::knot_get() const Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); Geom::Ray ray(ptA, B); if (cubic) { - ray.setPoints((*cubic)[1], ptA); + ray.setPoints(ptA, (*cubic)[1]); } - Geom::Angle first_curve_angle = ray.transformed(Geom::Rotate(Geom::deg_to_rad(90))).angle(); - Geom::Point result_point = Geom::Point::polar(first_curve_angle, (lpe->original_height * lpe->prop_scale)/2.0) + ptA; + ray.setAngle(ray.angle() + Geom::deg_to_rad(90)); + Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA; pap_helper_path.clear(); Geom::Path hp(result_point); -- cgit v1.2.3 From 689ac8e0dc1edc3e53c88daa44fae0f8f1857346 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 8 Dec 2015 15:24:13 +0100 Subject: Fix return value for SPIEnumBits::write(). (bzr r14517) --- src/style-internal.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index c117a97f9..b425a1c80 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -709,7 +709,8 @@ SPIEnumBits::write( guint const flags, SPIBase const *const base) const { unsigned j = 1; for (unsigned i = 0; enums[i].key; ++i) { if (j & this->value ) { - return_string += enums[i].value + " "; + return_string += enums[i].key; + return_string += " "; } j *= 2; } -- cgit v1.2.3 From 59550e0f297b3b75beb182260b9ecf3a2d876b7e Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Tue, 8 Dec 2015 20:48:40 +0100 Subject: fix warning (class was a struct) (bzr r14504.1.10) --- src/gradient-drag.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gradient-drag.h b/src/gradient-drag.h index 72ec62572..b07f748a7 100644 --- a/src/gradient-drag.h +++ b/src/gradient-drag.h @@ -124,7 +124,7 @@ private: sigc::connection _ungrabbed_connection; }; -class SPCtrlLine; +struct SPCtrlLine; /** This is the root class of the gradient dragging machinery. It holds lists of GrDraggers and of lines (simple canvas items). It also remembers one of the draggers as selected. -- cgit v1.2.3 From 654133de49a3616dded19d6a4c05f020e4444110 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Tue, 8 Dec 2015 22:36:17 +0100 Subject: 0-sized arrays are supposed to be forbidden (bzr r14504.1.12) --- src/widgets/mesh-toolbar.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp index 9937b23ed..3643ce00c 100644 --- a/src/widgets/mesh-toolbar.cpp +++ b/src/widgets/mesh-toolbar.cpp @@ -433,14 +433,14 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj /* Number of mesh rows */ { - gchar const* labels[] = {}; + gchar const** labels = NULL; gdouble values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; eact = create_adjustment_action( "MeshRowAction", _("Rows"), _("Rows:"), _("Number of rows in new mesh"), "/tools/mesh/mesh_rows", 1, GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, 1, 20, 1, 1, - labels, values, G_N_ELEMENTS(labels), + labels, values, 0, ms_row_changed, NULL /*unit tracker*/, 1.0, 0 ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); @@ -449,14 +449,14 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj /* Number of mesh columns */ { - gchar const* labels[] = {}; + gchar const** labels = NULL; gdouble values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; eact = create_adjustment_action( "MeshColumnAction", _("Columns"), _("Columns:"), _("Number of columns in new mesh"), "/tools/mesh/mesh_cols", 1, GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, 1, 20, 1, 1, - labels, values, G_N_ELEMENTS(labels), + labels, values, 0, ms_col_changed, NULL /*unit tracker*/, 1.0, 0 ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); -- cgit v1.2.3 From 402e0259b8310d25a1f51cc6a4c69f496f73591e Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Tue, 8 Dec 2015 22:36:21 +0100 Subject: cppification: GSList replaced by vectors (connectors) (bzr r14504.1.13) --- src/conn-avoid-ref.cpp | 26 ++++++++++++-------------- src/conn-avoid-ref.h | 7 +++---- src/graphlayout.cpp | 9 +++------ src/widgets/connector-toolbar.cpp | 10 ++++------ 4 files changed, 22 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/conn-avoid-ref.cpp b/src/conn-avoid-ref.cpp index 4c9665fa0..d43d000a7 100644 --- a/src/conn-avoid-ref.cpp +++ b/src/conn-avoid-ref.cpp @@ -139,9 +139,9 @@ void SPAvoidRef::handleSettingChange(void) } -GSList *SPAvoidRef::getAttachedShapes(const unsigned int type) +std::vector SPAvoidRef::getAttachedShapes(const unsigned int type) { - GSList *list = NULL; + std::vector list; Avoid::IntList shapes; GQuark shapeId = g_quark_from_string(item->getId()); @@ -157,15 +157,15 @@ GSList *SPAvoidRef::getAttachedShapes(const unsigned int type) continue; } SPItem *shapeItem = SP_ITEM(obj); - list = g_slist_prepend(list, shapeItem); + list.push_back(shapeItem); } return list; } -GSList *SPAvoidRef::getAttachedConnectors(const unsigned int type) +std::vector SPAvoidRef::getAttachedConnectors(const unsigned int type) { - GSList *list = NULL; + std::vector list; Avoid::IntList conns; GQuark shapeId = g_quark_from_string(item->getId()); @@ -181,7 +181,7 @@ GSList *SPAvoidRef::getAttachedConnectors(const unsigned int type) continue; } SPItem *connItem = SP_ITEM(obj); - list = g_slist_prepend(list, connItem); + list.push_back(connItem); } return list; } @@ -331,7 +331,7 @@ static Avoid::Polygon avoid_item_poly(SPItem const *item) } -GSList *get_avoided_items(GSList *list, SPObject *from, SPDesktop *desktop, +std::vector get_avoided_items(std::vector &list, SPObject *from, SPDesktop *desktop, bool initialised) { for (SPObject *child = from->firstChild() ; child != NULL; child = child->next ) { @@ -342,7 +342,7 @@ GSList *get_avoided_items(GSList *list, SPObject *from, SPDesktop *desktop, (!initialised || SP_ITEM(child)->avoidRef->shapeRef) ) { - list = g_slist_prepend (list, SP_ITEM(child)); + list.push_back(SP_ITEM(child)); } if (SP_IS_ITEM(child) && desktop->isLayer(SP_ITEM(child))) { @@ -376,17 +376,15 @@ void init_avoided_shape_geometry(SPDesktop *desktop) DocumentUndo::setUndoSensitive(document, false); bool initialised = false; - GSList *items = get_avoided_items(NULL, desktop->currentRoot(), desktop, + std::vector tmp; + std::vector items = get_avoided_items(tmp, desktop->currentRoot(), desktop, initialised); - for ( GSList const *iter = items ; iter != NULL ; iter = iter->next ) { - SPItem *item = reinterpret_cast(iter->data); + for (std::vector::const_iterator iter = items.begin(); iter != items.end(); ++iter) { + SPItem *item = *iter; item->avoidRef->handleSettingChange(); } - if (items) { - g_slist_free(items); - } DocumentUndo::setUndoSensitive(document, saved); } diff --git a/src/conn-avoid-ref.h b/src/conn-avoid-ref.h index e9e12118f..2c7da9aae 100644 --- a/src/conn-avoid-ref.h +++ b/src/conn-avoid-ref.h @@ -20,7 +20,6 @@ class SPDesktop; class SPObject; class SPItem; -typedef struct _GSList GSList; namespace Avoid { class ShapeRef; } class SPAvoidRef { @@ -41,8 +40,8 @@ public: // Avoid::runningTo // Avoid::runningFrom // Avoid::runningToAndFrom - GSList *getAttachedShapes(const unsigned int type); - GSList *getAttachedConnectors(const unsigned int type); + std::vector getAttachedShapes(const unsigned int type); + std::vector getAttachedConnectors(const unsigned int type); private: SPItem *item; @@ -55,7 +54,7 @@ private: sigc::connection _transformed_connection; }; -extern GSList *get_avoided_items(GSList *list, SPObject *from, +extern std::vector get_avoided_items(std::vector &list, SPObject *from, SPDesktop *desktop, bool initialised = true); extern void avoid_item_move(Geom::Affine const *mp, SPItem *moved_item); extern void init_avoided_shape_geometry(SPDesktop *desktop); diff --git a/src/graphlayout.cpp b/src/graphlayout.cpp index 9b67ba0b5..39ffb6cc7 100644 --- a/src/graphlayout.cpp +++ b/src/graphlayout.cpp @@ -106,7 +106,6 @@ void graphlayout(std::vector const &items) { return; } - using Inkscape::Util::GSListIterator; list selected; filterConnectors(items,selected); if (selected.empty()) return; @@ -164,10 +163,11 @@ void graphlayout(std::vector const &items) { continue; } unsigned u=i_iter->second; - GSList *nlist=iu->avoidRef->getAttachedConnectors(Avoid::runningFrom); + std::vector nlist=iu->avoidRef->getAttachedConnectors(Avoid::runningFrom); list connectors; - connectors.insert >(connectors.end(),nlist,NULL); + connectors.insert(connectors.end(), nlist.begin(), nlist.end()); + for (list::iterator j(connectors.begin()); j != connectors.end(); ++j) { @@ -203,9 +203,6 @@ void graphlayout(std::vector const &items) { } } } - if(nlist) { - g_slist_free(nlist); - } } const unsigned E = es.size(); double eweights[E]; diff --git a/src/widgets/connector-toolbar.cpp b/src/widgets/connector-toolbar.cpp index 8cc254bd2..733fb34e8 100644 --- a/src/widgets/connector-toolbar.cpp +++ b/src/widgets/connector-toolbar.cpp @@ -200,17 +200,15 @@ static void connector_spacing_changed(GtkAdjustment *adj, GObject* tbl) desktop->namedview->updateRepr(); bool modmade = false; - GSList *items = get_avoided_items(NULL, desktop->currentRoot(), desktop); - for ( GSList const *iter = items ; iter != NULL ; iter = iter->next ) { - SPItem *item = reinterpret_cast(iter->data); + std::vector items; + items = get_avoided_items(items, desktop->currentRoot(), desktop); + for (std::vector::const_iterator iter = items.begin(); iter != items.end(); ++iter ) { + SPItem *item = *iter; Geom::Affine m = Geom::identity(); avoid_item_move(&m, item); modmade = true; } - if (items) { - g_slist_free(items); - } if(modmade) { DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, _("Change connector spacing")); -- cgit v1.2.3 From cfd295134c9804bf98fba835361000a891c2fa56 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Tue, 8 Dec 2015 23:18:50 +0100 Subject: cppification: GSList replaced by vectors (undo/redo) (bzr r14504.1.14) --- src/desktop-style.h | 1 - src/document-private.h | 6 ++--- src/document-undo.cpp | 70 ++++++++++++++++++++++---------------------------- src/document.cpp | 25 +++++------------- src/document.h | 2 +- 5 files changed, 41 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/desktop-style.h b/src/desktop-style.h index b9199b615..bf05adadf 100644 --- a/src/desktop-style.h +++ b/src/desktop-style.h @@ -19,7 +19,6 @@ class SPDesktop; class SPObject; class SPItem; class SPStyle; -typedef struct _GSList GSList; namespace Inkscape { namespace XML { class Node; diff --git a/src/document-private.h b/src/document-private.h index a4a2abd77..55c844ecc 100644 --- a/src/document-private.h +++ b/src/document-private.h @@ -53,9 +53,7 @@ struct SPDocumentPrivate { IDChangedSignalMap id_changed_signals; /* Resources */ - /* It is GHashTable of GSLists */ std::map > resources; - //GHashTable *resources; ResourcesChangedSignalMap resources_changed_signals; sigc::signal destroySignal; @@ -70,8 +68,8 @@ struct SPDocumentPrivate { bool sensitive; /* If we save actions to undo stack */ Inkscape::XML::Event * partial; /* partial undo log when interrupted */ int history_size; - GSList * undo; /* Undo stack of reprs */ - GSList * redo; /* Redo stack of reprs */ + std::vector undo; /* Undo stack of reprs */ + std::vector redo; /* Redo stack of reprs */ /* Undo listener */ Inkscape::CompositeUndoStackObserver undoStackObservers; diff --git a/src/document-undo.cpp b/src/document-undo.cpp index 59e060cd5..eb0ac7707 100644 --- a/src/document-undo.cpp +++ b/src/document-undo.cpp @@ -162,12 +162,12 @@ void Inkscape::DocumentUndo::maybeDone(SPDocument *doc, const gchar *key, const return; } - if (key && !doc->actionkey.empty() && (doc->actionkey == key) && doc->priv->undo) { - ((Inkscape::Event *)doc->priv->undo->data)->event = - sp_repr_coalesce_log (((Inkscape::Event *)doc->priv->undo->data)->event, log); + if (key && !doc->actionkey.empty() && (doc->actionkey == key) && !doc->priv->undo.empty()) { + (doc->priv->undo.back())->event = + sp_repr_coalesce_log ((doc->priv->undo.back())->event, log); } else { Inkscape::Event *event = new Inkscape::Event(log, event_type, event_description); - doc->priv->undo = g_slist_prepend (doc->priv->undo, event); + doc->priv->undo.push_back(event); doc->priv->history_size++; doc->priv->undoStackObservers.notifyUndoCommitEvent(event); } @@ -211,7 +211,7 @@ static void finish_incomplete_transaction(SPDocument &doc) { priv.partial = sp_repr_coalesce_log(priv.partial, log); sp_repr_debug_print_log(priv.partial); Inkscape::Event *event = new Inkscape::Event(priv.partial); - priv.undo = g_slist_prepend(priv.undo, event); + priv.undo.push_back(event); priv.undoStackObservers.notifyUndoCommitEvent(event); priv.partial = NULL; } @@ -227,8 +227,8 @@ static void perform_document_update(SPDocument &doc) { sp_repr_debug_print_log(update_log); //Coalesce the update changes with the last action performed by user - Inkscape::Event* undo_stack_top = (Inkscape::Event *)doc.priv->undo->data; - if (undo_stack_top) { + if (!doc.priv->undo.empty()) { + Inkscape::Event* undo_stack_top = doc.priv->undo.back(); undo_stack_top->event = sp_repr_coalesce_log(undo_stack_top->event, update_log); } else { sp_repr_free_log(update_log); @@ -256,13 +256,13 @@ gboolean Inkscape::DocumentUndo::undo(SPDocument *doc) finish_incomplete_transaction(*doc); - if (doc->priv->undo) { - Inkscape::Event *log=(Inkscape::Event *)doc->priv->undo->data; - doc->priv->undo = g_slist_remove (doc->priv->undo, log); + if (! doc->priv->undo.empty()) { + Inkscape::Event *log = doc->priv->undo.back(); + doc->priv->undo.pop_back(); sp_repr_undo_log (log->event); perform_document_update(*doc); - doc->priv->redo = g_slist_prepend (doc->priv->redo, log); + doc->priv->redo.push_back(log); doc->setModifiedSinceSave(); doc->priv->undoStackObservers.notifyUndoEvent(log); @@ -303,11 +303,11 @@ gboolean Inkscape::DocumentUndo::redo(SPDocument *doc) finish_incomplete_transaction(*doc); - if (doc->priv->redo) { - Inkscape::Event *log=(Inkscape::Event *)doc->priv->redo->data; - doc->priv->redo = g_slist_remove (doc->priv->redo, log); + if (! doc->priv->redo.empty()) { + Inkscape::Event *log = doc->priv->redo.back(); + doc->priv->redo.pop_back(); sp_repr_replay_log (log->event); - doc->priv->undo = g_slist_prepend (doc->priv->undo, log); + doc->priv->undo.push_back(log); doc->setModifiedSinceSave(); doc->priv->undoStackObservers.notifyRedoEvent(log); @@ -330,37 +330,29 @@ gboolean Inkscape::DocumentUndo::redo(SPDocument *doc) void Inkscape::DocumentUndo::clearUndo(SPDocument *doc) { - if (doc->priv->undo) - doc->priv->undoStackObservers.notifyClearUndoEvent(); - - while (doc->priv->undo) { - GSList *current; - - current = doc->priv->undo; - doc->priv->undo = current->next; - doc->priv->history_size--; - - delete ((Inkscape::Event *) current->data); - g_slist_free_1 (current); - } + if (! doc->priv->undo.empty()) + doc->priv->undoStackObservers.notifyClearUndoEvent(); + while (! doc->priv->undo.empty()) { + Inkscape::Event *e = doc->priv->undo.back(); + doc->priv->undo.pop_back(); + delete e; + doc->priv->history_size--; + } } void Inkscape::DocumentUndo::clearRedo(SPDocument *doc) { - if (doc->priv->redo) + if (!doc->priv->redo.empty()) doc->priv->undoStackObservers.notifyClearRedoEvent(); - while (doc->priv->redo) { - GSList *current; - - current = doc->priv->redo; - doc->priv->redo = current->next; - doc->priv->history_size--; - - delete ((Inkscape::Event *) current->data); - g_slist_free_1 (current); - } + while (! doc->priv->redo.empty()) { + Inkscape::Event *e = doc->priv->redo.back(); + doc->priv->redo.pop_back(); + delete e; + doc->priv->history_size--; + } } + /* Local Variables: mode:c++ diff --git a/src/document.cpp b/src/document.cpp index fcbe5a809..05e165965 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -81,7 +81,7 @@ using Inkscape::Util::unit_table; static gint sp_document_idle_handler(gpointer data); static gint sp_document_rerouting_handler(gpointer data); -gboolean sp_document_resource_list_free(gpointer key, gpointer value, gpointer data); +//gboolean sp_document_resource_list_free(gpointer key, gpointer value, gpointer data); static gint doc_count = 0; static gint doc_mem_count = 0; @@ -105,7 +105,6 @@ SPDocument::SPDocument() : rerouting_handler_id(0), profileManager(NULL), // deferred until after other initialization router(new Avoid::Router(Avoid::PolyLineRouting|Avoid::OrthogonalRouting)), - _collection_queue(NULL), oldSignalsConnected(false), current_persp3d(NULL), current_persp3d_impl(NULL), @@ -122,8 +121,6 @@ SPDocument::SPDocument() : p->sensitive = false; p->partial = NULL; p->history_size = 0; - p->undo = NULL; - p->redo = NULL; p->seeking = false; priv = p; @@ -283,19 +280,18 @@ void SPDocument::queueForOrphanCollection(SPObject *object) { g_return_if_fail(object->document == this); sp_object_ref(object, NULL); - _collection_queue = g_slist_prepend(_collection_queue, object); + _collection_queue.push_back(object); } void SPDocument::collectOrphans() { - while (_collection_queue) { - GSList *objects=_collection_queue; - _collection_queue = NULL; - for ( GSList *iter=objects ; iter ; iter = iter->next ) { - SPObject *object=reinterpret_cast(iter->data); + while (!_collection_queue.empty()) { + std::vector objects(_collection_queue); + _collection_queue.clear(); + for (std::vector::const_iterator iter = objects.begin(); iter != objects.end(); ++iter) { + SPObject *object = *iter; object->collectOrphan(); sp_object_unref(object, NULL); } - g_slist_free(objects); } } @@ -1588,13 +1584,6 @@ sigc::connection SPDocument::connectResourcesChanged(gchar const *key, /* Helpers */ -gboolean -sp_document_resource_list_free(gpointer /*key*/, gpointer value, gpointer /*data*/) -{ - g_slist_free((GSList *) value); - return TRUE; -} - static unsigned int count_objects_recursive(SPObject *obj, unsigned int count) { count++; // obj itself diff --git a/src/document.h b/src/document.h index c7d3abf90..cf8ebc3cb 100644 --- a/src/document.h +++ b/src/document.h @@ -122,7 +122,7 @@ public: // Instance of the connector router Avoid::Router *router; - GSList *_collection_queue; + std::vector _collection_queue; bool oldSignalsConnected; -- cgit v1.2.3 From b6a5a7b59a78a35128633bd7b7a070ebeb263505 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Tue, 8 Dec 2015 23:34:02 +0100 Subject: finally removed all GSList from main folder .h files (bzr r14504.1.15) --- src/desktop.cpp | 6 ------ src/graphlayout.h | 1 - src/path-chemistry.h | 1 - src/removeoverlap.h | 2 -- src/selection-chemistry.h | 2 -- src/seltrans.h | 1 - src/snap.h | 1 - src/sp-clippath.h | 1 - src/sp-guide.h | 1 - src/sp-item-group.h | 1 - src/sp-object.h | 1 - src/sp-switch.h | 1 - src/unclump.h | 1 - src/vanishing-point.h | 1 - 14 files changed, 21 deletions(-) (limited to 'src') diff --git a/src/desktop.cpp b/src/desktop.cpp index 491313234..0aac46e8d 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -1704,12 +1704,6 @@ static void _reconstruction_start(SPDesktop * desktop) desktop->_reconstruction_old_layer_id = desktop->currentLayer()->getId() ? desktop->currentLayer()->getId() : ""; desktop->layers->reset(); - /* - GSList const * selection_objs = desktop->selection->list(); - for (; selection_objs != NULL; selection_objs = selection_objs->next) { - - } - */ desktop->selection->clear(); } diff --git a/src/graphlayout.h b/src/graphlayout.h index 9794dd6b5..dfef45359 100644 --- a/src/graphlayout.h +++ b/src/graphlayout.h @@ -16,7 +16,6 @@ #include -typedef struct _GSList GSList; class SPItem; void graphlayout(std::vector const &items); diff --git a/src/path-chemistry.h b/src/path-chemistry.h index f454167a9..35ab923c0 100644 --- a/src/path-chemistry.h +++ b/src/path-chemistry.h @@ -24,7 +24,6 @@ class Node; } // namespace Inkscape typedef unsigned int guint32; -typedef struct _GSList GSList; void sp_selected_path_combine (SPDesktop *desktop); void sp_selected_path_break_apart (SPDesktop *desktop); diff --git a/src/removeoverlap.h b/src/removeoverlap.h index d873663d1..cc0c7d9b7 100644 --- a/src/removeoverlap.h +++ b/src/removeoverlap.h @@ -13,8 +13,6 @@ #ifndef SEEN_REMOVEOVERLAP_H #define SEEN_REMOVEOVERLAP_H -typedef struct _GSList GSList; - void removeoverlap(std::vector const &items, double xGap, double yGap); #endif // SEEN_REMOVEOVERLAP_H diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h index 5bcc5b1ea..4bfa2c0aa 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -22,7 +22,6 @@ class SPCSSAttr; class SPDesktop; -typedef struct _GSList GSList; namespace Inkscape { @@ -75,7 +74,6 @@ void sp_selection_unsymbol(SPDesktop *desktop); void sp_selection_tile(SPDesktop *desktop, bool apply = true); void sp_selection_untile(SPDesktop *desktop); -//void sp_selection_group_impl(GSList const *reprs_to_group, Inkscape::XML::Node *group, Inkscape::XML::Document *xml_doc, SPDocument *doc); void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop); void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop); diff --git a/src/seltrans.h b/src/seltrans.h index 26c2e9cd9..f756cc77a 100644 --- a/src/seltrans.h +++ b/src/seltrans.h @@ -34,7 +34,6 @@ class SPDesktop; struct SPCanvasItem; struct SPCtrlLine; struct SPSelTransHandle; -typedef struct _GSList GSList; namespace Inkscape { diff --git a/src/snap.h b/src/snap.h index c4dd67b4c..41d21b1b2 100644 --- a/src/snap.h +++ b/src/snap.h @@ -39,7 +39,6 @@ namespace Inkscape { class PureTransform; } -typedef struct _GSList GSList; /** * Class to coordinate snapping operations. diff --git a/src/sp-clippath.h b/src/sp-clippath.h index 8abe97f3f..7b1c83356 100644 --- a/src/sp-clippath.h +++ b/src/sp-clippath.h @@ -19,7 +19,6 @@ #define SP_IS_CLIPPATH(obj) (dynamic_cast((SPObject*)obj) != NULL) struct SPClipPathView; -typedef struct _GSList GSList; #include diff --git a/src/sp-guide.h b/src/sp-guide.h index 720c83d36..25a0e5af8 100644 --- a/src/sp-guide.h +++ b/src/sp-guide.h @@ -22,7 +22,6 @@ typedef unsigned int guint32; extern "C" { typedef void (*GCallback) (void); - typedef struct _GSList GSList; } class SPDesktop; diff --git a/src/sp-item-group.h b/src/sp-item-group.h index fc0b6382f..0c74c3dc3 100644 --- a/src/sp-item-group.h +++ b/src/sp-item-group.h @@ -25,7 +25,6 @@ namespace Inkscape { class Drawing; class DrawingItem; -typedef struct _GSList GSList; } // namespace Inkscape diff --git a/src/sp-object.h b/src/sp-object.h index 7bc02fad5..70d3e5df5 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -59,7 +59,6 @@ class SPObject; class SPCSSAttr; class SPStyle; -typedef struct _GSList GSList; namespace Inkscape { namespace XML { diff --git a/src/sp-switch.h b/src/sp-switch.h index 7152e1b82..57ce8b236 100644 --- a/src/sp-switch.h +++ b/src/sp-switch.h @@ -17,7 +17,6 @@ #include "sp-item-group.h" -typedef struct _GSList GSList; #define SP_SWITCH(obj) (dynamic_cast((SPObject*)obj)) #define SP_IS_SWITCH(obj) (dynamic_cast((SPObject*)obj) != NULL) diff --git a/src/unclump.h b/src/unclump.h index 461e99d0b..c6948f320 100644 --- a/src/unclump.h +++ b/src/unclump.h @@ -11,7 +11,6 @@ #ifndef SEEN_DIALOGS_UNCLUMP_H #define SEEN_DIALOGS_UNCLUMP_H -typedef struct _GSList GSList; void unclump(std::vector &items); diff --git a/src/vanishing-point.h b/src/vanishing-point.h index e967096e5..28da8e7fa 100644 --- a/src/vanishing-point.h +++ b/src/vanishing-point.h @@ -193,7 +193,6 @@ public: inline bool hasEmptySelection() { return this->selection->isEmpty(); } bool allBoxesAreSelected (VPDragger *dragger); - GSList * selectedBoxesWithVPinDragger (VPDragger *dragger); // FIXME: Should this be private? (It's the case with the corresponding function in gradient-drag.h) // But vp_knot_grabbed_handler -- cgit v1.2.3 From 1c18349cc106bb55c7bca12fd572fb7b899ff225 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Wed, 9 Dec 2015 01:45:44 +0100 Subject: replaced remaining GHashTable with std::map (bzr r14504.1.16) --- src/attributes.cpp | 20 ++++++-------------- src/document-private.h | 4 ---- src/extension/internal/cairo-render-context.cpp | 14 +++++++------- src/extension/internal/cairo-render-context.h | 2 +- src/xml/repr-io.cpp | 18 +++++++----------- 5 files changed, 21 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index ad6a51c88..e8620a498 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -536,21 +536,13 @@ static SPStyleProp const props[] = { unsigned sp_attribute_lookup(gchar const *key) { - static GHashTable *propdict = NULL; - - if (!propdict) { - unsigned int i; - propdict = g_hash_table_new(g_str_hash, g_str_equal); - for (i = 1; i < n_attrs; i++) { - g_assert(props[i].code == static_cast< gint >(i) ); - // If this g_assert fails, then the sort order of SPAttributeEnum does not match the order in props[]! - g_hash_table_insert(propdict, - const_cast(static_cast(props[i].name)), - GINT_TO_POINTER(props[i].code)); - } + for (unsigned int i = 1; i < n_attrs; i++) { + g_assert(props[i].code == static_cast< gint >(i) ); + // If this g_assert fails, then the sort order of SPAttributeEnum does not match the order in props[]! + if(g_str_equal(const_cast(static_cast(props[i].name)), key)) + return GPOINTER_TO_UINT(GINT_TO_POINTER(props[i].code)); } - - return GPOINTER_TO_UINT(g_hash_table_lookup(propdict, key)); + return SP_ATTR_INVALID; } unsigned char const * diff --git a/src/document-private.h b/src/document-private.h index 55c844ecc..eaed0020e 100644 --- a/src/document-private.h +++ b/src/document-private.h @@ -36,16 +36,12 @@ class Event; } } -typedef struct _GHashTable GHashTable; - struct SPDocumentPrivate { typedef std::map IDChangedSignalMap; typedef std::map ResourcesChangedSignalMap; std::map iddef; std::map reprdef; - //GHashTable *iddef; /**< Dictionary of id -> SPObject mappings */ - //GHashTable *reprdef; /**< Dictionary of Inkscape::XML::Node -> SPObject mappings */ unsigned long serial; diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 97b84606f..8b7a22f21 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -130,14 +130,12 @@ CairoRenderContext::CairoRenderContext(CairoRenderer *parent) : _clip_mode(CLIP_MODE_MASK), _omittext_state(EMPTY) { - font_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, font_data_free); } CairoRenderContext::~CairoRenderContext(void) { - if(font_table != NULL) { - g_hash_table_remove_all(font_table); - } + for (std::map::const_iterator iter = font_table.begin(); iter != font_table.end(); ++iter) + font_data_free(iter->second); if (_cr) cairo_destroy(_cr); if (_surface) cairo_surface_destroy(_surface); @@ -1645,7 +1643,9 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const &font_ma // create a cairo_font_face from PangoFont double size = style->font_size.computed; /// \fixme why is this variable never used? gpointer fonthash = (gpointer)font; - cairo_font_face_t *font_face = (cairo_font_face_t *)g_hash_table_lookup(font_table, fonthash); + cairo_font_face_t *font_face = NULL; + if(font_table.find(fonthash)!=font_table.end()) + font_face = font_table[fonthash]; FcPattern *fc_pattern = NULL; @@ -1660,7 +1660,7 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const &font_ma if(font_face == NULL) { font_face = cairo_win32_font_face_create_for_logfontw(&lfw); - g_hash_table_insert(font_table, fonthash, font_face); + font_table[fonthash] = font_face; } # endif #else @@ -1669,7 +1669,7 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const &font_ma fc_pattern = fc_font->font_pattern; if(font_face == NULL) { font_face = cairo_ft_font_face_create_for_pattern(fc_pattern); - g_hash_table_insert(font_table, fonthash, font_face); + font_table[fonthash] = font_face; } # endif #endif diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index 57d155b60..b3ab3655a 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -219,7 +219,7 @@ protected: void _prepareRenderGraphic(void); void _prepareRenderText(void); - GHashTable *font_table; + std::map font_table; static void font_data_free(gpointer data); CairoRenderState *_createState(void); diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index a4146f215..4a6f59b43 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -38,6 +38,7 @@ #include "preferences.h" #include +#include using Inkscape::IO::Writer; using Inkscape::Util::List; @@ -50,8 +51,8 @@ using Inkscape::XML::calc_abs_doc_base; using Inkscape::XML::rebase_href_attrs; Document *sp_repr_do_read (xmlDocPtr doc, const gchar *default_ns); -static Node *sp_repr_svg_read_node (Document *xml_doc, xmlNodePtr node, const gchar *default_ns, GHashTable *prefix_map); -static gint sp_repr_qualified_name (gchar *p, gint len, xmlNsPtr ns, const xmlChar *name, const gchar *default_ns, GHashTable *prefix_map); +static Node *sp_repr_svg_read_node (Document *xml_doc, xmlNodePtr node, const gchar *default_ns, std::map &prefix_map); +static gint sp_repr_qualified_name (gchar *p, gint len, xmlNsPtr ns, const xmlChar *name, const gchar *default_ns, std::map &prefix_map); static void sp_repr_write_stream_root_element(Node *repr, Writer &out, bool add_whitespace, gchar const *default_ns, int inlineattrs, int indent, @@ -486,8 +487,7 @@ Document *sp_repr_do_read (xmlDocPtr doc, const gchar *default_ns) return NULL; } - GHashTable * prefix_map; - prefix_map = g_hash_table_new (g_str_hash, g_str_equal); + std::map prefix_map; Document *rdoc = new Inkscape::XML::SimpleDocument(); @@ -536,21 +536,17 @@ Document *sp_repr_do_read (xmlDocPtr doc, const gchar *default_ns) } } - g_hash_table_destroy (prefix_map); - return rdoc; } -gint sp_repr_qualified_name (gchar *p, gint len, xmlNsPtr ns, const xmlChar *name, const gchar */*default_ns*/, GHashTable *prefix_map) +gint sp_repr_qualified_name (gchar *p, gint len, xmlNsPtr ns, const xmlChar *name, const gchar */*default_ns*/, std::map &prefix_map) { const xmlChar *prefix; if (ns){ if (ns->href ) { prefix = reinterpret_cast( sp_xml_ns_uri_prefix(reinterpret_cast(ns->href), reinterpret_cast(ns->prefix)) ); - void* p0 = reinterpret_cast(const_cast(prefix)); - void* p1 = reinterpret_cast(const_cast(ns->href)); - g_hash_table_insert( prefix_map, p0, p1 ); + prefix_map[reinterpret_cast(prefix)] = reinterpret_cast(ns->href); } else { prefix = NULL; @@ -567,7 +563,7 @@ gint sp_repr_qualified_name (gchar *p, gint len, xmlNsPtr ns, const xmlChar *nam } } -static Node *sp_repr_svg_read_node (Document *xml_doc, xmlNodePtr node, const gchar *default_ns, GHashTable *prefix_map) +static Node *sp_repr_svg_read_node (Document *xml_doc, xmlNodePtr node, const gchar *default_ns, std::map &prefix_map) { xmlAttrPtr prop; xmlNodePtr child; -- cgit v1.2.3 From d2ea9b6aecbbcf55b37081ec049af14b52a2ecf5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 9 Dec 2015 16:06:31 +0100 Subject: Fix GTK3 rulers on guide Lock and remove gap between guides and horizontal ruler (bzr r14518) --- src/menus-skeleton.h | 2 +- src/widgets/desktop-widget.cpp | 50 ++++++++++++++++++++++++++---------------- src/widgets/desktop-widget.h | 2 +- 3 files changed, 33 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index 11070d390..8cdfbeb05 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -86,8 +86,8 @@ static char const menus_skeleton[] = " \n" " \n" " \n" -" \n" " \n" +" \n" " \n" " \n" " \n" diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index fd2847506..431b7a05d 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -70,6 +70,11 @@ #include "widget-sizes.h" #include "verbs.h" +#if GTK_CHECK_VERSION(3,0,0) +# include +# include +# include +#endif #include #include @@ -391,21 +396,19 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) dtw->tool_toolbox = ToolboxFactory::createToolToolbox(); ToolboxFactory::setOrientation( dtw->tool_toolbox, GTK_ORIENTATION_VERTICAL ); gtk_box_pack_start( GTK_BOX(dtw->hbox), dtw->tool_toolbox, FALSE, TRUE, 0 ); - /* Lock all guides */ -#if GTK_CHECK_VERSION(3,0,0) - dtw->lock_and_hruler = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); -#else - dtw->lock_and_hruler = gtk_hbox_new (FALSE, 0); -#endif // Lock guides button dtw->guides_lock = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION, SP_BUTTON_TYPE_TOGGLE, NULL, INKSCAPE_ICON("object-locked"), _("Toggle lock of all guides in the document")); - - gtk_box_pack_start (GTK_BOX (dtw->lock_and_hruler), dtw->guides_lock, FALSE, FALSE, 0); - g_signal_connect (G_OBJECT (dtw->guides_lock), "toggled", G_CALLBACK (sp_update_guides_lock), dtw); +#if GTK_CHECK_VERSION(3,0,0) + Glib::RefPtr guides_lock_style_provider = Gtk::CssProvider::create(); + guides_lock_style_provider->load_from_data("GtkWidget { padding-left: 0; padding-right: 0; padding-top: 0; padding-bottom: 0; }"); + Gtk::Widget * wnd = Glib::wrap(dtw->guides_lock); + Glib::RefPtr context = wnd->get_style_context(); + context->add_provider(guides_lock_style_provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); +#endif /* Horizontal ruler */ GtkWidget *eventbox = gtk_event_box_new (); @@ -415,7 +418,6 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) sp_ruler_set_unit(SP_RULER(dtw->hruler), pt); gtk_widget_set_tooltip_text (dtw->hruler_box, gettext(pt->name_plural.c_str())); gtk_container_add (GTK_CONTAINER (eventbox), dtw->hruler); - gtk_container_add (GTK_CONTAINER (dtw->lock_and_hruler), eventbox); g_signal_connect (G_OBJECT (eventbox), "button_press_event", G_CALLBACK (sp_dt_hruler_event), dtw); g_signal_connect (G_OBJECT (eventbox), "button_release_event", G_CALLBACK (sp_dt_hruler_event), dtw); g_signal_connect (G_OBJECT (eventbox), "motion_notify_event", G_CALLBACK (sp_dt_hruler_event), dtw); @@ -424,18 +426,24 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) GtkWidget *tbl = gtk_grid_new(); dtw->canvas_tbl = gtk_grid_new(); - gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), dtw->lock_and_hruler, 0, 0, 1, 1); + gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), dtw->guides_lock, 0, 0, 1, 1); + gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), eventbox, 1, 0, 1, 1); #else GtkWidget *tbl = gtk_table_new(2, 3, FALSE); dtw->canvas_tbl = gtk_table_new(3, 3, FALSE); gtk_table_attach(GTK_TABLE(dtw->canvas_tbl), - dtw->lock_and_hruler, - 0, 2, 0, 1, + dtw->guides_lock, + 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(dtw->canvas_tbl), + eventbox, + 1, 2, 0, 1, + GTK_FILL, GTK_FILL, + 0, 0); #endif - + g_signal_connect (G_OBJECT (dtw->guides_lock), "toggled", G_CALLBACK (sp_update_guides_lock), dtw); gtk_box_pack_start( GTK_BOX(dtw->hbox), tbl, TRUE, TRUE, 1 ); /* Vertical ruler */ @@ -1593,10 +1601,12 @@ void SPDesktopWidget::layoutWidgets() } if (!prefs->getBool(pref_root + "rulers/state", true)) { - gtk_widget_hide (dtw->lock_and_hruler); + gtk_widget_hide (dtw->guides_lock); + gtk_widget_hide (dtw->hruler); gtk_widget_hide (dtw->vruler); } else { - gtk_widget_show_all (dtw->lock_and_hruler); + gtk_widget_show_all (dtw->guides_lock); + gtk_widget_show_all (dtw->hruler); gtk_widget_show_all (dtw->vruler); } } @@ -2084,12 +2094,14 @@ void sp_desktop_widget_toggle_rulers (SPDesktopWidget *dtw) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (gtk_widget_get_visible (dtw->lock_and_hruler)) { - gtk_widget_hide (dtw->lock_and_hruler); + if (gtk_widget_get_visible (dtw->guides_lock)) { + gtk_widget_hide (dtw->guides_lock); + gtk_widget_hide (dtw->hruler); gtk_widget_hide (dtw->vruler); prefs->setBool(dtw->desktop->is_fullscreen() ? "/fullscreen/rulers/state" : "/window/rulers/state", false); } else { - gtk_widget_show_all (dtw->lock_and_hruler); + gtk_widget_show_all (dtw->guides_lock); + gtk_widget_show_all (dtw->hruler); gtk_widget_show_all (dtw->vruler); prefs->setBool(dtw->desktop->is_fullscreen() ? "/fullscreen/rulers/state" : "/window/rulers/state", true); } diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h index bb5834165..58aba4bcb 100644 --- a/src/widgets/desktop-widget.h +++ b/src/widgets/desktop-widget.h @@ -89,7 +89,7 @@ struct SPDesktopWidget { GtkWidget *hruler_box, *vruler_box; // eventboxes for setting tooltips GtkWidget *guides_lock; - GtkWidget *lock_and_hruler; + GtkWidget *guides_lock_alignment; GtkWidget *sticky_zoom; GtkWidget *cms_adjust; GtkWidget *coord_status; -- cgit v1.2.3 From 7cd471edf6d96b0614fe2cb84d35a9889c3aefcc Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 9 Dec 2015 16:13:54 +0100 Subject: Remove unused var in header file (bzr r14519) --- src/widgets/desktop-widget.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h index 58aba4bcb..08966ad5f 100644 --- a/src/widgets/desktop-widget.h +++ b/src/widgets/desktop-widget.h @@ -89,7 +89,6 @@ struct SPDesktopWidget { GtkWidget *hruler_box, *vruler_box; // eventboxes for setting tooltips GtkWidget *guides_lock; - GtkWidget *guides_lock_alignment; GtkWidget *sticky_zoom; GtkWidget *cms_adjust; GtkWidget *coord_status; -- cgit v1.2.3 From e0a657bb7bcd383fed77d65d217f7fa163718866 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Wed, 9 Dec 2015 16:25:12 +0100 Subject: fix crash noticed by Tav (bzr r14504.1.17) --- src/sp-namedview.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index c03019572..50b567d2c 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -690,7 +690,6 @@ void SPNamedView::remove_child(Inkscape::XML::Node *child) { } else { for(std::vector::iterator it=this->guides.begin();it!=this->guides.end();++it ) { if ( (*it)->getRepr() == child ) { - delete (*it); this->guides.erase(it); break; } -- cgit v1.2.3 From 092c87ff207189a0d2f7fea193ecf8ea401a9a31 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 9 Dec 2015 17:26:27 +0100 Subject: Remove unnecesary headers for GTK3 (bzr r14521) --- src/widgets/desktop-widget.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 85f58c830..da7a54ca0 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -71,9 +71,7 @@ #include "verbs.h" #if GTK_CHECK_VERSION(3,0,0) -# include # include -# include #endif #include #include -- cgit v1.2.3 From 97324d275423a8367fdd671cbdda8097f26b0b10 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 9 Dec 2015 21:01:20 +0100 Subject: Remove unused header file. (bzr r14522) --- src/extension/execution-env.cpp | 2 - src/extension/implementation/implementation.cpp | 1 - src/extension/implementation/script.cpp | 1 - src/extension/internal/bitmap/imagemagick.cpp | 1 - src/extension/internal/bluredge.cpp | 2 - src/extension/internal/filter/filter.cpp | 1 - src/extension/internal/grid.cpp | 1 - src/graphlayout.cpp | 1 - src/removeoverlap.cpp | 1 - src/ui/dialog/align-and-distribute.cpp | 1 - src/ui/dialog/transformation.cpp | 1 - src/util/CMakeLists.txt | 1 - src/util/Makefile_insert | 1 - src/util/glib-list-iterators.h | 237 ------------------------ src/widgets/pencil-toolbar.cpp | 1 - 15 files changed, 253 deletions(-) delete mode 100644 src/util/glib-list-iterators.h (limited to 'src') diff --git a/src/extension/execution-env.cpp b/src/extension/execution-env.cpp index 27d19fdff..31491605b 100644 --- a/src/extension/execution-env.cpp +++ b/src/extension/execution-env.cpp @@ -30,8 +30,6 @@ #include "display/sp-canvas.h" -#include "util/glib-list-iterators.h" - namespace Inkscape { namespace Extension { diff --git a/src/extension/implementation/implementation.cpp b/src/extension/implementation/implementation.cpp index b0ff3e91c..92a8a2833 100644 --- a/src/extension/implementation/implementation.cpp +++ b/src/extension/implementation/implementation.cpp @@ -23,7 +23,6 @@ #include "desktop.h" #include "ui/view/view.h" -#include "util/glib-list-iterators.h" namespace Inkscape { namespace Extension { diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 52cc7a2ca..4a929fa08 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -42,7 +42,6 @@ #include "xml/node.h" #include "xml/attribute-record.h" -#include "util/glib-list-iterators.h" #include "path-prefix.h" #ifdef WIN32 diff --git a/src/extension/internal/bitmap/imagemagick.cpp b/src/extension/internal/bitmap/imagemagick.cpp index 40d548a24..a235dcb0f 100644 --- a/src/extension/internal/bitmap/imagemagick.cpp +++ b/src/extension/internal/bitmap/imagemagick.cpp @@ -24,7 +24,6 @@ #include "selection.h" #include "sp-object.h" -#include "util/glib-list-iterators.h" #include "extension/effect.h" #include "extension/system.h" diff --git a/src/extension/internal/bluredge.cpp b/src/extension/internal/bluredge.cpp index 9f19f8b3b..0e3aa98ce 100644 --- a/src/extension/internal/bluredge.cpp +++ b/src/extension/internal/bluredge.cpp @@ -22,8 +22,6 @@ #include "path-chemistry.h" #include "sp-item.h" -#include "util/glib-list-iterators.h" - #include "extension/effect.h" #include "extension/system.h" diff --git a/src/extension/internal/filter/filter.cpp b/src/extension/internal/filter/filter.cpp index 65162af22..25e89bbf3 100644 --- a/src/extension/internal/filter/filter.cpp +++ b/src/extension/internal/filter/filter.cpp @@ -11,7 +11,6 @@ #include "selection.h" #include "document-private.h" #include "sp-item.h" -#include "util/glib-list-iterators.h" #include "extension/extension.h" #include "extension/effect.h" #include "extension/system.h" diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp index 8fd82b675..8a9c7a72f 100644 --- a/src/extension/internal/grid.cpp +++ b/src/extension/internal/grid.cpp @@ -24,7 +24,6 @@ #include "document.h" #include "selection.h" #include "sp-object.h" -#include "util/glib-list-iterators.h" #include "2geom/geom.h" #include "svg/path-string.h" diff --git a/src/graphlayout.cpp b/src/graphlayout.cpp index 39ffb6cc7..3956b39fe 100644 --- a/src/graphlayout.cpp +++ b/src/graphlayout.cpp @@ -25,7 +25,6 @@ #include "desktop.h" #include "inkscape.h" #include "sp-namedview.h" -#include "util/glib-list-iterators.h" #include "graphlayout.h" #include "sp-path.h" #include "sp-item.h" diff --git a/src/removeoverlap.cpp b/src/removeoverlap.cpp index 9ea75de0d..138577fb8 100644 --- a/src/removeoverlap.cpp +++ b/src/removeoverlap.cpp @@ -12,7 +12,6 @@ */ #include #include <2geom/transforms.h> -#include "util/glib-list-iterators.h" #include "sp-item.h" #include "sp-item-transform.h" #include "libvpsc/generate-constraints.h" diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 6a9c3db6b..9e7861217 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -42,7 +42,6 @@ #include "ui/icon-names.h" #include "ui/tools/node-tool.h" #include "ui/tool/multi-path-manipulator.h" -#include "util/glib-list-iterators.h" #include "verbs.h" #include "widgets/icon.h" #include "sp-root.h" diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index ae972bbbd..b7638e8c1 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -35,7 +35,6 @@ #include "sp-item-transform.h" #include "macros.h" #include "sp-item.h" -#include "util/glib-list-iterators.h" #include "ui/icon-names.h" #include "widgets/icon.h" diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 8fd8c8c66..9680b6377 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -24,7 +24,6 @@ set(util_SRC format.h forward-pointer-iterator.h function.h - glib-list-iterators.h list-container-test.h list-container.h list-copy.h diff --git a/src/util/Makefile_insert b/src/util/Makefile_insert index c23dffbca..2a778e660 100644 --- a/src/util/Makefile_insert +++ b/src/util/Makefile_insert @@ -25,7 +25,6 @@ util_libutil_a_SOURCES = \ util/format.h \ util/forward-pointer-iterator.h \ util/function.h \ - util/glib-list-iterators.h \ util/list.h \ util/list-container.h \ util/list-copy.h \ diff --git a/src/util/glib-list-iterators.h b/src/util/glib-list-iterators.h deleted file mode 100644 index 6244e5b18..000000000 --- a/src/util/glib-list-iterators.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Inkscape::Util::GSListIterator - STL iterator for GSList - * Inkscape::Util::GSListConstIterator - STL iterator for GSList - * Inkscape::Util::GListIterator - STL iterator for GList - * Inkscape::Util::GListConstIterator - STL iterator for GList - * - * Authors: - * MenTaLguY - * - * Copyright (C) 2005 MenTaLguY - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef SEEN_INKSCAPE_GLIB_LIST_ITERATORS_H -#define SEEN_INKSCAPE_GLIB_LIST_ITERATORS_H - -#include -#include -#include - -namespace Inkscape { - -namespace Util { - -template class GSListConstIterator; -template class GSListIterator; -template class GListConstIterator; -template class GListIterator; - -template -class GSListConstIterator { -public: - typedef std::forward_iterator_tag iterator_category; - typedef T * const value_type G_GNUC_MAY_ALIAS; - typedef std::ptrdiff_t difference_type; - typedef value_type *pointer; - typedef value_type &reference; - - GSListConstIterator(GSList const *list) : _list(list) {} - // default copy - // default assign - GSList const *list() const { return _list; } - - reference operator*() const { - return *reinterpret_cast(&_list->data); - } - - bool operator==(GSListConstIterator const &other) { - return other._list == _list; - } - bool operator!=(GSListConstIterator const &other) { - return other._list != _list; - } - - GSListConstIterator &operator++() { - _list = _list->next; - return *this; - } - GSListConstIterator operator++(int) { - GSListConstIterator saved=*this; - _list = _list->next; - return saved; - } - -private: - GSList const *_list; -}; - -template -class GSListIterator { -public: - typedef std::forward_iterator_tag iterator_category; - typedef T *value_type G_GNUC_MAY_ALIAS; - typedef std::ptrdiff_t difference_type; - typedef value_type *pointer; - typedef value_type &reference; - typedef value_type const &const_reference; - - GSListIterator(GSList *list) : _list(list) {} - // default copy - // default assign - operator GSListConstIterator() const { return _list; } - GSList const *list() const { return _list; } - GSList *list() { return _list; } - - const_reference operator*() const { - return *reinterpret_cast(&_list->data); - } - reference operator*() { - return *reinterpret_cast(&_list->data); - } - - bool operator==(GSListIterator const &other) { - return other._list == _list; - } - bool operator!=(GSListIterator const &other) { - return other._list != _list; - } - - GSListIterator &operator++() { - _list = _list->next; - return *this; - } - GSListIterator operator++(int) { - GSListIterator saved=*this; - _list = _list->next; - return saved; - } - -private: - GSList *_list; -}; - -template -class GListConstIterator { -public: - typedef std::bidirectional_iterator_tag iterator_category; - typedef T * const value_type G_GNUC_MAY_ALIAS; - typedef std::ptrdiff_t difference_type; - typedef value_type *pointer; - typedef value_type &reference; - - GListConstIterator(GList const *list) : _list(list) {} - // default copy - // default assign - GList const *list() const { return _list; } - - reference operator*() const { - return *reinterpret_cast(&_list->data); - } - - bool operator==(GListConstIterator const &other) { - return other._list == _list; - } - bool operator!=(GListConstIterator const &other) { - return other._list != _list; - } - - GListConstIterator &operator++() { - _list = _list->next; - return *this; - } - GListConstIterator operator++(int) { - GListConstIterator saved=*this; - _list = _list->next; - return saved; - } - - GListConstIterator &operator--() { - _list = _list->prev; - return *this; - } - GListConstIterator operator--(int) { - GListConstIterator saved=*this; - _list = _list->prev; - return saved; - } - -private: - GList const *_list; -}; - -template -class GListIterator { -public: - typedef std::bidirectional_iterator_tag iterator_category; - typedef T *value_type G_GNUC_MAY_ALIAS; - typedef std::ptrdiff_t difference_type; - typedef value_type *pointer; - typedef value_type &reference; - typedef value_type const &const_reference; - - GListIterator(GList *list) : _list(list) {} - // default copy - // default assign - operator GSListConstIterator() const { - return reinterpret_cast(_list); - } - operator GSListIterator() const { - return reinterpret_cast(_list); - } - operator GListConstIterator() const { return _list; } - GList const *list() const { return _list; } - GList *list() { return _list; } - - const_reference operator*() const { - return *reinterpret_cast(&_list->data); - } - reference operator*() { return *reinterpret_cast(&_list->data); } - - bool operator==(GListIterator const &other) { - return other._list == _list; - } - bool operator!=(GListIterator const &other) { - return other._list != _list; - } - - GListIterator &operator++() { - _list = _list->next; - return *this; - } - GListIterator operator++(int) { - GListIterator saved=*this; - _list = _list->next; - return saved; - } - - GListIterator &operator--() { - _list = _list->prev; - return *this; - } - GListIterator operator--(int) { - GListIterator saved=*this; - _list = _list->prev; - return saved; - } - -private: - GList *_list; -}; - -} - -} - -#endif -/* - 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/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index aed80a66f..94875ecc1 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -53,7 +53,6 @@ #include "live_effects/lpeobject.h" #include "live_effects/lpeobject-reference.h" #include "sp-lpe-item.h" -#include "util/glib-list-iterators.h" using Inkscape::UI::UXManager; using Inkscape::UI::ToolboxFactory; -- cgit v1.2.3 From 1b5e5271ae41e3ab4e2d352118e66ccafc608a6f Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 10 Dec 2015 00:43:23 -0500 Subject: Remove CtrlPoint and replace with SPKnot (bzr r14523) --- src/display/CMakeLists.txt | 2 - src/display/Makefile_insert | 2 - src/display/guideline.cpp | 49 ++++++++----- src/display/guideline.h | 4 +- src/display/sp-ctrlpoint.cpp | 169 ------------------------------------------- src/display/sp-ctrlpoint.h | 54 -------------- src/sp-guide.cpp | 2 - src/ui/control-manager.cpp | 26 +------ src/ui/control-types.h | 1 - 9 files changed, 37 insertions(+), 272 deletions(-) delete mode 100644 src/display/sp-ctrlpoint.cpp delete mode 100644 src/display/sp-ctrlpoint.h (limited to 'src') diff --git a/src/display/CMakeLists.txt b/src/display/CMakeLists.txt index d4f8c16ff..0bf1d6e45 100644 --- a/src/display/CMakeLists.txt +++ b/src/display/CMakeLists.txt @@ -54,7 +54,6 @@ set(display_SRC sp-canvas.cpp sp-ctrlcurve.cpp sp-ctrlline.cpp - sp-ctrlpoint.cpp sp-ctrlquadr.cpp @@ -120,7 +119,6 @@ set(display_SRC sp-canvas.h sp-ctrlcurve.h sp-ctrlline.h - sp-ctrlpoint.h sp-ctrlquadr.h ) diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert index 20e498981..419852f7d 100644 --- a/src/display/Makefile_insert +++ b/src/display/Makefile_insert @@ -115,8 +115,6 @@ ink_common_sources += \ display/sp-ctrlcurve.h \ display/sp-ctrlline.cpp \ display/sp-ctrlline.h \ - display/sp-ctrlpoint.cpp \ - display/sp-ctrlpoint.h \ display/sp-ctrlquadr.cpp \ display/sp-ctrlquadr.h diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 4b7ea59ab..820a61d4d 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -17,7 +17,7 @@ #include <2geom/coord.h> #include <2geom/transforms.h> #include "sp-canvas-util.h" -#include "sp-ctrlpoint.h" +#include "knot.h" #include "guideline.h" #include "display/cairo-utils.h" @@ -25,6 +25,7 @@ #include "desktop.h" #include "sp-namedview.h" #include "display/sp-canvas.h" +#include "display/sodipodi-ctrl.h" #include "ui/control-manager.h" using Inkscape::ControlManager; @@ -36,6 +37,7 @@ static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf); static double sp_guideline_point(SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); +static gboolean sp_guideline_origin_move(SPKnot *knot, Geom::Point *position, guint state, SPGuideLine *data); static void sp_guideline_drawline (SPCanvasBuf *buf, gint x0, gint y0, gint x1, gint y1, guint32 rgba); G_DEFINE_TYPE(SPGuideLine, sp_guideline, SP_TYPE_CANVAS_ITEM); @@ -72,8 +74,8 @@ static void sp_guideline_destroy(SPCanvasItem *object) SPGuideLine *gl = SP_GUIDELINE(object); - if (gl->origin != NULL && SP_IS_CTRLPOINT(gl->origin)) { - sp_canvas_item_destroy(gl->origin); + if (gl->origin != NULL && SP_IS_KNOT(gl->origin)) { + knot_unref(gl->origin); } else { // FIXME: This branch shouldn't be reached (although it seems to be harmless). //g_error("Why can it be that gl->origin is not a valid SPCtrlPoint?\n"); @@ -179,14 +181,16 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, gl->affine = affine; if (gl->locked) { - sp_ctrlpoint_set_circle(gl->origin, false); - sp_ctrlpoint_set_lenght(gl->origin, 6); + gl->origin->setStroke(0x0000ff88, 0x0000ff88, 0x0000ff88); + gl->origin->setShape(SP_CTRL_SHAPE_CROSS); + gl->origin->setSize(6); } else { - sp_ctrlpoint_set_circle(gl->origin, true); - sp_ctrlpoint_set_lenght(gl->origin, 4); + gl->origin->setStroke(0xff000088, 0xff0000ff, 0xff0000ff); + gl->origin->setShape(SP_CTRL_SHAPE_CIRCLE); + gl->origin->setSize(4); } - sp_ctrlpoint_set_coords(gl->origin, gl->point_on_line); - sp_canvas_item_request_update(SP_CANVAS_ITEM (gl->origin)); + gl->origin->moveto(gl->point_on_line); + gl->origin->updateCtrl(); Geom::Point pol_transformed = gl->point_on_line*affine; if (gl->is_horizontal()) { @@ -219,12 +223,15 @@ static double sp_guideline_point(SPCanvasItem *item, Geom::Point p, SPCanvasItem SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point point_on_line, Geom::Point normal) { SPCanvasItem *item = sp_canvas_item_new(parent, SP_TYPE_GUIDELINE, NULL); - SPCanvasItem *origin = ControlManager::getManager().createControl(parent, Inkscape::CTRL_TYPE_ORIGIN); - ControlManager::getManager().track(origin); - SPGuideLine *gl = SP_GUIDELINE(item); - SPCtrlPoint *cp = SP_CTRLPOINT(origin); - gl->origin = cp; + gl->origin = new SPKnot(SP_ACTIVE_DESKTOP, "No tip yet!! XXX"); + + gl->origin->setAnchor(SP_ANCHOR_CENTER); + gl->origin->setMode(SP_CTRL_MODE_COLOR); + gl->origin->setFill(0xffffff80, 0xffffffff, 0xffffff80); + gl->origin->moveto(point_on_line); + gl->origin->request_signal.connect(sigc::bind(sigc::ptr_fun(sp_guideline_origin_move), gl)); + gl->origin->updateCtrl(); normal.normalize(); gl->label = label; @@ -233,11 +240,18 @@ SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point p gl->angle = tan( -gl->normal_to_line[Geom::X] / gl->normal_to_line[Geom::Y]); sp_guideline_set_position(gl, point_on_line); - sp_ctrlpoint_set_coords(cp, point_on_line); - return item; } +static gboolean sp_guideline_origin_move(SPKnot *knot, Geom::Point *position, guint state, SPGuideLine *gl) +{ + if(gl->locked) { + return true; + } + sp_guideline_set_position(gl, *position); + return false; +} + void sp_guideline_set_label(SPGuideLine *gl, const char* label) { if (gl->label) { @@ -271,8 +285,6 @@ void sp_guideline_set_normal(SPGuideLine *gl, Geom::Point normal_to_line) void sp_guideline_set_color(SPGuideLine *gl, unsigned int rgba) { gl->rgba = rgba; - sp_ctrlpoint_set_color(gl->origin, rgba); - sp_canvas_item_request_update(SP_CANVAS_ITEM(gl)); } @@ -283,7 +295,6 @@ void sp_guideline_set_sensitive(SPGuideLine *gl, int sensitive) void sp_guideline_delete(SPGuideLine *gl) { - //gtk_object_destroy(GTK_OBJECT(gl->origin)); sp_canvas_item_destroy(SP_CANVAS_ITEM(gl)); } diff --git a/src/display/guideline.h b/src/display/guideline.h index 778517f1d..143a57622 100644 --- a/src/display/guideline.h +++ b/src/display/guideline.h @@ -16,6 +16,7 @@ #include <2geom/point.h> #include "sp-canvas-item.h" +#include "knot.h" #define SP_TYPE_GUIDELINE (sp_guideline_get_type()) #define SP_GUIDELINE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_GUIDELINE, SPGuideLine)) @@ -27,7 +28,8 @@ struct SPGuideLine { SPCanvasItem item; Geom::Affine affine; - SPCtrlPoint *origin; // unlike 'item', this is only held locally + //SPCtrlPoint *origin; // unlike 'item', this is only held locally + SPKnot *origin; guint32 rgba; diff --git a/src/display/sp-ctrlpoint.cpp b/src/display/sp-ctrlpoint.cpp deleted file mode 100644 index 19dbbc130..000000000 --- a/src/display/sp-ctrlpoint.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Simple point - * - * Author: - * Maximilian Albert - * Jon A. Cruz - * - * Copyright (C) 2008 Maximilian Albert - * - * Released under GNU GPL - */ - -#include "sp-canvas-util.h" -#include "sp-ctrlpoint.h" - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include -#include "display/cairo-utils.h" -#include "display/sp-canvas.h" - -static void sp_ctrlpoint_destroy(SPCanvasItem *object); - -static void sp_ctrlpoint_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); -static void sp_ctrlpoint_render (SPCanvasItem *item, SPCanvasBuf *buf); - -G_DEFINE_TYPE(SPCtrlPoint, sp_ctrlpoint, SP_TYPE_CANVAS_ITEM); - -static void sp_ctrlpoint_class_init(SPCtrlPointClass *klass) -{ - SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(klass); - - item_class->destroy = sp_ctrlpoint_destroy; - item_class->update = sp_ctrlpoint_update; - item_class->render = sp_ctrlpoint_render; -} - -static void -sp_ctrlpoint_init (SPCtrlPoint *ctrlpoint) -{ - ctrlpoint->rgba = 0x0000ff7f; - ctrlpoint->pt[Geom::X] = ctrlpoint->pt[Geom::Y] = 0.0; - ctrlpoint->item=NULL; - ctrlpoint->lenght = 4; - ctrlpoint->is_circle = true; -} - -static void sp_ctrlpoint_destroy(SPCanvasItem *object) -{ - g_return_if_fail (object != NULL); - g_return_if_fail (SP_IS_CTRLPOINT (object)); - - SPCtrlPoint *ctrlpoint = SP_CTRLPOINT (object); - - ctrlpoint->item=NULL; - - if (SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->destroy) - SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->destroy(object); -} - -static void -sp_ctrlpoint_render (SPCanvasItem *item, SPCanvasBuf *buf) -{ - SPCtrlPoint *cp = SP_CTRLPOINT (item); - - if (!buf->ct) - return; - - sp_canvas_prepare_buffer (buf); - - guint32 rgba = cp->rgba; - cairo_set_source_rgba(buf->ct, SP_RGBA32_B_F(rgba), SP_RGBA32_G_F(rgba), SP_RGBA32_R_F(rgba), SP_RGBA32_A_F(rgba)); - - cairo_set_line_width(buf->ct, 1); - cairo_new_path(buf->ct); - - Geom::Point pt = cp->pt * cp->affine; - if( cp->is_circle ) { - cairo_arc(buf->ct, pt[Geom::X] - buf->rect.left(), pt[Geom::Y] - buf->rect.top(), cp->lenght/2.0, 0.0, 2 * M_PI); - } else { - cairo_rectangle(buf->ct, pt[Geom::X] - buf->rect.left() - cp->lenght/2.0, pt[Geom::Y] - buf->rect.top() - cp->lenght/2.0 , cp->lenght, cp->lenght); - } - cairo_stroke(buf->ct); -} - -static void sp_ctrlpoint_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags) -{ - SPCtrlPoint *cp = SP_CTRLPOINT(item); - - item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); - - if (SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->update) { - SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->update(item, affine, flags); - } - - sp_canvas_item_reset_bounds (item); - - cp->affine = affine; - - Geom::Point pt = cp->pt * affine; - - item->x1 = pt[Geom::X] - cp->lenght; - item->y1 = pt[Geom::Y] - cp->lenght; - item->x2 = pt[Geom::X] + cp->lenght; - item->y2 = pt[Geom::Y] + cp->lenght; - - item->canvas->requestRedraw((int)item->x1 - 15, (int)item->y1 - 15, - (int)item->x1 + 15, (int)item->y1 + 15); -} - -void -sp_ctrlpoint_set_color (SPCtrlPoint *cp, guint32 rgba) -{ - g_return_if_fail (cp != NULL); - g_return_if_fail (SP_IS_CTRLPOINT (cp)); - - if (rgba != cp->rgba) { - SPCanvasItem *item; - cp->rgba = rgba; - item = SP_CANVAS_ITEM (cp); - item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); - } -} - -#define EPSILON 1e-6 -#define DIFFER(a,b) (fabs ((a) - (b)) > EPSILON) - -void -sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const gdouble x, const gdouble y) -{ - g_return_if_fail (cp != NULL); - g_return_if_fail (SP_IS_CTRLPOINT (cp)); - - if (DIFFER (x, cp->pt[Geom::X]) || DIFFER (y, cp->pt[Geom::Y])) { - cp->pt[Geom::X] = x; - cp->pt[Geom::Y] = y; - sp_canvas_item_request_update (SP_CANVAS_ITEM (cp)); - } -} - -void -sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const Geom::Point pt) -{ - sp_ctrlpoint_set_coords(cp, pt[Geom::X], pt[Geom::Y]); -} - -void -sp_ctrlpoint_set_lenght (SPCtrlPoint *cp, const double r) -{ - cp->lenght = r; -} - -void -sp_ctrlpoint_set_circle (SPCtrlPoint *cp, const bool circle) -{ - cp->is_circle = circle; -} - -/* - 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/display/sp-ctrlpoint.h b/src/display/sp-ctrlpoint.h deleted file mode 100644 index 02e61caf0..000000000 --- a/src/display/sp-ctrlpoint.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef SEEN_INKSCAPE_CTRLPOINT_H -#define SEEN_INKSCAPE_CTRLPOINT_H - -/* - * A simple point - * - * Author: - * Maximilian Albert - * - * Copyright (C) 2008 Maximilian Albert - * - * Released under GNU GPL - */ - -#include "sp-canvas-item.h" - -class SPItem; - -#define SP_TYPE_CTRLPOINT (sp_ctrlpoint_get_type ()) -#define SP_CTRLPOINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CTRLPOINT, SPCtrlPoint)) -#define SP_IS_CTRLPOINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CTRLPOINT)) - -struct SPCtrlPoint : public SPCanvasItem { - SPItem *item; // the item to which this line belongs in some sense; may be NULL for some users - guint32 rgba; - Geom::Point pt; - Geom::Affine affine; - double lenght; - bool is_circle; -}; -struct SPCtrlPointClass : public SPCanvasItemClass{}; - -GType sp_ctrlpoint_get_type (void); - -void sp_ctrlpoint_set_color (SPCtrlPoint *cp, guint32 rgba); -void sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const gdouble x, const gdouble y); -void sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const Geom::Point pt); -void sp_ctrlpoint_set_lenght (SPCtrlPoint *cp, const double r); -void sp_ctrlpoint_set_circle (SPCtrlPoint *cp, const bool circle); - - - -#endif // SEEN_INKSCAPE_CTRLPOINT_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/sp-guide.cpp b/src/sp-guide.cpp index 70c73b7e3..441c2e793 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -288,7 +288,6 @@ void SPGuide::showSPGuide() { for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { sp_canvas_item_show(SP_CANVAS_ITEM(*it)); - sp_canvas_item_show(SP_CANVAS_ITEM((*it)->origin)); } } @@ -311,7 +310,6 @@ void SPGuide::hideSPGuide() { for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { sp_canvas_item_hide(SP_CANVAS_ITEM(*it)); - sp_canvas_item_hide(SP_CANVAS_ITEM((*it)->origin)); } } diff --git a/src/ui/control-manager.cpp b/src/ui/control-manager.cpp index 7a5620684..cedaea405 100644 --- a/src/ui/control-manager.cpp +++ b/src/ui/control-manager.cpp @@ -20,7 +20,6 @@ #include "display/sp-canvas-item.h" #include "display/sp-ctrlline.h" #include "display/sp-ctrlcurve.h" -#include "display/sp-ctrlpoint.h" #include "preferences.h" using Inkscape::ControlFlags; @@ -139,8 +138,6 @@ ControlManagerImpl::ControlManagerImpl(ControlManager &manager) : _typeTable[CTRL_TYPE_NODE_SMOOTH] = SP_TYPE_CTRL; _typeTable[CTRL_TYPE_NODE_SYMETRICAL] = SP_TYPE_CTRL; - _typeTable[CTRL_TYPE_ORIGIN] = SP_TYPE_CTRLPOINT; - _typeTable[CTRL_TYPE_LINE] = SP_TYPE_CTRLLINE; @@ -182,10 +179,6 @@ ControlManagerImpl::ControlManagerImpl(ControlManager &manager) : _sizeTable[CTRL_TYPE_SIZER] = std::vector(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); _sizeTable[CTRL_TYPE_SHAPER] = std::vector(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); } - { - int sizes[] = {2, 3, 4, 7, 8, 9, 10}; - _sizeTable[CTRL_TYPE_ORIGIN] = std::vector(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); - } { int sizes[] = {5, 7, 9, 10, 11, 12, 13}; _sizeTable[CTRL_TYPE_NODE_AUTO] = std::vector(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); @@ -258,10 +251,6 @@ SPCanvasItem *ControlManagerImpl::createControl(SPCanvasGroup *parent, ControlTy NULL); break; } - case CTRL_TYPE_ORIGIN: - item = sp_canvas_item_new(parent, SP_TYPE_CTRLPOINT, - NULL); - break; case CTRL_TYPE_INVISIPOINT: item = sp_canvas_item_new(parent, SP_TYPE_CTRL, "shape", SP_CTRL_SHAPE_SQUARE, @@ -297,18 +286,11 @@ void ControlManagerImpl::updateItem(SPCanvasItem *item) if (item) { double target = _sizeTable[item->ctrlType][_size - 1]; - if ((item->ctrlType == CTRL_TYPE_ORIGIN) && SP_IS_CTRLPOINT(item)) { - if (SP_CTRLPOINT(item)->is_circle ) { - sp_ctrlpoint_set_lenght(SP_CTRLPOINT(item), target ); - } else { - sp_ctrlpoint_set_lenght(SP_CTRLPOINT(item), target + 2 ); - } - } else { - if (_sizeChangers.count(item->ctrlType) && _manager.isSelected(item)) { - target += 2; - } - g_object_set(item, "size", target, NULL); + if (_sizeChangers.count(item->ctrlType) && _manager.isSelected(item)) { + target += 2; } + g_object_set(item, "size", target, NULL); + sp_canvas_item_request_update(item); } } diff --git a/src/ui/control-types.h b/src/ui/control-types.h index 0bbf31144..1a0230324 100644 --- a/src/ui/control-types.h +++ b/src/ui/control-types.h @@ -26,7 +26,6 @@ enum ControlType { CTRL_TYPE_ROTATE, CTRL_TYPE_SIZER, CTRL_TYPE_SHAPER, - CTRL_TYPE_ORIGIN, CTRL_TYPE_LINE, CTRL_TYPE_NODE_AUTO, CTRL_TYPE_NODE_CUSP, -- cgit v1.2.3 From d2edbb1ddc55f9d839892066a7015aca4029d4d7 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Thu, 10 Dec 2015 11:22:55 +0100 Subject: hide/show handle with guide (bzr r14524) --- src/sp-guide.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 441c2e793..065acf586 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -288,6 +288,7 @@ void SPGuide::showSPGuide() { for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { sp_canvas_item_show(SP_CANVAS_ITEM(*it)); + (*it)->origin->show(); } } @@ -310,6 +311,7 @@ void SPGuide::hideSPGuide() { for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { sp_canvas_item_hide(SP_CANVAS_ITEM(*it)); + (*it)->origin->hide(); } } -- cgit v1.2.3 From e151d5d9804624f69d037e708c6a2bd35058e467 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 11 Dec 2015 02:24:16 +0100 Subject: Fix bug launching a document by commandline with guides (bzr r14525) --- src/display/guideline.cpp | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 820a61d4d..1c28149a9 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -180,6 +180,15 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, gl->affine = affine; + if (!gl->origin){ + gl->origin = new SPKnot(SP_ACTIVE_DESKTOP, "No tip yet!! XXX"); + + gl->origin->setAnchor(SP_ANCHOR_CENTER); + gl->origin->setMode(SP_CTRL_MODE_COLOR); + gl->origin->setFill(0xffffff80, 0xffffffff, 0xffffff80); + gl->origin->request_signal.connect(sigc::bind(sigc::ptr_fun(sp_guideline_origin_move), gl)); + } + if (gl->locked) { gl->origin->setStroke(0x0000ff88, 0x0000ff88, 0x0000ff88); gl->origin->setShape(SP_CTRL_SHAPE_CROSS); @@ -191,7 +200,7 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, } gl->origin->moveto(gl->point_on_line); gl->origin->updateCtrl(); - + Geom::Point pol_transformed = gl->point_on_line*affine; if (gl->is_horizontal()) { sp_canvas_update_bbox (item, -1000000, round(pol_transformed[Geom::Y] - 16), 1000000, round(pol_transformed[Geom::Y] + 1)); @@ -224,15 +233,16 @@ SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point p { SPCanvasItem *item = sp_canvas_item_new(parent, SP_TYPE_GUIDELINE, NULL); SPGuideLine *gl = SP_GUIDELINE(item); - gl->origin = new SPKnot(SP_ACTIVE_DESKTOP, "No tip yet!! XXX"); - - gl->origin->setAnchor(SP_ANCHOR_CENTER); - gl->origin->setMode(SP_CTRL_MODE_COLOR); - gl->origin->setFill(0xffffff80, 0xffffffff, 0xffffff80); - gl->origin->moveto(point_on_line); - gl->origin->request_signal.connect(sigc::bind(sigc::ptr_fun(sp_guideline_origin_move), gl)); - gl->origin->updateCtrl(); - + if ( SP_ACTIVE_DESKTOP ){ + gl->origin = new SPKnot(SP_ACTIVE_DESKTOP, "No tip yet!! XXX"); + + gl->origin->setAnchor(SP_ANCHOR_CENTER); + gl->origin->setMode(SP_CTRL_MODE_COLOR); + gl->origin->setFill(0xffffff80, 0xffffffff, 0xffffff80); + gl->origin->moveto(point_on_line); + gl->origin->request_signal.connect(sigc::bind(sigc::ptr_fun(sp_guideline_origin_move), gl)); + gl->origin->updateCtrl(); + } normal.normalize(); gl->label = label; gl->locked = false; -- cgit v1.2.3 From 0732d8cfbf843dac04be27f45b8102d6df216410 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 10 Dec 2015 21:47:16 -0500 Subject: Clean up some code, only init the SPKnot in one place. (bzr r14526) --- src/display/guideline.cpp | 14 -------------- src/display/guideline.h | 5 +---- src/sp-guide.cpp | 4 +++- 3 files changed, 4 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 1c28149a9..fd6ccf164 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -69,16 +69,11 @@ static void sp_guideline_destroy(SPCanvasItem *object) { g_return_if_fail (object != NULL); g_return_if_fail (SP_IS_GUIDELINE (object)); - //g_return_if_fail (SP_GUIDELINE(object)->origin != NULL); - //g_return_if_fail (SP_IS_CTRLPOINT(SP_GUIDELINE(object)->origin)); SPGuideLine *gl = SP_GUIDELINE(object); if (gl->origin != NULL && SP_IS_KNOT(gl->origin)) { knot_unref(gl->origin); - } else { - // FIXME: This branch shouldn't be reached (although it seems to be harmless). - //g_error("Why can it be that gl->origin is not a valid SPCtrlPoint?\n"); } if (gl->label) { @@ -233,16 +228,7 @@ SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point p { SPCanvasItem *item = sp_canvas_item_new(parent, SP_TYPE_GUIDELINE, NULL); SPGuideLine *gl = SP_GUIDELINE(item); - if ( SP_ACTIVE_DESKTOP ){ - gl->origin = new SPKnot(SP_ACTIVE_DESKTOP, "No tip yet!! XXX"); - gl->origin->setAnchor(SP_ANCHOR_CENTER); - gl->origin->setMode(SP_CTRL_MODE_COLOR); - gl->origin->setFill(0xffffff80, 0xffffffff, 0xffffff80); - gl->origin->moveto(point_on_line); - gl->origin->request_signal.connect(sigc::bind(sigc::ptr_fun(sp_guideline_origin_move), gl)); - gl->origin->updateCtrl(); - } normal.normalize(); gl->label = label; gl->locked = false; diff --git a/src/display/guideline.h b/src/display/guideline.h index 143a57622..d58821fc8 100644 --- a/src/display/guideline.h +++ b/src/display/guideline.h @@ -22,14 +22,11 @@ #define SP_GUIDELINE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_GUIDELINE, SPGuideLine)) #define SP_IS_GUIDELINE(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_GUIDELINE)) -struct SPCtrlPoint; - struct SPGuideLine { SPCanvasItem item; Geom::Affine affine; - //SPCtrlPoint *origin; // unlike 'item', this is only held locally - SPKnot *origin; + SPKnot *origin; // unlike 'item', this is only held locally guint32 rgba; diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 065acf586..b8990a461 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -288,7 +288,9 @@ void SPGuide::showSPGuide() { for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { sp_canvas_item_show(SP_CANVAS_ITEM(*it)); - (*it)->origin->show(); + if((*it)->origin) { + (*it)->origin->show(); + } } } -- cgit v1.2.3 From 678ace57cb2e98572d3e5c30138b3100aceef1ed Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 11 Dec 2015 10:16:30 +0100 Subject: Fix crash on hidden guides (bzr r14527) --- src/display/guideline.cpp | 46 +++++++++++++++++++++++----------------------- src/sp-guide.cpp | 7 ++++++- 2 files changed, 29 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index fd6ccf164..4b573a586 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -172,31 +172,32 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, if ((SP_CANVAS_ITEM_CLASS(sp_guideline_parent_class))->update) { (SP_CANVAS_ITEM_CLASS(sp_guideline_parent_class))->update(item, affine, flags); } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop && item->visible) { + if (!gl->origin) { + gl->origin = new SPKnot(desktop, "No tip yet!! XXX"); + + gl->origin->setAnchor(SP_ANCHOR_CENTER); + gl->origin->setMode(SP_CTRL_MODE_COLOR); + gl->origin->setFill(0xffffff80, 0xffffffff, 0xffffff80); + gl->origin->request_signal.connect(sigc::bind(sigc::ptr_fun(sp_guideline_origin_move), gl)); + } - gl->affine = affine; - - if (!gl->origin){ - gl->origin = new SPKnot(SP_ACTIVE_DESKTOP, "No tip yet!! XXX"); - - gl->origin->setAnchor(SP_ANCHOR_CENTER); - gl->origin->setMode(SP_CTRL_MODE_COLOR); - gl->origin->setFill(0xffffff80, 0xffffffff, 0xffffff80); - gl->origin->request_signal.connect(sigc::bind(sigc::ptr_fun(sp_guideline_origin_move), gl)); - } - - if (gl->locked) { - gl->origin->setStroke(0x0000ff88, 0x0000ff88, 0x0000ff88); - gl->origin->setShape(SP_CTRL_SHAPE_CROSS); - gl->origin->setSize(6); - } else { - gl->origin->setStroke(0xff000088, 0xff0000ff, 0xff0000ff); - gl->origin->setShape(SP_CTRL_SHAPE_CIRCLE); - gl->origin->setSize(4); + if (gl->locked) { + gl->origin->setStroke(0x0000ff88, 0x0000ff88, 0x0000ff88); + gl->origin->setShape(SP_CTRL_SHAPE_CROSS); + gl->origin->setSize(6); + } else { + gl->origin->setStroke(0xff000088, 0xff0000ff, 0xff0000ff); + gl->origin->setShape(SP_CTRL_SHAPE_CIRCLE); + gl->origin->setSize(4); + } + gl->origin->moveto(gl->point_on_line); + gl->origin->updateCtrl(); } - gl->origin->moveto(gl->point_on_line); - gl->origin->updateCtrl(); - Geom::Point pol_transformed = gl->point_on_line*affine; + gl->affine = affine; + Geom::Point pol_transformed = gl->point_on_line * affine; if (gl->is_horizontal()) { sp_canvas_update_bbox (item, -1000000, round(pol_transformed[Geom::Y] - 16), 1000000, round(pol_transformed[Geom::Y] + 1)); } else if (gl->is_vertical()) { @@ -205,7 +206,6 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, //TODO: labels in angled guidelines are not showing up for some reason. sp_canvas_update_bbox (item, -1000000, -1000000, 1000000, 1000000); } - } // Returns 0.0 if point is on the guideline diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index b8990a461..a57947e01 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -290,6 +290,9 @@ void SPGuide::showSPGuide() sp_canvas_item_show(SP_CANVAS_ITEM(*it)); if((*it)->origin) { (*it)->origin->show(); + } else { + //reposition to same place to show knots + sp_guideline_set_position(*it, point_on_line); } } } @@ -313,7 +316,9 @@ void SPGuide::hideSPGuide() { for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { sp_canvas_item_hide(SP_CANVAS_ITEM(*it)); - (*it)->origin->hide(); + if ((*it)->origin) { + (*it)->origin->hide(); + } } } -- cgit v1.2.3 From b3abbe4f9bb5e1db77547c791425586e43047dc0 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 13 Dec 2015 20:21:23 +0100 Subject: Perfomance optimization bugfix Fixed bugs: - https://launchpad.net/bugs/1515971 (bzr r14528) --- src/selection-chemistry.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index cdbc6a937..e6d5f174e 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1341,6 +1341,7 @@ void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) bool no_more = false; // Set to true, if no more layers above SPObject *next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); if (next) { + selection->clear(); sp_selection_change_layer_maintain_clones(items,next); std::vector temp_clip; sp_selection_copy_impl(items, temp_clip, dt->doc()->getReprDoc()); @@ -1384,6 +1385,7 @@ void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) bool no_more = false; // Set to true, if no more layers below SPObject *next=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); if (next) { + selection->clear(); sp_selection_change_layer_maintain_clones(items,next); std::vector temp_clip; sp_selection_copy_impl(items, temp_clip, dt->doc()->getReprDoc()); // we're in the same doc, so no need to copy defs @@ -1424,6 +1426,7 @@ void sp_selection_to_layer(SPDesktop *dt, SPObject *moveto, bool suppressDone) std::vector items(selection->itemList()); if (moveto) { + selection->clear(); sp_selection_change_layer_maintain_clones(items,moveto); std::vector temp_clip; sp_selection_copy_impl(items, temp_clip, dt->doc()->getReprDoc()); // we're in the same doc, so no need to copy defs -- cgit v1.2.3 From ab7cc89c4f9f938575e777530c31312cde116208 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 13 Dec 2015 20:23:22 +0100 Subject: cppification and performance (bzr r14529) --- src/display/sp-canvas-item.h | 2 + src/display/sp-canvas-util.cpp | 3 + src/display/sp-canvas.cpp | 195 ++++++++++++++--------------------------- 3 files changed, 71 insertions(+), 129 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas-item.h b/src/display/sp-canvas-item.h index 3e9e085a0..66cd03dd9 100644 --- a/src/display/sp-canvas-item.h +++ b/src/display/sp-canvas-item.h @@ -116,7 +116,9 @@ G_END_DECLS void sp_canvas_item_affine_absolute(SPCanvasItem *item, Geom::Affine const &aff); void sp_canvas_item_raise(SPCanvasItem *item, int positions); +void sp_canvas_item_raise_to_top(SPCanvasItem *item); void sp_canvas_item_lower(SPCanvasItem *item, int positions); +void sp_canvas_item_lower_to_bottom(SPCanvasItem *item); bool sp_canvas_item_is_visible(SPCanvasItem *item); void sp_canvas_item_show(SPCanvasItem *item); void sp_canvas_item_hide(SPCanvasItem *item); diff --git a/src/display/sp-canvas-util.cpp b/src/display/sp-canvas-util.cpp index 79c8c614e..25b70824b 100644 --- a/src/display/sp-canvas-util.cpp +++ b/src/display/sp-canvas-util.cpp @@ -67,6 +67,9 @@ void sp_canvas_item_set_i2w_affine (SPCanvasItem * item, Geom::Affine const &i2 void sp_canvas_item_move_to_z (SPCanvasItem * item, gint z) { g_assert (item != NULL); + + if (z == 0) + return sp_canvas_item_lower_to_bottom(item); gint current_z = sp_canvas_item_order (item); diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 5efc4ce86..6441ea68b 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -58,7 +58,7 @@ struct SPCanvasGroupClass { }; /** - * A group of Items. + * A group of items. */ struct SPCanvasGroup { /** @@ -109,8 +109,8 @@ struct SPCanvasGroup { SPCanvasItem item; - GList *items; - GList *last; + std::list *items; + }; /** @@ -166,13 +166,6 @@ static guint object_signals[LAST_SIGNAL] = { 0 }; */ void sp_canvas_item_construct(SPCanvasItem *item, SPCanvasGroup *parent, gchar const *first_arg_name, va_list args); -/** - * Convenience function to reorder items in a group's child list. - * - * This puts the specified link after the "before" link. - */ -void put_item_after(GList *link, GList *before); - /** * Helper that returns true iff item is descendant of parent. */ @@ -590,64 +583,6 @@ void sp_canvas_item_affine_absolute(SPCanvasItem *item, Geom::Affine const &affi item->canvas->need_repick = TRUE; } -namespace { - -void put_item_after(GList *link, GList *before) -{ - if (link == before) { - return; - } - - SPCanvasGroup *parent = SP_CANVAS_GROUP (SP_CANVAS_ITEM (link->data)->parent); - - if (before == NULL) { - if (link == parent->items) { - return; - } - - link->prev->next = link->next; - - if (link->next) { - link->next->prev = link->prev; - } else { - parent->last = link->prev; - } - - link->prev = before; - link->next = parent->items; - link->next->prev = link; - parent->items = link; - } else { - if ((link == parent->last) && (before == parent->last->prev)) { - return; - } - - if (link->next) { - link->next->prev = link->prev; - } - - if (link->prev) { - link->prev->next = link->next; - } else { - parent->items = link->next; - parent->items->prev = NULL; - } - - link->prev = before; - link->next = before->next; - - link->prev->next = link; - - if (link->next) { - link->next->prev = link; - } else { - parent->last = link; - } - } -} - -} // namespace - /** * Raises the item in its parent's stack by the specified number of positions. * @@ -668,24 +603,34 @@ void sp_canvas_item_raise(SPCanvasItem *item, int positions) } SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); - GList *link = g_list_find (parent->items, item); - g_assert (link != NULL); + std::list::iterator l = std::find(parent->items->begin(),parent->items->end(), item); + g_assert (l != parent->items->end()); - GList *before; - for (before = link; positions && before; positions--) - before = before->next; + for (int i=0; iitems->end(); ++i) + l++; - if (!before) { - before = parent->last; - } + parent->items->remove(item); + parent->items->insert(l, item); - put_item_after (link, before); + redraw_if_visible (item); + item->canvas->need_repick = TRUE; +} +void sp_canvas_item_raise_to_top(SPCanvasItem *item) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (SP_IS_CANVAS_ITEM (item)); + if (!item->parent) + return; + SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); + parent->items->remove(item); + parent->items->insert(parent->items->end(),item); redraw_if_visible (item); item->canvas->need_repick = TRUE; } + /** * Lowers the item in its parent's stack by the specified number of positions. * @@ -701,28 +646,35 @@ void sp_canvas_item_lower(SPCanvasItem *item, int positions) g_return_if_fail (SP_IS_CANVAS_ITEM (item)); g_return_if_fail (positions >= 1); - if (!item->parent || positions == 0) { + if (!item->parent || positions == 0 || item == SP_CANVAS_GROUP(item->parent)->items->front() ) { return; } SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); - GList *link = g_list_find (parent->items, item); - g_assert (link != NULL); + std::list::iterator l = std::find(parent->items->begin(),parent->items->end(), item); + g_assert (l != parent->items->end()); - GList *before; - if (link->prev) { - for (before = link->prev; positions && before; positions--) { - before = before->prev; - } - } else { - before = NULL; - } - - put_item_after (link, before); + for (int i=0; iitems->begin(); ++i) + l--; + + parent->items->remove(item); + parent->items->insert(l, item); redraw_if_visible (item); item->canvas->need_repick = TRUE; } +void sp_canvas_item_lower_to_bottom(SPCanvasItem *item) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (SP_IS_CANVAS_ITEM (item)); + if (!item->parent) + return; + SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); + parent->items->remove(item); + parent->items->insert(parent->items->begin(),item); + redraw_if_visible (item); + item->canvas->need_repick = TRUE; +} bool sp_canvas_item_is_visible(SPCanvasItem *item) { @@ -919,7 +871,8 @@ void sp_canvas_item_request_update(SPCanvasItem *item) */ gint sp_canvas_item_order (SPCanvasItem * item) { - return g_list_index (SP_CANVAS_GROUP (item->parent)->items, item); + SPCanvasGroup * p = SP_CANVAS_GROUP(item->parent); + return std::distance(p->items->begin(), std::find(p->items->begin(), p->items->end(), item)); } // SPCanvasGroup @@ -936,9 +889,9 @@ static void sp_canvas_group_class_init(SPCanvasGroupClass *klass) item_class->viewbox_changed = SPCanvasGroup::viewboxChanged; } -static void sp_canvas_group_init(SPCanvasGroup * /*group*/) +static void sp_canvas_group_init(SPCanvasGroup * group) { - // Nothing here + group->items = new std::list; } void SPCanvasGroup::destroy(SPCanvasItem *object) @@ -948,14 +901,15 @@ void SPCanvasGroup::destroy(SPCanvasItem *object) SPCanvasGroup const *group = SP_CANVAS_GROUP(object); - GList *list = group->items; - while (list) { - SPCanvasItem *child = reinterpret_cast(list->data); - list = list->next; - + std::list *list = group->items; + for (std::list::iterator it = list->begin(); it != list->end(); ++it) { + SPCanvasItem *child = *it; sp_canvas_item_destroy(child); } + group->items->clear(); + delete group->items; + if (SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy) { (* SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy)(object); } @@ -966,8 +920,8 @@ void SPCanvasGroup::update(SPCanvasItem *item, Geom::Affine const &affine, unsig SPCanvasGroup const *group = SP_CANVAS_GROUP(item); Geom::OptRect bounds; - for (GList *list = group->items; list; list = list->next) { - SPCanvasItem *i = SP_CANVAS_ITEM(list->data); + for (std::list::const_iterator it = group->items->begin(); it != group->items->end(); ++it) { + SPCanvasItem *i = *it; sp_canvas_item_invoke_update (i, affine, flags); @@ -1002,9 +956,8 @@ double SPCanvasGroup::point(SPCanvasItem *item, Geom::Point p, SPCanvasItem **ac *actual_item = NULL; double dist = 0.0; - - for (GList *list = group->items; list; list = list->next) { - SPCanvasItem *child = SP_CANVAS_ITEM(list->data); + for (std::list::const_iterator it = group->items->begin(); it != group->items->end(); ++it) { + SPCanvasItem *child = *it; if ((child->x1 <= x2) && (child->y1 <= y2) && (child->x2 >= x1) && (child->y2 >= y1)) { SPCanvasItem *point_item = NULL; // cater for incomplete item implementations @@ -1037,8 +990,8 @@ void SPCanvasGroup::render(SPCanvasItem *item, SPCanvasBuf *buf) { SPCanvasGroup const *group = SP_CANVAS_GROUP(item); - for (GList *list = group->items; list; list = list->next) { - SPCanvasItem *child = SP_CANVAS_ITEM(list->data); + for (std::list::const_iterator it = group->items->begin(); it != group->items->end(); ++it) { + SPCanvasItem *child = *it; if (child->visible) { if ((child->x1 < buf->rect.right()) && (child->y1 < buf->rect.bottom()) && @@ -1056,8 +1009,8 @@ void SPCanvasGroup::viewboxChanged(SPCanvasItem *item, Geom::IntRect const &new_ { SPCanvasGroup *group = SP_CANVAS_GROUP(item); - for (GList *list = group->items; list; list = list->next) { - SPCanvasItem *child = SP_CANVAS_ITEM(list->data); + for (std::list::const_iterator it = group->items->begin(); it != group->items->end(); ++it) { + SPCanvasItem *child = *it; if (child->visible) { if (SP_CANVAS_ITEM_GET_CLASS(child)->viewbox_changed) { SP_CANVAS_ITEM_GET_CLASS(child)->viewbox_changed(child, new_area); @@ -1071,37 +1024,21 @@ void SPCanvasGroup::add(SPCanvasItem *item) g_object_ref(item); g_object_ref_sink(item); - if (!items) { - items = g_list_append(items, item); - last = items; - } else { - last = g_list_append(last, item)->next; - } + items->push_back(item); sp_canvas_item_request_update(item); } void SPCanvasGroup::remove(SPCanvasItem *item) { + g_return_if_fail(item != NULL); + items->remove(item); - for (GList *children = items; children; children = children->next) { - if (children->data == item) { - - // Unparent the child - item->parent = NULL; - g_object_unref(item); - - // Remove it from the list - if (children == last) { - last = children->prev; - } + // Unparent the child + item->parent = NULL; + g_object_unref(item); - items = g_list_remove_link(items, children); - g_list_free(children); - break; - } - } } static void sp_canvas_dispose (GObject *object); -- cgit v1.2.3 From 743c2ecacf5abf06b43ce05f8107e6f00230c942 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 13 Dec 2015 23:57:10 +0100 Subject: fix minor bug from recent merge: layer names were incorrectly created (bzr r14530) --- src/layer-manager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/layer-manager.cpp b/src/layer-manager.cpp index 5dae5f20a..c0fe95dd7 100644 --- a/src/layer-manager.cpp +++ b/src/layer-manager.cpp @@ -194,9 +194,10 @@ Glib::ustring LayerManager::getNextLayerName( SPObject* obj, gchar const *label) std::set layers = _document->getResourceList("layer"); SPObject *root=_desktop->currentRoot(); if ( root ) { - std::set::iterator iter = layers.find(obj); - if (iter != layers.end()) + for (std::set::const_iterator iter = layers.begin(); iter != layers.end(); ++iter) { + if (*iter != obj) currentNames.insert( (*iter)->label() ? Glib::ustring((*iter)->label()) : Glib::ustring() ); + } } // Not sure if we need to cap it, but we'll just be paranoid for the moment -- cgit v1.2.3 From 78c3176c18c0306aaac30b640e939de9051b3a1f Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 14 Dec 2015 14:45:25 +0100 Subject: Fix two bugs with component transfer filter primitive: 1. Discrete type was ignoring last value in list. 2. Change in alpha was not propogated to pre-multiplied color values leading to "ghosting". (bzr r14532) --- src/display/nr-filter-component-transfer.cpp | 202 +++++++-------------------- 1 file changed, 47 insertions(+), 155 deletions(-) (limited to 'src') diff --git a/src/display/nr-filter-component-transfer.cpp b/src/display/nr-filter-component-transfer.cpp index dd90193fe..dd37ab873 100644 --- a/src/display/nr-filter-component-transfer.cpp +++ b/src/display/nr-filter-component-transfer.cpp @@ -30,6 +30,32 @@ FilterPrimitive * FilterComponentTransfer::create() { FilterComponentTransfer::~FilterComponentTransfer() {} +struct UnmultiplyAlpha { + guint32 operator()(guint32 in) { + EXTRACT_ARGB32(in, a, r, g, b); + if (a == 0 ) + return in; + r = unpremul_alpha(r, a); + g = unpremul_alpha(g, a); + b = unpremul_alpha(b, a); + ASSEMBLE_ARGB32(out, a, r, g, b); + return out; + } +}; + +struct MultiplyAlpha { + guint32 operator()(guint32 in) { + EXTRACT_ARGB32(in, a, r, g, b); + if (a == 0 ) + return in; + r = premul_alpha(r, a); + g = premul_alpha(g, a); + b = premul_alpha(b, a); + ASSEMBLE_ARGB32(out, a, r, g, b); + return out; + } +}; + struct ComponentTransfer { ComponentTransfer(guint32 color) : _shift(color * 8) @@ -40,11 +66,7 @@ protected: guint32 _mask; }; -template -struct ComponentTransferTable; - -template <> -struct ComponentTransferTable : public ComponentTransfer { +struct ComponentTransferTable : public ComponentTransfer { ComponentTransferTable(guint32 color, std::vector const &values) : ComponentTransfer(color) , _v(values.size()) @@ -55,49 +77,17 @@ struct ComponentTransferTable : public ComponentTransfer { } guint32 operator()(guint32 in) { guint32 component = (in & _mask) >> _shift; - guint32 alpha = (in & 0xff000000) >> 24; - if (alpha == 0) return in; - - component = (255 * component + alpha/2) / alpha; guint32 k = (_v.size() - 1) * component; guint32 dx = k % 255; k /= 255; component = _v[k]*255 + (_v[k+1] - _v[k])*dx; component = (component + 127) / 255; - component = premul_alpha(component, alpha); return (in & ~_mask) | (component << _shift); } private: std::vector _v; }; -template <> -struct ComponentTransferTable { - ComponentTransferTable(std::vector const &values) - : _v(values.size()) - { - for (unsigned i = 0; i< values.size(); ++i) { - _v[i] = round(CLAMP(values[i], 0.0, 1.0) * 255); - } - } - guint32 operator()(guint32 in) { - guint32 alpha = (in & 0xff000000) >> 24; - if (alpha == 0) return in; - - guint32 k = (_v.size() - 1) * alpha; - guint32 dx = k % 255; k /= 255; - alpha = _v[k]*255 + (_v[k+1] - _v[k])*dx; - alpha = (alpha + 127) / 255; - return (in & 0x00ffffff) | (alpha << 24); - } -private: - std::vector _v; -}; - -template -struct ComponentTransferDiscrete; - -template <> -struct ComponentTransferDiscrete : public ComponentTransfer { +struct ComponentTransferDiscrete : public ComponentTransfer { ComponentTransferDiscrete(guint32 color, std::vector const &values) : ComponentTransfer(color) , _v(values.size()) @@ -108,45 +98,15 @@ struct ComponentTransferDiscrete : public ComponentTransfer { } guint32 operator()(guint32 in) { guint32 component = (in & _mask) >> _shift; - guint32 alpha = (in & 0xff000000) >> 24; - if (alpha == 0) return in; - - component = (255 * component + alpha/2) / alpha; - guint32 k = (_v.size() - 1) * component / 255; + guint32 k = (_v.size()) * component / 255; component = _v[k]; - component = premul_alpha(component, alpha); - return (in & ~_mask) | (component << _shift); + return (in & ~_mask) | ((guint32)component << _shift); } private: std::vector _v; }; -template <> -struct ComponentTransferDiscrete { - ComponentTransferDiscrete(std::vector const &values) - : _v(values.size()) - { - for (unsigned i = 0; i< values.size(); ++i) { - _v[i] = round(CLAMP(values[i], 0.0, 1.0) * 255); - } - } - guint32 operator()(guint32 in) { - guint32 alpha = (in & 0xff000000) >> 24; - if (alpha == 0) return in; - - guint32 k = (_v.size() - 1) * alpha / 255; - alpha = _v[k]; - return (in & 0x00ffffff) | (alpha << 24); - } -private: - std::vector _v; -}; - -template -struct ComponentTransferLinear; - -template <> -struct ComponentTransferLinear : public ComponentTransfer { +struct ComponentTransferLinear : public ComponentTransfer { ComponentTransferLinear(guint32 color, double intercept, double slope) : ComponentTransfer(color) , _intercept(round(intercept*255*255)) @@ -154,14 +114,10 @@ struct ComponentTransferLinear : public ComponentTransfer { {} guint32 operator()(guint32 in) { gint32 component = (in & _mask) >> _shift; - guint32 alpha = (in & 0xff000000) >> 24; - if (alpha == 0) return 0; // TODO: this can probably be reduced to something simpler - component = (255 * component + alpha/2) / alpha; component = pxclamp(_slope * component + _intercept, 0, 255*255); component = (component + 127) / 255; - component = premul_alpha(component, alpha); return (in & ~_mask) | (component << _shift); } private: @@ -169,28 +125,7 @@ private: gint32 _slope; }; -template <> -struct ComponentTransferLinear { - ComponentTransferLinear(double intercept, double slope) - : _intercept(round(intercept*255*255)) - , _slope(round(slope*255)) - {} - guint32 operator()(guint32 in) { - gint32 alpha = (in & 0xff000000) >> 24; - alpha = pxclamp(_slope * alpha + _intercept, 0, 255*255); - alpha = (alpha + 127) / 255; - return (in & 0x00ffffff) | (alpha << 24); - } -private: - gint32 _intercept; - gint32 _slope; -}; - -template -struct ComponentTransferGamma; - -template <> -struct ComponentTransferGamma : public ComponentTransfer { +struct ComponentTransferGamma : public ComponentTransfer { ComponentTransferGamma(guint32 color, double amplitude, double exponent, double offset) : ComponentTransfer(color) , _amplitude(amplitude) @@ -199,13 +134,9 @@ struct ComponentTransferGamma : public ComponentTransfer { {} guint32 operator()(guint32 in) { double component = (in & _mask) >> _shift; - guint32 alpha = (in & 0xff000000) >> 24; - if (alpha == 0) return 0; - - double alphaf = alpha; - component /= alphaf; + component /= 255.0; component = _amplitude * pow(component, _exponent) + _offset; - guint32 cpx = pxclamp(component * alphaf, 0, 255); + guint32 cpx = pxclamp(component * 255.0, 0, 255); return (in & ~_mask) | (cpx << _shift); } private: @@ -214,26 +145,6 @@ private: double _offset; }; -template <> -struct ComponentTransferGamma { - ComponentTransferGamma(double amplitude, double exponent, double offset) - : _amplitude(amplitude) - , _exponent(exponent) - , _offset(offset) - {} - guint32 operator()(guint32 in) { - double alpha = (in & 0xff000000) >> 24; - alpha /= 255.0; - alpha = _amplitude * pow(alpha, _exponent) + _offset; - guint32 cpx = pxclamp(alpha * 255.0, 0, 255); - return (in & 0x00ffffff) | (cpx << 24); - } -private: - double _amplitude; - double _exponent; - double _offset; -}; - void FilterComponentTransfer::render_cairo(FilterSlot &slot) { cairo_surface_t *input = slot.getcairo(_input); @@ -252,31 +163,38 @@ void FilterComponentTransfer::render_cairo(FilterSlot &slot) //cairo_surface_t *outtemp = ink_cairo_surface_create_identical(out); ink_cairo_surface_blit(input, out); + // We need to operate on unmultipled by alpha color values otherwise a change in alpha screws + // up the premultiplied by alpha r, g, b values. + ink_cairo_surface_filter(out, out, UnmultiplyAlpha()); + // parameters: R = 0, G = 1, B = 2, A = 3 // Cairo: R = 2, G = 1, B = 0, A = 3 // If tableValues is empty, use identity. - for (unsigned i = 0; i < 3; ++i) { + for (unsigned i = 0; i < 4; ++i) { + guint32 color = 2 - i; + if(i==3) color = 3; // alpha + switch (type[i]) { case COMPONENTTRANSFER_TYPE_TABLE: if(!tableValues[i].empty()) { ink_cairo_surface_filter(out, out, - ComponentTransferTable(color, tableValues[i])); + ComponentTransferTable(color, tableValues[i])); } break; case COMPONENTTRANSFER_TYPE_DISCRETE: if(!tableValues[i].empty()) { ink_cairo_surface_filter(out, out, - ComponentTransferDiscrete(color, tableValues[i])); + ComponentTransferDiscrete(color, tableValues[i])); } break; case COMPONENTTRANSFER_TYPE_LINEAR: ink_cairo_surface_filter(out, out, - ComponentTransferLinear(color, intercept[i], slope[i])); + ComponentTransferLinear(color, intercept[i], slope[i])); break; case COMPONENTTRANSFER_TYPE_GAMMA: ink_cairo_surface_filter(out, out, - ComponentTransferGamma(color, amplitude[i], exponent[i], offset[i])); + ComponentTransferGamma(color, amplitude[i], exponent[i], offset[i])); break; case COMPONENTTRANSFER_TYPE_ERROR: case COMPONENTTRANSFER_TYPE_IDENTITY: @@ -286,33 +204,7 @@ void FilterComponentTransfer::render_cairo(FilterSlot &slot) //ink_cairo_surface_blit(out, outtemp); } - // fast paths for alpha channel - switch (type[3]) { - case COMPONENTTRANSFER_TYPE_TABLE: - if(!tableValues[3].empty()) { - ink_cairo_surface_filter(out, out, - ComponentTransferTable(tableValues[3])); - } - break; - case COMPONENTTRANSFER_TYPE_DISCRETE: - if(!tableValues[3].empty()) { - ink_cairo_surface_filter(out, out, - ComponentTransferDiscrete(tableValues[3])); - } - break; - case COMPONENTTRANSFER_TYPE_LINEAR: - ink_cairo_surface_filter(out, out, - ComponentTransferLinear(intercept[3], slope[3])); - break; - case COMPONENTTRANSFER_TYPE_GAMMA: - ink_cairo_surface_filter(out, out, - ComponentTransferGamma(amplitude[3], exponent[3], offset[3])); - break; - case COMPONENTTRANSFER_TYPE_ERROR: - case COMPONENTTRANSFER_TYPE_IDENTITY: - default: - break; - } + ink_cairo_surface_filter(out, out, MultiplyAlpha()); slot.set(_output, out); cairo_surface_destroy(out); -- cgit v1.2.3 From 4d2fef1da189759823cf4792e4d9f875fbb1d2c6 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 14 Dec 2015 16:31:46 +0100 Subject: Small bug fix related to previous check-in. (bzr r14533) --- src/display/nr-filter-component-transfer.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/display/nr-filter-component-transfer.cpp b/src/display/nr-filter-component-transfer.cpp index dd37ab873..b2545b76f 100644 --- a/src/display/nr-filter-component-transfer.cpp +++ b/src/display/nr-filter-component-transfer.cpp @@ -99,6 +99,7 @@ struct ComponentTransferDiscrete : public ComponentTransfer { guint32 operator()(guint32 in) { guint32 component = (in & _mask) >> _shift; guint32 k = (_v.size()) * component / 255; + if( k == _v.size() ) --k; component = _v[k]; return (in & ~_mask) | ((guint32)component << _shift); } -- cgit v1.2.3 From 67d50bdf148df18e790341e963bafeb50767cfb4 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Mon, 14 Dec 2015 21:46:00 +0100 Subject: static code analysis: suppress compiler warning (bzr r14535) --- src/document.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 05e165965..b22b99e66 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1039,7 +1039,7 @@ SPObject *SPDocument::getObjectById(gchar const *id) const return NULL; } - GQuark idq = g_quark_from_string(id); + // GQuark idq = g_quark_from_string(id); std::map::iterator rv = priv->iddef.find(id); //gpointer rv = g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)); if(rv != priv->iddef.end()) -- cgit v1.2.3 From 38f4e0e9aeb0696939475ce9450a20b281144d27 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Fri, 18 Dec 2015 23:31:07 +0100 Subject: brings back CMS tab Fixed bugs: - https://launchpad.net/bugs/1504612 (bzr r14537) --- src/color-profile.cpp | 1 + src/document.cpp | 2 ++ src/ui/dialog/document-properties.cpp | 14 ++++++++++---- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/color-profile.cpp b/src/color-profile.cpp index 34f1b0155..bcefe994a 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -271,6 +271,7 @@ void ColorProfile::build(SPDocument *document, Inkscape::XML::Node *repr) { SPObject::build(document, repr); this->readAttr( "xlink:href" ); + this->readAttr( "id" ); this->readAttr( "local" ); this->readAttr( "name" ); this->readAttr( "rendering-intent" ); diff --git a/src/document.cpp b/src/document.cpp index b22b99e66..70fb56fe8 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -992,6 +992,8 @@ void SPDocument::bindObjectToId(gchar const *id, SPObject *object) { GQuark idq = g_quark_from_string(id); if (object) { + if(object->getId()) + priv->iddef.erase(object->getId()); g_assert(priv->iddef.find(id)==priv->iddef.end()); priv->iddef[id] = object; //g_assert(g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)) == NULL); diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 8af744fd3..b90467d93 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -479,7 +479,13 @@ void DocumentProperties::linkSelectedProfile() std::vector > pairs = ColorProfile::getProfileFilesWithNames(); Glib::ustring file = pairs[row].first; Glib::ustring name = pairs[row].second; - + std::set current = SP_ACTIVE_DOCUMENT->getResourceList( "iccprofile" ); + for (std::set::const_iterator it = current.begin(); it != current.end(); ++it) { + SPObject* obj = *it; + Inkscape::ColorProfile* prof = reinterpret_cast(obj); + if (!strcmp(prof->href, file.c_str())) + return; + } Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::XML::Node *cprofRepr = xml_doc->createElement("svg:color-profile"); gchar* tmp = g_strdup(name.c_str()); @@ -487,6 +493,8 @@ void DocumentProperties::linkSelectedProfile() sanitizeName(nameStr); cprofRepr->setAttribute("name", nameStr.c_str()); cprofRepr->setAttribute("xlink:href", (gchar*) file.c_str()); + cprofRepr->setAttribute("id", (gchar*) file.c_str()); + // Checks whether there is a defs element. Creates it when needed Inkscape::XML::Node *defsRepr = sp_repr_lookup_name(xml_doc, "svg:defs"); @@ -598,9 +606,7 @@ void DocumentProperties::removeSelectedProfile(){ SPObject* obj = *it; Inkscape::ColorProfile* prof = reinterpret_cast(obj); if (!name.compare(prof->name)){ - - //XML Tree being used directly here while it shouldn't be. - sp_repr_unparent(obj->getRepr()); + prof->deleteObject(true, false); DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_COLOR_PROFILE, _("Remove linked color profile")); break; // removing the color profile likely invalidates part of the traversed list, stop traversing here. } -- cgit v1.2.3 From 1e70568de64dabbccd225f6a0124e2447b35cbfa Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sat, 19 Dec 2015 01:13:37 +0100 Subject: fixes layer movement when there is a document scaling factor (bzr r14538) --- src/ui/dialog/layers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp index f4152e556..1c022ecad 100644 --- a/src/ui/dialog/layers.cpp +++ b/src/ui/dialog/layers.cpp @@ -715,11 +715,11 @@ void LayersPanel::_doTreeMove( ) { if (_dnd_source && _dnd_source->getRepr() ) { if(!_dnd_target){ - _dnd_source->doWriteTransform(_dnd_source->getRepr(), _dnd_source->document->getRoot()->i2doc_affine().inverse() * _dnd_source->i2doc_affine()); + _dnd_source->doWriteTransform(_dnd_source->getRepr(), _dnd_source->i2doc_affine() * _dnd_source->document->getRoot()->i2doc_affine().inverse()); }else{ SPItem* parent = _dnd_into ? _dnd_target : dynamic_cast(_dnd_target->parent); if(parent){ - Geom::Affine move = parent->i2doc_affine().inverse() * _dnd_source->i2doc_affine(); + Geom::Affine move = _dnd_source->i2doc_affine() * parent->i2doc_affine().inverse(); _dnd_source->doWriteTransform(_dnd_source->getRepr(), move); } } -- cgit v1.2.3 From 6f817f71119774c09888fddf8ba28a96c4546165 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 21 Dec 2015 10:48:56 +0100 Subject: Add option for checkerboard background. Fixed bugs: - https://launchpad.net/bugs/397723 (bzr r14539) --- src/attributes.cpp | 1 + src/attributes.h | 1 + src/desktop.cpp | 16 ++++++++++------ src/display/sodipodi-ctrlrect.cpp | 15 +++++++++++++++ src/display/sodipodi-ctrlrect.h | 3 +++ src/sp-namedview.cpp | 6 ++++++ src/sp-namedview.h | 1 + src/ui/dialog/document-properties.cpp | 24 +++++++++++++++++++----- src/ui/dialog/document-properties.h | 1 + 9 files changed, 57 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index e8620a498..dcd644b5d 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -82,6 +82,7 @@ static SPStyleProp const props[] = { {SP_ATTR_FIT_MARGIN_LEFT, "fit-margin-left"}, {SP_ATTR_FIT_MARGIN_RIGHT, "fit-margin-right"}, {SP_ATTR_FIT_MARGIN_BOTTOM, "fit-margin-bottom"}, + {SP_ATTR_INKSCAPE_PAGECHECKERBOARD, "inkscape:checkerboard"}, {SP_ATTR_INKSCAPE_PAGEOPACITY, "inkscape:pageopacity"}, {SP_ATTR_INKSCAPE_PAGESHADOW, "inkscape:pageshadow"}, {SP_ATTR_INKSCAPE_ZOOM, "inkscape:zoom"}, diff --git a/src/attributes.h b/src/attributes.h index 03df0cb94..754cc876a 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -83,6 +83,7 @@ enum SPAttributeEnum { SP_ATTR_FIT_MARGIN_LEFT, SP_ATTR_FIT_MARGIN_RIGHT, SP_ATTR_FIT_MARGIN_BOTTOM, + SP_ATTR_INKSCAPE_PAGECHECKERBOARD, SP_ATTR_INKSCAPE_PAGEOPACITY, SP_ATTR_INKSCAPE_PAGESHADOW, SP_ATTR_INKSCAPE_ZOOM, diff --git a/src/desktop.cpp b/src/desktop.cpp index 0aac46e8d..f099ba39f 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -210,9 +210,11 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid main = (SPCanvasGroup *) sp_canvas_item_new (root, SP_TYPE_CANVAS_GROUP, NULL); g_signal_connect (G_OBJECT (main), "event", G_CALLBACK (sp_desktop_root_handler), this); + /* This is the background the page sits on. */ table = sp_canvas_item_new (main, SP_TYPE_CTRLRECT, NULL); SP_CTRLRECT(table)->setRectangle(Geom::Rect(Geom::Point(-80000, -80000), Geom::Point(80000, 80000))); SP_CTRLRECT(table)->setColor(0x00000000, true, 0x00000000); + SP_CTRLRECT(table)->setCheckerboard( false ); sp_canvas_item_move_to_z (table, 0); page = sp_canvas_item_new (main, SP_TYPE_CTRLRECT, NULL); @@ -1731,14 +1733,16 @@ static void _namedview_modified (SPObject *obj, guint flags, SPDesktop *desktop) if (flags & SP_OBJECT_MODIFIED_FLAG) { - /* Show/hide page background */ - if (nv->pagecolor | (0xff != 0xffffffff)) { - sp_canvas_item_show (desktop->table); - ((CtrlRect *) desktop->table)->setColor(0x00000000, true, nv->pagecolor | 0xff); - sp_canvas_item_move_to_z (desktop->table, 0); + /* Set page background */ + sp_canvas_item_show (desktop->table); + if (nv->pagecheckerboard) { + ((CtrlRect *) desktop->table)->setCheckerboard( true ); + ((CtrlRect *) desktop->table)->setColor(0x00000000, true, nv->pagecolor ); // | 0xff); } else { - sp_canvas_item_hide (desktop->table); + ((CtrlRect *) desktop->table)->setCheckerboard( false ); + ((CtrlRect *) desktop->table)->setColor(0x00000000, true, nv->pagecolor | 0xff); } + sp_canvas_item_move_to_z (desktop->table, 0); /* Show/hide page border */ if (nv->showborder) { diff --git a/src/display/sodipodi-ctrlrect.cpp b/src/display/sodipodi-ctrlrect.cpp index 75789ff50..ecc952c48 100644 --- a/src/display/sodipodi-ctrlrect.cpp +++ b/src/display/sodipodi-ctrlrect.cpp @@ -74,6 +74,8 @@ void CtrlRect::init() { _has_fill = false; _dashed = false; + _checkerboard = false; + _shadow = 0; _area = Geom::OptIntRect(); @@ -109,10 +111,17 @@ void CtrlRect::render(SPCanvasBuf *buf) cairo_rectangle(buf->ct, 0.5 + area[X].min(), 0.5 + area[Y].min(), area[X].max() - area[X].min(), area[Y].max() - area[Y].min()); + if (_checkerboard) { + cairo_pattern_t *cb = ink_cairo_pattern_create_checkerboard(); + cairo_set_source(buf->ct, cb); + cairo_pattern_destroy(cb); + cairo_fill_preserve(buf->ct); + } if (_has_fill) { ink_cairo_set_source_rgba32(buf->ct, _fill_color); cairo_fill_preserve(buf->ct); } + ink_cairo_set_source_rgba32(buf->ct, _border_color); cairo_stroke(buf->ct); @@ -297,6 +306,12 @@ void CtrlRect::setDashed(bool d) _requestUpdate(); } +void CtrlRect::setCheckerboard(bool d) +{ + _checkerboard = d; + _requestUpdate(); +} + void CtrlRect::_requestUpdate() { sp_canvas_item_request_update(SP_CANVAS_ITEM(this)); diff --git a/src/display/sodipodi-ctrlrect.h b/src/display/sodipodi-ctrlrect.h index ff6c55b06..08a085649 100644 --- a/src/display/sodipodi-ctrlrect.h +++ b/src/display/sodipodi-ctrlrect.h @@ -39,6 +39,7 @@ public: void setShadow(int s, guint c); void setRectangle(Geom::Rect const &r); void setDashed(bool d); + void setCheckerboard(bool d); void render(SPCanvasBuf *buf); void update(Geom::Affine const &affine, unsigned int flags); @@ -49,6 +50,8 @@ private: Geom::Rect _rect; bool _has_fill; bool _dashed; + bool _checkerboard; + Geom::OptIntRect _area; gint _shadow_size; guint32 _border_color; diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 50b567d2c..0942081ca 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -84,6 +84,7 @@ SPNamedView::SPNamedView() : SPObjectGroup(), snap_manager(this) { this->lockguides = false; this->grids_visible = false; this->showborder = TRUE; + this->pagecheckerboard = FALSE; this->showpageshadow = TRUE; this->guides.clear(); @@ -207,6 +208,7 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "bordercolor" ); this->readAttr( "borderopacity" ); this->readAttr( "pagecolor" ); + this->readAttr( "inkscape:pagecheckerboard" ); this->readAttr( "inkscape:pageopacity" ); this->readAttr( "inkscape:pageshadow" ); this->readAttr( "inkscape:zoom" ); @@ -390,6 +392,10 @@ void SPNamedView::set(unsigned int key, const gchar* value) { } this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_INKSCAPE_PAGECHECKERBOARD: + this->pagecheckerboard = (value) ? sp_str_to_bool (value) : TRUE; + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; case SP_ATTR_INKSCAPE_PAGEOPACITY: this->pagecolor = (this->pagecolor & 0xffffff00) | (DEFAULTPAGECOLOR & 0xff); sp_nv_read_opacity(value, &this->pagecolor); diff --git a/src/sp-namedview.h b/src/sp-namedview.h index 7aae90f40..3d63f2b97 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -46,6 +46,7 @@ public: unsigned int editable : 1; unsigned int showguides : 1; unsigned int lockguides : 1; + unsigned int pagecheckerboard : 1; unsigned int showborder : 1; unsigned int showpageshadow : 1; unsigned int borderlayer : 2; diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index b90467d93..030bbbf7b 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -116,10 +116,11 @@ DocumentProperties::DocumentProperties() _page_metadata2(Gtk::manage(new UI::Widget::NotebookPage(1, 1))), //--------------------------------------------------------------- _rcb_antialias(_("Use antialiasing"), _("If unset, no antialiasing will be done on the drawing"), "shape-rendering", _wr, false, NULL, NULL, NULL, "crispEdges"), + _rcb_checkerboard(_("Checkerboard background"), _("If set, use checkerboard for background, otherwise use background color at full opacity."), "inkscape:checkerboard", _wr, false), _rcb_canb(_("Show page _border"), _("If set, rectangular page border is shown"), "showborder", _wr, false), _rcb_bord(_("Border on _top of drawing"), _("If set, border is always on top of the drawing"), "borderlayer", _wr, false), _rcb_shad(_("_Show border shadow"), _("If set, page border shows a shadow on its right and lower side"), "inkscape:showpageshadow", _wr, false), - _rcp_bg(_("Back_ground color:"), _("Background color"), _("Color of the page background. Note: transparency setting ignored while editing but used when exporting to bitmap."), "pagecolor", "inkscape:pageopacity", _wr), + _rcp_bg(_("Back_ground color:"), _("Background color"), _("Color of the page background. Note: transparency setting ignored while editing if 'Checkerboard background' set (but used when exporting to bitmap)."), "pagecolor", "inkscape:pageopacity", _wr), _rcp_bord(_("Border _color:"), _("Page border color"), _("Color of the page border"), "bordercolor", "borderopacity", _wr), _rum_deflt(_("Display _units:"), "inkscape:document-units", _wr), _page_sizer(_wr), @@ -327,10 +328,19 @@ void DocumentProperties::build_page() Gtk::Label* label_gen = Gtk::manage (new Gtk::Label); label_gen->set_markup (_("General")); + Gtk::Label *label_for = Gtk::manage (new Gtk::Label); label_for->set_markup (_("Page Size")); + + Gtk::Label* label_bkg = Gtk::manage (new Gtk::Label); + label_bkg->set_markup (_("Background")); + + Gtk::Label* label_bdr = Gtk::manage (new Gtk::Label); + label_bdr->set_markup (_("Border")); + Gtk::Label* label_dsp = Gtk::manage (new Gtk::Label); label_dsp->set_markup (_("Display")); + _page_sizer.init(); Gtk::Widget *const widget_array[] = @@ -343,13 +353,16 @@ void DocumentProperties::build_page() label_for, 0, 0, &_page_sizer, 0, 0, - label_dsp, 0, + label_bkg, 0, + 0, &_rcb_checkerboard, + _rcp_bg._label, &_rcp_bg, + label_bdr, 0, 0, &_rcb_canb, 0, &_rcb_bord, 0, &_rcb_shad, - 0, &_rcb_antialias, - _rcp_bg._label, &_rcp_bg, _rcp_bord._label, &_rcp_bord, + label_dsp, 0, + 0, &_rcb_antialias, }; std::list _slaveList; @@ -1438,6 +1451,7 @@ void DocumentProperties::update() set_sensitive (true); //-----------------------------------------------------------page page + _rcb_checkerboard.setActive (nv->pagecheckerboard); _rcp_bg.setRgba32 (nv->pagecolor); _rcb_canb.setActive (nv->showborder); _rcb_bord.setActive (nv->borderlayer == SP_BORDER_LAYER_TOP); @@ -1636,7 +1650,7 @@ void DocumentProperties::onRemoveGrid() SPDesktop *dt = getDesktop(); SPNamedView *nv = dt->getNamedView(); Inkscape::CanvasGrid * found_grid = NULL; - if( pagenum < nv->grids.size()) + if( pagenum < (gint)nv->grids.size()) found_grid = nv->grids[pagenum]; if (found_grid) { diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h index b1f90b4b7..7340b67f5 100644 --- a/src/ui/dialog/document-properties.h +++ b/src/ui/dialog/document-properties.h @@ -118,6 +118,7 @@ protected: UI::Widget::Registry _wr; //--------------------------------------------------------------- UI::Widget::RegisteredCheckButton _rcb_antialias; + UI::Widget::RegisteredCheckButton _rcb_checkerboard; UI::Widget::RegisteredCheckButton _rcb_canb; UI::Widget::RegisteredCheckButton _rcb_bord; UI::Widget::RegisteredCheckButton _rcb_shad; -- cgit v1.2.3 From 28cc694075fa441ea915133118c365dcf3a3be16 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 26 Dec 2015 18:42:49 +0000 Subject: Rebase on libcroco 0.6.11 (bzr r14540) --- src/libcroco/cr-enc-handler.c | 6 ++---- src/libcroco/cr-input.c | 2 ++ src/libcroco/cr-sel-eng.c | 4 ++-- src/libcroco/cr-simple-sel.c | 2 +- src/libcroco/cr-tknzr.c | 8 ++++++-- 5 files changed, 13 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/libcroco/cr-enc-handler.c b/src/libcroco/cr-enc-handler.c index 646bf1fe2..a7c4269ad 100644 --- a/src/libcroco/cr-enc-handler.c +++ b/src/libcroco/cr-enc-handler.c @@ -89,8 +89,7 @@ cr_enc_handler_get_instance (enum CREncoding a_enc) for (i = 0; gv_default_enc_handlers[i].encoding; i++) { if (gv_default_enc_handlers[i].encoding == a_enc) { - return (CREncHandler *) - & gv_default_enc_handlers[i].encoding; + return (CREncHandler *) & gv_default_enc_handlers[i]; } } @@ -118,8 +117,7 @@ cr_enc_handler_resolve_enc_alias (const guchar * a_alias_name, g_return_val_if_fail (a_alias_name != NULL, CR_BAD_PARAM_ERROR); - alias_name_up = g_strdup (a_alias_name); - g_ascii_strup (alias_name_up, -1); + alias_name_up = (guchar *) g_ascii_strup ((const gchar *) a_alias_name, -1); for (i = 0; gv_default_aliases[i].name; i++) { if (!strcmp (gv_default_aliases[i].name, (const gchar *) alias_name_up)) { diff --git a/src/libcroco/cr-input.c b/src/libcroco/cr-input.c index 5395ae214..732068aff 100644 --- a/src/libcroco/cr-input.c +++ b/src/libcroco/cr-input.c @@ -722,6 +722,8 @@ cr_input_consume_white_spaces (CRInput * a_this, gulong * a_nb_chars) } + *a_nb_chars = (gulong) nb_consumed; + if (nb_consumed && status == CR_END_OF_INPUT_ERROR) { status = CR_OK; } diff --git a/src/libcroco/cr-sel-eng.c b/src/libcroco/cr-sel-eng.c index ed40de393..6f496df2f 100644 --- a/src/libcroco/cr-sel-eng.c +++ b/src/libcroco/cr-sel-eng.c @@ -139,7 +139,7 @@ lang_pseudo_class_handler (CRSelEng *const a_this, /* "xml:lang" needed for SVG */ if ( (strqcmp (a_sel->content.pseudo->name->stryng->str, "lang", 4 ) && (strqcmp (a_sel->content.pseudo->name->stryng->str, "xml:lang", 8 ) ) ) - || !a_sel->content.pseudo->type == FUNCTION_PSEUDO) { + || a_sel->content.pseudo->type != FUNCTION_PSEUDO) { cr_utils_trace_info ("This handler is for :lang only"); return FALSE; } @@ -180,7 +180,7 @@ first_child_pseudo_class_handler (CRSelEng *const a_this, if (strcmp (a_sel->content.pseudo->name->stryng->str, "first-child") - || !a_sel->content.pseudo->type == IDENT_PSEUDO) { + || a_sel->content.pseudo->type != IDENT_PSEUDO) { cr_utils_trace_info ("This handler is for :first-child only"); return FALSE; } diff --git a/src/libcroco/cr-simple-sel.c b/src/libcroco/cr-simple-sel.c index a4670fe88..4df93fa77 100644 --- a/src/libcroco/cr-simple-sel.c +++ b/src/libcroco/cr-simple-sel.c @@ -254,7 +254,7 @@ cr_simple_sel_compute_specificity (CRSimpleSel * a_this) g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); for (cur_sel = a_this; cur_sel; cur_sel = cur_sel->next) { - if (cur_sel->type_mask | TYPE_SELECTOR) { + if (cur_sel->type_mask & TYPE_SELECTOR) { c++; /*hmmh, is this a new language ? */ } else if (!cur_sel->name || !cur_sel->name->stryng diff --git a/src/libcroco/cr-tknzr.c b/src/libcroco/cr-tknzr.c index 228471bf9..83f6ab3c0 100644 --- a/src/libcroco/cr-tknzr.c +++ b/src/libcroco/cr-tknzr.c @@ -1902,6 +1902,8 @@ cr_tknzr_seek_index (CRTknzr * a_this, enum CRSeekPos a_origin, gint a_pos) enum CRStatus cr_tknzr_consume_chars (CRTknzr * a_this, guint32 a_char, glong * a_nb_char) { + gulong consumed = *(gulong *) a_nb_char; + enum CRStatus status; g_return_val_if_fail (a_this && PRIVATE (a_this) && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); @@ -1912,8 +1914,10 @@ cr_tknzr_consume_chars (CRTknzr * a_this, guint32 a_char, glong * a_nb_char) PRIVATE (a_this)->token_cache = NULL; } - return cr_input_consume_chars (PRIVATE (a_this)->input, - a_char, a_nb_char); + status = cr_input_consume_chars (PRIVATE (a_this)->input, + a_char, &consumed); + *a_nb_char = (glong) consumed; + return status; } enum CRStatus -- cgit v1.2.3 From 2ca0f70c0eb69bae5b498d568c9edde85784aead Mon Sep 17 00:00:00 2001 From: Yuri Chornoivan Date: Sat, 26 Dec 2015 20:37:12 +0100 Subject: minor typos (mail to inkscape-translator) (bzr r14541) --- src/extension/param/string.cpp | 2 +- src/style.cpp | 4 ++-- src/widgets/measure-toolbar.cpp | 2 +- src/widgets/spray-toolbar.cpp | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/extension/param/string.cpp b/src/extension/param/string.cpp index 4e525ff73..1d9205502 100644 --- a/src/extension/param/string.cpp +++ b/src/extension/param/string.cpp @@ -132,7 +132,7 @@ public: if (_pref->get(NULL, NULL) != NULL) { this->set_text(Glib::ustring(_pref->get(NULL, NULL))); } - this->set_max_length(_pref->getMaxLength()); //Set the max lenght - default zero means no maximum + this->set_max_length(_pref->getMaxLength()); //Set the max length - default zero means no maximum this->signal_changed().connect(sigc::mem_fun(this, &ParamStringEntry::changed_text)); }; void changed_text (void); diff --git a/src/style.cpp b/src/style.cpp index 2a216e940..35138d25b 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -287,7 +287,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &color ); // 'font-size'/'font' must be before properties that need to know em, ex size (SPILength, - // SPILenghtOrNormal) + // SPILengthOrNormal) _properties.push_back( &font_style ); _properties.push_back( &font_variant ); _properties.push_back( &font_weight ); @@ -383,7 +383,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // // 'color' must be before 'fill', 'stroke', 'text-decoration-color', ... // _propmap.insert( std::make_pair( color.name, reinterpret_cast(&SPStyle::color ) ) ); - // // 'font-size' must be before properties that need to know em, ex size (SPILength, SPILenghtOrNormal) + // // 'font-size' must be before properties that need to know em, ex size (SPILength, SPILengthOrNormal) // _propmap.insert( std::make_pair( font_style.name, reinterpret_cast(&SPStyle::font_style ) ) ); // _propmap.insert( std::make_pair( font_variant.name, reinterpret_cast(&SPStyle::font_variant ) ) ); // _propmap.insert( std::make_pair( font_weight.name, reinterpret_cast(&SPStyle::font_weight ) ) ); diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 67c128dd2..f48dcd4e0 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -210,7 +210,7 @@ sp_toggle_show_in_between( GtkToggleAction* act, gpointer data ) if ( active ) { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Compute all elements.")); } else { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Compute max lenght.")); + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Compute max length.")); } MeasureTool *mt = get_measure_tool(); if (mt) { diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 30e9c6418..c4fbbca82 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -476,8 +476,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Picker */ { InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction", - _("Pick color from the drawing. You can use clonetiler trace dialog for avanced effects. In clone mode original fill or stroke colors must be unset."), - _("Pick color from the drawing. You can use clonetiler trace dialog for avanced effects. In clone mode original fill or stroke colors must be unset."), + _("Pick color from the drawing. You can use clonetiler trace dialog for advanced effects. In clone mode original fill or stroke colors must be unset."), + _("Pick color from the drawing. You can use clonetiler trace dialog for advanced effects. In clone mode original fill or stroke colors must be unset."), INKSCAPE_ICON("color-picker"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picker", false) ); @@ -502,8 +502,8 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj /* Inverse Value Size */ { InkToggleAction* act = ink_toggle_action_new( "SprayPickInverseValueAction", - _("Inversed pick value, retaining color in advanced trace mode"), - _("Inversed pick value, retaining color in advanced trace mode"), + _("Inverted pick value, retaining color in advanced trace mode"), + _("Inverted pick value, retaining color in advanced trace mode"), INKSCAPE_ICON("object-tweak-shrink"), secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_inverse_value", false) ); -- cgit v1.2.3 From bd6d862b36eff6c0026fd0c2e8a183095b4dc2cc Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 26 Dec 2015 20:19:12 +0000 Subject: Separate C++-specific compiler flags to avoid C warnings about C++11 compatibility (bzr r14542) --- src/Makefile.am | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 27d4fb844..087a727de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,6 +40,7 @@ noinst_LIBRARIES = \ all_libs = \ $(noinst_LIBRARIES) \ $(INKSCAPE_LIBS) \ + $(INKSCAPE_CXX_DEPS_LIBS) \ $(EXIF_LIBS) \ $(GNOME_VFS_LIBS) \ $(XFT_LIBS) \ @@ -65,6 +66,10 @@ BUILT_SOURCES = # Extra files to distribute EXTRA_DIST = +# C++-specific flags defined here +AM_CXXFLAGS = \ + $(INKSCAPE_CXX_DEPS_CFLAGS) + AM_CPPFLAGS = \ -I$(top_srcdir)/cxxtest \ -I$(builddir)/extension/dbus \ -- cgit v1.2.3 From edf1e6f457cdf895bae7dc03967561d850702c04 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 26 Dec 2015 23:02:45 +0000 Subject: Replace deprecated GC direct variable access. (bzr r14543) --- src/inkgc/gc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/inkgc/gc.cpp b/src/inkgc/gc.cpp index 90c02d9c8..ffa94ea2a 100644 --- a/src/inkgc/gc.cpp +++ b/src/inkgc/gc.cpp @@ -28,9 +28,9 @@ void display_warning(char *msg, GC_word arg) { } void do_init() { - GC_no_dls = 1; - GC_all_interior_pointers = 1; - GC_finalize_on_demand = 0; + GC_set_no_dls(1); + GC_set_all_interior_pointers(1); + GC_set_finalize_on_demand(0); GC_INIT(); -- cgit v1.2.3 From aa0ce3f41a366589a46f6013438cf2a8a648e8e1 Mon Sep 17 00:00:00 2001 From: Alexandre Prokoudine Date: Sun, 27 Dec 2015 02:47:49 +0300 Subject: Mark user-visible message for translation (bzr r14544) --- src/verbs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/verbs.cpp b/src/verbs.cpp index ed4b1ceb0..fd7eea2d5 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1588,7 +1588,7 @@ void TagVerb::perform( SPAction *action, void *data) id=NULL; do { g_free(id); - id = g_strdup_printf("Set %d", tag_suffix++); + id = g_strdup_printf(_("Set %d"), tag_suffix++); } while (dt->doc()->getObjectById(id)); doc = dt->doc()->getReprDoc(); -- cgit v1.2.3 From 21713dba2790f08a8c8a14131e73ab0332819488 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 27 Dec 2015 10:28:29 +0000 Subject: Fix more GThreads issues (bzr r14546) --- src/extension/param/parameter.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/extension/param/parameter.cpp b/src/extension/param/parameter.cpp index 8c99ee55d..10029893f 100644 --- a/src/extension/param/parameter.cpp +++ b/src/extension/param/parameter.cpp @@ -15,22 +15,19 @@ # include "config.h" #endif -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - #ifdef linux // does the dollar sign need escaping when passed as string parameter? # define ESCAPE_DOLLAR_COMMANDLINE #endif #include + +#include "ui/widget/color-notebook.h" #include #include #include "document-private.h" #include "sp-object.h" #include -#include "ui/widget/color-notebook.h" #include "parameter.h" #include "bool.h" -- cgit v1.2.3 From 926cd79383db18f325adfbc24be8bb4fd32f06b9 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 27 Dec 2015 17:08:31 +0000 Subject: Apply Tav/suv patch to replace Pango OT functions with Harfbuzz Fixed bugs: - https://launchpad.net/bugs/1488159 (bzr r14549) --- src/libnrtype/FontFactory.cpp | 129 +++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 65eb62dda..728902e22 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -24,6 +24,10 @@ #include "util/unordered-containers.h" #include +#include +#include +#include + typedef INK_UNORDERED_MAP FaceMapType; // need to avoid using the size field @@ -99,7 +103,10 @@ font_factory::font_factory(void) : fontSize(512), loadedPtr(new FaceMapType()) { - // std::cout << pango_version_string() << std::endl; + // std::cout << "FontFactory(): Pango Version (run time): " + // << pango_version_string() << std::endl; + // std::cout << "FontFactory(): Pango Version (compile time): " + // << PANGO_VERSION_STRING << std::endl; #ifdef USE_PANGO_WIN32 #else pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fontServer), @@ -593,13 +600,15 @@ font_instance* font_factory::FaceFromFontSpecification(char const *fontSpecifica return font; } -void dump_tag( guint32 *tag, Glib::ustring prefix = "" ) { +void dump_tag( guint32 *tag, Glib::ustring prefix = "", bool lf=true ) { std::cout << prefix << ((char)((*tag & 0xff000000)>>24)) << ((char)((*tag & 0x00ff0000)>>16)) << ((char)((*tag & 0x0000ff00)>>8)) - << ((char)((*tag & 0x000000ff)>>0)) - << std::endl; + << ((char)((*tag & 0x000000ff)>>0)); + if( lf ) { + std::cout << std::endl; + } } Glib::ustring extract_tag( guint32 *tag ) { @@ -677,74 +686,66 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) } // Extract which OpenType tables are in the font. We'll make a list of all tables - // regardless of which script and langauge they are in. These functions are deprecated but - // will eventually be replaced by newer functions (according to Behdad). - PangoOTInfo* info = pango_ot_info_get( res->theFace ); - - PangoOTTag* scripts = pango_ot_info_list_scripts( info, PANGO_OT_TABLE_GSUB ); - // std::cout << " scripts: " << std::endl; - for( unsigned i = 0; scripts[i] != 0; ++i ) { - // dump_tag( &scripts[i], " " ); - - guint script_index = -1; - if( pango_ot_info_find_script( info, PANGO_OT_TABLE_GSUB, scripts[i], &script_index )) { - - PangoOTTag* languages = - pango_ot_info_list_languages( info, PANGO_OT_TABLE_GSUB, script_index, NULL); - // if( languages[0] != 0 ) - // std::cout << " languages: " << std::endl; - - for( unsigned j = 0; languages[j] != 0; ++j ) { - // dump_tag( &languages[j], " lang: "); - - guint language_index = -1; - if( pango_ot_info_find_language(info, PANGO_OT_TABLE_GSUB, script_index, languages[j], &language_index, NULL)) { - - PangoOTTag* features = - pango_ot_info_list_features( info, PANGO_OT_TABLE_GSUB, 0, i, j ); - if( features[0] != 0 ) - // std::cout << " features: " << std::endl; - - for( unsigned k = 0; features[k] != 0; ++k ) { - // dump_tag( &features[k], " feature: "); - ++(res->openTypeTables[ extract_tag(&features[k])]); - } - g_free( features ); - } else { - // std::cout << " No languages defined" << std::endl; - PangoOTTag* features = - pango_ot_info_list_features( info, PANGO_OT_TABLE_GSUB, 0, i, PANGO_OT_DEFAULT_LANGUAGE ); - // if( features[0] != 0 ) - // std::cout << " default features: " << std::endl; - - for( unsigned k = 0; features[k] != 0; ++k ) { - // dump_tag( &features[k], " feature: " ); - ++(res->openTypeTables[ extract_tag(&features[k])]); - } - g_free( features ); + // regardless of which script and langauge they are in. This Harfbuzz code replaces + // an ealier Pango version as the Pango functions are depricated. + + // Empty map... bitmap fonts seem to be loaded multiple times. + res->openTypeTables.clear(); + + hb_face_t *hb_face = hb_ft_face_create(res->theFace, NULL); + + // First time to get size of array + unsigned int script_count = hb_ot_layout_table_get_script_tags(hb_face, HB_OT_TAG_GSUB, 0, NULL, NULL); + hb_tag_t *scripts_hb = g_new(hb_tag_t, script_count + 1 ); + + // Second time to fill array (this two step process was not neccessary with Pango + hb_ot_layout_table_get_script_tags (hb_face, HB_OT_TAG_GSUB, 0, &script_count, scripts_hb); + + // std::cout << " scripts: " << script_count << std::endl; + for( unsigned i = 0; i < script_count; ++i ) { + // dump_tag( &scripts_hb[i], " " ); + unsigned int language_count = hb_ot_layout_script_get_language_tags(hb_face, HB_OT_TAG_GSUB, i, 0, NULL, NULL); + if( language_count > 0 ) { + hb_tag_t *languages_hb = g_new( hb_tag_t, language_count + 1 ); + hb_ot_layout_script_get_language_tags(hb_face, HB_OT_TAG_GSUB, i, 0, &language_count, languages_hb); + + for( unsigned j = 0; j < language_count; ++j ) { + // dump_tag( &languages_hb[j], " " ); + unsigned int feature_count = + hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, j, 0, NULL, NULL); + hb_tag_t *features_hb = g_new( hb_tag_t, feature_count + 1 ); + hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, j, 0, &feature_count, features_hb); + + for( unsigned k = 0; k < feature_count; ++k ) { + // dump_tag( &features_hb[k], " " ); + + ++(res->openTypeTables[ extract_tag(&features_hb[k])]); } + g_free(features_hb); } - g_free( languages ); - } else { - // std::cout << " No scripts defined! " << std::endl; + g_free(languages_hb); + } + { + // Even if no languages are present there is still the default. + unsigned int feature_count = + hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, 0, NULL, NULL); + hb_tag_t *features_hb = g_new( hb_tag_t, feature_count + 1 ); + hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, 0, &feature_count, features_hb); + + for( unsigned k = 0; k < feature_count; ++k ) { + // dump_tag( &features_hb[k], " " ); + ++(res->openTypeTables[ extract_tag(&features_hb[k])]); + } + g_free(features_hb); } } - g_free( scripts ); - - PangoOTTag* features = - pango_ot_info_list_features( info, PANGO_OT_TABLE_GSUB, 0, 0, PANGO_OT_DEFAULT_LANGUAGE ); - // if( features[0] != 0 ) - // std::cout << " DFTL DFTL features: " << std::endl; - for( unsigned i = 0; features[i] != 0; ++i ) { - // dump_tag( &features[i], " feature: " ); - ++(res->openTypeTables[ extract_tag(&features[i])]); - } + g_free( scripts_hb ); + // hb_face_destroy(hb_face); + // std::map::iterator it; // for( it = res->openTypeTables.begin(); it != res->openTypeTables.end(); ++it) { // std::cout << "Table: " << it->first << " Occurances: " << it->second << std::endl; // } - g_free( features ); - } else { // already here res = loadedFaces[descr]; -- cgit v1.2.3 From 9944a1a48890ac3d45c8c2d1e67b91403b461f04 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 27 Dec 2015 17:33:13 +0000 Subject: Remove superfluous glibmm/threads.h checks (bzr r14550) --- src/widgets/gradient-selector.cpp | 4 ---- src/widgets/sp-color-selector.cpp | 4 ---- src/widgets/sp-color-selector.h | 4 ---- 3 files changed, 12 deletions(-) (limited to 'src') diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index 63599f3f9..604ecd108 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -17,10 +17,6 @@ # include "config.h" #endif -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - #include #include "gradient-vector.h" diff --git a/src/widgets/sp-color-selector.cpp b/src/widgets/sp-color-selector.cpp index dad0a18b0..93eaaee8b 100644 --- a/src/widgets/sp-color-selector.cpp +++ b/src/widgets/sp-color-selector.cpp @@ -7,10 +7,6 @@ # include "config.h" #endif -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - #include #include #include diff --git a/src/widgets/sp-color-selector.h b/src/widgets/sp-color-selector.h index 308a5519c..75cb79b00 100644 --- a/src/widgets/sp-color-selector.h +++ b/src/widgets/sp-color-selector.h @@ -5,10 +5,6 @@ # include #endif -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - #include #include "color.h" -- cgit v1.2.3 From b9e569809a4e82a5593c114c5839ae060c220b67 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 27 Dec 2015 18:35:20 +0000 Subject: Revert Pango/Harfbuzz fixes. Needs work (bzr r14552) --- src/libnrtype/FontFactory.cpp | 129 +++++++++++++++++++------------------- src/widgets/gradient-selector.cpp | 4 ++ src/widgets/sp-color-selector.cpp | 4 ++ src/widgets/sp-color-selector.h | 4 ++ 4 files changed, 76 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 728902e22..65eb62dda 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -24,10 +24,6 @@ #include "util/unordered-containers.h" #include -#include -#include -#include - typedef INK_UNORDERED_MAP FaceMapType; // need to avoid using the size field @@ -103,10 +99,7 @@ font_factory::font_factory(void) : fontSize(512), loadedPtr(new FaceMapType()) { - // std::cout << "FontFactory(): Pango Version (run time): " - // << pango_version_string() << std::endl; - // std::cout << "FontFactory(): Pango Version (compile time): " - // << PANGO_VERSION_STRING << std::endl; + // std::cout << pango_version_string() << std::endl; #ifdef USE_PANGO_WIN32 #else pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fontServer), @@ -600,15 +593,13 @@ font_instance* font_factory::FaceFromFontSpecification(char const *fontSpecifica return font; } -void dump_tag( guint32 *tag, Glib::ustring prefix = "", bool lf=true ) { +void dump_tag( guint32 *tag, Glib::ustring prefix = "" ) { std::cout << prefix << ((char)((*tag & 0xff000000)>>24)) << ((char)((*tag & 0x00ff0000)>>16)) << ((char)((*tag & 0x0000ff00)>>8)) - << ((char)((*tag & 0x000000ff)>>0)); - if( lf ) { - std::cout << std::endl; - } + << ((char)((*tag & 0x000000ff)>>0)) + << std::endl; } Glib::ustring extract_tag( guint32 *tag ) { @@ -686,66 +677,74 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) } // Extract which OpenType tables are in the font. We'll make a list of all tables - // regardless of which script and langauge they are in. This Harfbuzz code replaces - // an ealier Pango version as the Pango functions are depricated. - - // Empty map... bitmap fonts seem to be loaded multiple times. - res->openTypeTables.clear(); - - hb_face_t *hb_face = hb_ft_face_create(res->theFace, NULL); - - // First time to get size of array - unsigned int script_count = hb_ot_layout_table_get_script_tags(hb_face, HB_OT_TAG_GSUB, 0, NULL, NULL); - hb_tag_t *scripts_hb = g_new(hb_tag_t, script_count + 1 ); - - // Second time to fill array (this two step process was not neccessary with Pango - hb_ot_layout_table_get_script_tags (hb_face, HB_OT_TAG_GSUB, 0, &script_count, scripts_hb); - - // std::cout << " scripts: " << script_count << std::endl; - for( unsigned i = 0; i < script_count; ++i ) { - // dump_tag( &scripts_hb[i], " " ); - unsigned int language_count = hb_ot_layout_script_get_language_tags(hb_face, HB_OT_TAG_GSUB, i, 0, NULL, NULL); - if( language_count > 0 ) { - hb_tag_t *languages_hb = g_new( hb_tag_t, language_count + 1 ); - hb_ot_layout_script_get_language_tags(hb_face, HB_OT_TAG_GSUB, i, 0, &language_count, languages_hb); - - for( unsigned j = 0; j < language_count; ++j ) { - // dump_tag( &languages_hb[j], " " ); - unsigned int feature_count = - hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, j, 0, NULL, NULL); - hb_tag_t *features_hb = g_new( hb_tag_t, feature_count + 1 ); - hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, j, 0, &feature_count, features_hb); - - for( unsigned k = 0; k < feature_count; ++k ) { - // dump_tag( &features_hb[k], " " ); - - ++(res->openTypeTables[ extract_tag(&features_hb[k])]); + // regardless of which script and langauge they are in. These functions are deprecated but + // will eventually be replaced by newer functions (according to Behdad). + PangoOTInfo* info = pango_ot_info_get( res->theFace ); + + PangoOTTag* scripts = pango_ot_info_list_scripts( info, PANGO_OT_TABLE_GSUB ); + // std::cout << " scripts: " << std::endl; + for( unsigned i = 0; scripts[i] != 0; ++i ) { + // dump_tag( &scripts[i], " " ); + + guint script_index = -1; + if( pango_ot_info_find_script( info, PANGO_OT_TABLE_GSUB, scripts[i], &script_index )) { + + PangoOTTag* languages = + pango_ot_info_list_languages( info, PANGO_OT_TABLE_GSUB, script_index, NULL); + // if( languages[0] != 0 ) + // std::cout << " languages: " << std::endl; + + for( unsigned j = 0; languages[j] != 0; ++j ) { + // dump_tag( &languages[j], " lang: "); + + guint language_index = -1; + if( pango_ot_info_find_language(info, PANGO_OT_TABLE_GSUB, script_index, languages[j], &language_index, NULL)) { + + PangoOTTag* features = + pango_ot_info_list_features( info, PANGO_OT_TABLE_GSUB, 0, i, j ); + if( features[0] != 0 ) + // std::cout << " features: " << std::endl; + + for( unsigned k = 0; features[k] != 0; ++k ) { + // dump_tag( &features[k], " feature: "); + ++(res->openTypeTables[ extract_tag(&features[k])]); + } + g_free( features ); + } else { + // std::cout << " No languages defined" << std::endl; + PangoOTTag* features = + pango_ot_info_list_features( info, PANGO_OT_TABLE_GSUB, 0, i, PANGO_OT_DEFAULT_LANGUAGE ); + // if( features[0] != 0 ) + // std::cout << " default features: " << std::endl; + + for( unsigned k = 0; features[k] != 0; ++k ) { + // dump_tag( &features[k], " feature: " ); + ++(res->openTypeTables[ extract_tag(&features[k])]); + } + g_free( features ); } - g_free(features_hb); - } - g_free(languages_hb); - } - { - // Even if no languages are present there is still the default. - unsigned int feature_count = - hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, 0, NULL, NULL); - hb_tag_t *features_hb = g_new( hb_tag_t, feature_count + 1 ); - hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, 0, &feature_count, features_hb); - - for( unsigned k = 0; k < feature_count; ++k ) { - // dump_tag( &features_hb[k], " " ); - ++(res->openTypeTables[ extract_tag(&features_hb[k])]); } - g_free(features_hb); + g_free( languages ); + } else { + // std::cout << " No scripts defined! " << std::endl; } } - g_free( scripts_hb ); - // hb_face_destroy(hb_face); - + g_free( scripts ); + + PangoOTTag* features = + pango_ot_info_list_features( info, PANGO_OT_TABLE_GSUB, 0, 0, PANGO_OT_DEFAULT_LANGUAGE ); + // if( features[0] != 0 ) + // std::cout << " DFTL DFTL features: " << std::endl; + for( unsigned i = 0; features[i] != 0; ++i ) { + // dump_tag( &features[i], " feature: " ); + ++(res->openTypeTables[ extract_tag(&features[i])]); + } // std::map::iterator it; // for( it = res->openTypeTables.begin(); it != res->openTypeTables.end(); ++it) { // std::cout << "Table: " << it->first << " Occurances: " << it->second << std::endl; // } + g_free( features ); + } else { // already here res = loadedFaces[descr]; diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index 604ecd108..63599f3f9 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -17,6 +17,10 @@ # include "config.h" #endif +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + #include #include "gradient-vector.h" diff --git a/src/widgets/sp-color-selector.cpp b/src/widgets/sp-color-selector.cpp index 93eaaee8b..dad0a18b0 100644 --- a/src/widgets/sp-color-selector.cpp +++ b/src/widgets/sp-color-selector.cpp @@ -7,6 +7,10 @@ # include "config.h" #endif +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + #include #include #include diff --git a/src/widgets/sp-color-selector.h b/src/widgets/sp-color-selector.h index 75cb79b00..308a5519c 100644 --- a/src/widgets/sp-color-selector.h +++ b/src/widgets/sp-color-selector.h @@ -5,6 +5,10 @@ # include #endif +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + #include #include "color.h" -- cgit v1.2.3 From 5d0daf518c59355e7cef239d6a5ae25804569a9c Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 27 Dec 2015 18:38:12 +0000 Subject: Remove superfluous glibmm/threads.h checks (bzr r14553) --- src/widgets/gradient-selector.cpp | 4 ---- src/widgets/sp-color-selector.cpp | 4 ---- src/widgets/sp-color-selector.h | 4 ---- 3 files changed, 12 deletions(-) (limited to 'src') diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index 63599f3f9..604ecd108 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -17,10 +17,6 @@ # include "config.h" #endif -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - #include #include "gradient-vector.h" diff --git a/src/widgets/sp-color-selector.cpp b/src/widgets/sp-color-selector.cpp index dad0a18b0..93eaaee8b 100644 --- a/src/widgets/sp-color-selector.cpp +++ b/src/widgets/sp-color-selector.cpp @@ -7,10 +7,6 @@ # include "config.h" #endif -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - #include #include #include diff --git a/src/widgets/sp-color-selector.h b/src/widgets/sp-color-selector.h index 308a5519c..75cb79b00 100644 --- a/src/widgets/sp-color-selector.h +++ b/src/widgets/sp-color-selector.h @@ -5,10 +5,6 @@ # include #endif -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - #include #include "color.h" -- cgit v1.2.3 From 877710a8135b68a0ffd01a9a6e7734220bc9cab0 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 27 Dec 2015 19:20:50 +0000 Subject: Remove more superfluous glibmm/threads.h checking (bzr r14554) --- src/ui/dialog/tags.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index 9b6f3219f..cbb2fb953 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -13,10 +13,6 @@ # include #endif -#if WITH_GLIBMM_2_32 -# include -#endif - #include "tags.h" #include #include -- cgit v1.2.3 From fe412c234e1126a39a1b229cd1117f614567c148 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 27 Dec 2015 23:47:12 +0000 Subject: Fix GTK+ fullscreen issue Fixed bugs: - https://launchpad.net/bugs/1529521 (bzr r14555) --- src/inkview.cpp | 4 ---- src/verbs.cpp | 4 ---- src/verbs.h | 3 --- src/widgets/desktop-widget.cpp | 2 -- 4 files changed, 13 deletions(-) (limited to 'src') diff --git a/src/inkview.cpp b/src/inkview.cpp index 8b7492798..aab4b4a20 100644 --- a/src/inkview.cpp +++ b/src/inkview.cpp @@ -126,7 +126,6 @@ sp_svgview_main_key_press (GtkWidget */*widget*/, GdkEventKey *event, struct SPS sp_svgview_goto_last(ss); break; case GDK_KEY_F11: -#ifdef HAVE_GTK_WINDOW_FULLSCREEN if (ss->fullscreen) { gtk_window_unfullscreen (GTK_WINDOW(ss->window)); ss->fullscreen = false; @@ -134,9 +133,6 @@ sp_svgview_main_key_press (GtkWidget */*widget*/, GdkEventKey *event, struct SPS gtk_window_fullscreen (GTK_WINDOW(ss->window)); ss->fullscreen = true; } -#else - std::cout<<"Your GTK+ does not support fullscreen mode. Upgrade to 2.2."<toggleGrids(); break; -#ifdef HAVE_GTK_WINDOW_FULLSCREEN case SP_VERB_FULLSCREEN: dt->fullscreen(); break; @@ -1958,7 +1957,6 @@ void ZoomVerb::perform(SPAction *action, void *data) dt->fullscreen(); dt->focusMode(!dt->is_fullscreen()); break; -#endif // HAVE_GTK_WINDOW_FULLSCREEN case SP_VERB_FOCUSTOGGLE: dt->focusMode(!dt->is_focusMode()); break; @@ -2852,12 +2850,10 @@ Verb *Verb::_base_verbs[] = { INKSCAPE_ICON("zoom-half-size")), new ZoomVerb(SP_VERB_ZOOM_2_1, "Zoom2:1", N_("_Zoom 2:1"), N_("Zoom to 2:1"), INKSCAPE_ICON("zoom-double-size")), -#ifdef HAVE_GTK_WINDOW_FULLSCREEN new ZoomVerb(SP_VERB_FULLSCREEN, "FullScreen", N_("_Fullscreen"), N_("Stretch this document window to full screen"), INKSCAPE_ICON("view-fullscreen")), new ZoomVerb(SP_VERB_FULLSCREENFOCUS, "FullScreenFocus", N_("Fullscreen & Focus Mode"), N_("Stretch this document window to full screen"), INKSCAPE_ICON("view-fullscreen")), -#endif // HAVE_GTK_WINDOW_FULLSCREEN new ZoomVerb(SP_VERB_FOCUSTOGGLE, "FocusToggle", N_("Toggle _Focus Mode"), N_("Remove excess toolbars to focus on drawing"), NULL), new ZoomVerb(SP_VERB_VIEW_NEW, "ViewNew", N_("Duplic_ate Window"), N_("Open a new window with the same document"), diff --git a/src/verbs.h b/src/verbs.h index e16acb2d1..4f453761e 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -19,7 +19,6 @@ #include #include -//#include "require-config.h" /* HAVE_GTK_WINDOW_FULLSCREEN */ #include struct SPAction; @@ -262,10 +261,8 @@ enum { SP_VERB_ZOOM_1_1, SP_VERB_ZOOM_1_2, SP_VERB_ZOOM_2_1, -#ifdef HAVE_GTK_WINDOW_FULLSCREEN SP_VERB_FULLSCREEN, SP_VERB_FULLSCREENFOCUS, -#endif /* HAVE_GTK_WINDOW_FULLSCREEN */ SP_VERB_FOCUSTOGGLE, SP_VERB_VIEW_NEW, SP_VERB_VIEW_NEW_PREVIEW, diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index da7a54ca0..1fdd3ca6d 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1500,7 +1500,6 @@ sp_desktop_widget_maximize(SPDesktopWidget *dtw) void sp_desktop_widget_fullscreen(SPDesktopWidget *dtw) { -#ifdef HAVE_GTK_WINDOW_FULLSCREEN GtkWindow *topw = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(dtw->canvas))); if (GTK_IS_WINDOW(topw)) { if (dtw->desktop->is_fullscreen()) { @@ -1524,7 +1523,6 @@ sp_desktop_widget_fullscreen(SPDesktopWidget *dtw) // widget layout is triggered by the resulting window_state_event } } -#endif /* HAVE_GTK_WINDOW_FULLSCREEN */ } /** -- cgit v1.2.3 From c5ee3ce4be0f65a00b5908a9051cdb470d805192 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 28 Dec 2015 09:50:50 +0100 Subject: Corrects attribute name for saving page 'checkerboard' background state. Fixed bugs: - https://launchpad.net/bugs/1529391 (bzr r14556) --- src/attributes.cpp | 2 +- src/sp-namedview.cpp | 2 +- src/ui/dialog/document-properties.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index dcd644b5d..e32f4ece4 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -82,7 +82,7 @@ static SPStyleProp const props[] = { {SP_ATTR_FIT_MARGIN_LEFT, "fit-margin-left"}, {SP_ATTR_FIT_MARGIN_RIGHT, "fit-margin-right"}, {SP_ATTR_FIT_MARGIN_BOTTOM, "fit-margin-bottom"}, - {SP_ATTR_INKSCAPE_PAGECHECKERBOARD, "inkscape:checkerboard"}, + {SP_ATTR_INKSCAPE_PAGECHECKERBOARD, "inkscape:pagecheckerboard"}, {SP_ATTR_INKSCAPE_PAGEOPACITY, "inkscape:pageopacity"}, {SP_ATTR_INKSCAPE_PAGESHADOW, "inkscape:pageshadow"}, {SP_ATTR_INKSCAPE_ZOOM, "inkscape:zoom"}, diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 0942081ca..9598a14ec 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -393,7 +393,7 @@ void SPNamedView::set(unsigned int key, const gchar* value) { this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_INKSCAPE_PAGECHECKERBOARD: - this->pagecheckerboard = (value) ? sp_str_to_bool (value) : TRUE; + this->pagecheckerboard = (value) ? sp_str_to_bool (value) : false; this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_INKSCAPE_PAGEOPACITY: diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 030bbbf7b..7cd48e62e 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -116,11 +116,11 @@ DocumentProperties::DocumentProperties() _page_metadata2(Gtk::manage(new UI::Widget::NotebookPage(1, 1))), //--------------------------------------------------------------- _rcb_antialias(_("Use antialiasing"), _("If unset, no antialiasing will be done on the drawing"), "shape-rendering", _wr, false, NULL, NULL, NULL, "crispEdges"), - _rcb_checkerboard(_("Checkerboard background"), _("If set, use checkerboard for background, otherwise use background color at full opacity."), "inkscape:checkerboard", _wr, false), + _rcb_checkerboard(_("Checkerboard background"), _("If set, use checkerboard for background, otherwise use background color at full opacity."), "inkscape:pagecheckerboard", _wr, false), _rcb_canb(_("Show page _border"), _("If set, rectangular page border is shown"), "showborder", _wr, false), _rcb_bord(_("Border on _top of drawing"), _("If set, border is always on top of the drawing"), "borderlayer", _wr, false), _rcb_shad(_("_Show border shadow"), _("If set, page border shows a shadow on its right and lower side"), "inkscape:showpageshadow", _wr, false), - _rcp_bg(_("Back_ground color:"), _("Background color"), _("Color of the page background. Note: transparency setting ignored while editing if 'Checkerboard background' set (but used when exporting to bitmap)."), "pagecolor", "inkscape:pageopacity", _wr), + _rcp_bg(_("Back_ground color:"), _("Background color"), _("Color of the page background. Note: transparency setting ignored while editing if 'Checkerboard background' unset (but used when exporting to bitmap)."), "pagecolor", "inkscape:pageopacity", _wr), _rcp_bord(_("Border _color:"), _("Page border color"), _("Color of the page border"), "bordercolor", "borderopacity", _wr), _rum_deflt(_("Display _units:"), "inkscape:document-units", _wr), _page_sizer(_wr), -- cgit v1.2.3 From 31c14638d661559cfb5aeda90c6854eb25934c39 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Thu, 31 Dec 2015 10:07:17 +0000 Subject: Enable build with old libgc version Fixed bugs: - https://launchpad.net/bugs/1530286 (bzr r14558) --- src/inkgc/gc.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/inkgc/gc.cpp b/src/inkgc/gc.cpp index ffa94ea2a..9372ac693 100644 --- a/src/inkgc/gc.cpp +++ b/src/inkgc/gc.cpp @@ -28,9 +28,15 @@ void display_warning(char *msg, GC_word arg) { } void do_init() { +#if WITH_GC_7_2 GC_set_no_dls(1); GC_set_all_interior_pointers(1); GC_set_finalize_on_demand(0); +#else + GC_no_dls = 1; + GC_all_interior_pointers = 1; + GC_finalize_on_demand = 0; +#endif GC_INIT(); -- cgit v1.2.3 From eafe1b968031373fca51138b097faec41c80c9d7 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 2 Jan 2016 18:41:53 -0500 Subject: Remove two path requirement, there is some really good functionality with multiple paths we're missing out on. (bzr r14560) --- src/splivarot.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src') diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 726df6e20..9b2890bb8 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -342,13 +342,6 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool g_assert(!il.empty()); - if (il.size() > 2) { - if (bop == bool_op_diff || bop == bool_op_cut || bop == bool_op_slice ) { - boolop_display_error_message(desktop, _("Select exactly 2 paths to perform difference, division, or path cut.")); - return; - } - } - // reverseOrderForOp marks whether the order of the list is the top->down order // it's only used when there are 2 objects, and for operations who need to know the // topmost object (differences, cuts) -- cgit v1.2.3 From 695d61abbef5af697f01e1b046e5ecc89c9aab80 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 5 Jan 2016 16:30:09 +0100 Subject: Improve constant definitions (bzr r14561) --- src/live_effects/lpe-bspline.cpp | 4 ++-- src/ui/tool/node.cpp | 2 +- src/ui/tool/path-manipulator.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 7e92e767d..1423e670a 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -20,8 +20,8 @@ namespace LivePathEffect { const double HANDLE_CUBIC_GAP = 0.001; const double NO_POWER = 0.0; -const double DEFAULT_START_POWER = 0.333334; -const double DEFAULT_END_POWER = 0.666667; +const double DEFAULT_START_POWER = 1.0/3.0; +const double DEFAULT_END_POWER = 2.0/3.0; Geom::PathVector hp; void sp_bspline_drawHandle(Geom::Point p, double helper_size); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 06e49dc7f..d70147f80 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -61,7 +61,7 @@ namespace Inkscape { namespace UI { const double NO_POWER = 0.0; -const double DEFAULT_START_POWER = 0.333334; +const double DEFAULT_START_POWER = 1.0/3.0; ControlPoint::ColorSet Node::node_colors = { {0xbfbfbf00, 0x000000ff}, // normal fill, stroke diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index fb9e2c070..01dbf13e9 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -58,7 +58,7 @@ enum PathChange { } // anonymous namespace const double HANDLE_CUBIC_GAP = 0.001; const double NO_POWER = 0.0; -const double DEFAULT_START_POWER = 0.333334; +const double DEFAULT_START_POWER = 1.0/3.0; /** -- cgit v1.2.3 From fe78d7dbadf8d2337dfcf2a6130e988119efa3c0 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 5 Jan 2016 17:25:01 +0100 Subject: Fix wrong symm node type in BSpline converted to Bezier (bzr r14562) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 01dbf13e9..f4790c317 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1292,7 +1292,7 @@ double PathManipulator::_bsplineHandlePosition(Handle *h, bool check_other) line_inside_nodes->moveto(n->position()); line_inside_nodes->lineto(next_node->position()); if(!are_near(h->position(), n->position())){ - pos = Geom::nearest_time(Geom::Point(h->position()[X] - HANDLE_CUBIC_GAP, h->position()[Y] - HANDLE_CUBIC_GAP), *line_inside_nodes->first_segment()); + pos = Geom::nearest_time(Geom::Point(h->position()[X] - HANDLE_CUBIC_GAP, h->position()[Y] + HANDLE_CUBIC_GAP), *line_inside_nodes->first_segment()); } } if (pos == NO_POWER && check_other){ -- cgit v1.2.3 From 253da39319875724ef7345f8cc14ac75a31a4f2d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 6 Jan 2016 13:40:41 +0100 Subject: Fix crash when apply Bend From Clipboard to a clone by the pen/pencil toolbar (bzr r14563) --- src/ui/tools/freehand-base.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index a889a12e6..613857626 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -42,6 +42,7 @@ #include "selection-chemistry.h" #include "snap.h" #include "sp-path.h" +#include "sp-use.h" #include "sp-namedview.h" #include "live_effects/lpe-powerstroke.h" #include "style.h" @@ -271,7 +272,11 @@ static void spdc_apply_powerstroke_shape(const std::vector & points static void spdc_apply_bend_shape(gchar const *svgd, FreehandBase *dc, SPItem *item) { using namespace Inkscape::LivePathEffect; - if(!SP_LPE_ITEM(item)->hasPathEffectOfType(BEND_PATH)){ + SPUse *use = dynamic_cast(item); + if ( use ) { + return; + } + if(!SP_IS_LPE_ITEM(item) || !SP_LPE_ITEM(item)->hasPathEffectOfType(BEND_PATH)){ Effect::createAndApply(BEND_PATH, dc->desktop->doc(), item); } Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); -- cgit v1.2.3 From 70e49f7eba8a099a9f5e7f9bfd3ec78f3f1ec1a7 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 9 Jan 2016 10:52:04 +0100 Subject: Support rendering of radial gradients with the 'fr' attribute. New in SVG 2. (bzr r14569) --- src/attributes-test.h | 3 ++- src/attributes.cpp | 1 + src/attributes.h | 1 + src/extension/internal/cairo-render-context.cpp | 3 ++- src/sp-radial-gradient.cpp | 18 +++++++++++++++++- src/sp-radial-gradient.h | 1 + 6 files changed, 24 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/attributes-test.h b/src/attributes-test.h index 1fc3972c0..b8d5d98a5 100644 --- a/src/attributes-test.h +++ b/src/attributes-test.h @@ -42,7 +42,7 @@ public: SVG 2: white-space, shape-inside, shape-outside, shape-padding, shape-margin SVG 2: text-decoration-fill, text-decoration-stroke SVG 2: solid-color, solid-opacity - SVG 2: Hatches and Meshes + SVG 2: Hatches and Meshes, radial gradient 'fr' CSS 3: text-orientation CSS 3: font-variant-xxx, font-feature-settings */ @@ -145,6 +145,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = { {"from", true}, {"fx", true}, {"fy", true}, + {"fr", true}, {"g1", true}, {"g2", true}, {"glyph-name", true}, diff --git a/src/attributes.cpp b/src/attributes.cpp index e32f4ece4..646c2ab0c 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -294,6 +294,7 @@ static SPStyleProp const props[] = { /* SPRadialGradient */ {SP_ATTR_FX, "fx"}, {SP_ATTR_FY, "fy"}, + {SP_ATTR_FR, "fr"}, /* SPMeshPatch */ {SP_ATTR_TENSOR, "tensor"}, //{SP_ATTR_TYPE, "type"}, diff --git a/src/attributes.h b/src/attributes.h index 754cc876a..f5544d0a1 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -296,6 +296,7 @@ enum SPAttributeEnum { /* SPRadialGradient */ SP_ATTR_FX, SP_ATTR_FY, + SP_ATTR_FR, /* SPMeshPatch */ SP_ATTR_TENSOR, //SP_ATTR_TYPE, diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 8b7a22f21..f811f00ad 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -1245,11 +1245,12 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain Geom::Point c (rg->cx.computed, rg->cy.computed); Geom::Point f (rg->fx.computed, rg->fy.computed); double r = rg->r.computed; + double fr = rg->fr.computed; if (pbox && SP_GRADIENT(rg)->getUnits() == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) apply_bbox2user = true; // create radial gradient pattern - pattern = cairo_pattern_create_radial(f[Geom::X], f[Geom::Y], 0, c[Geom::X], c[Geom::Y], r); + pattern = cairo_pattern_create_radial(f[Geom::X], f[Geom::Y], fr, c[Geom::X], c[Geom::Y], r); // add stops for (gint i = 0; unsigned(i) < rg->vector.stops.size(); i++) { diff --git a/src/sp-radial-gradient.cpp b/src/sp-radial-gradient.cpp index 8fb230ba7..7175a8165 100644 --- a/src/sp-radial-gradient.cpp +++ b/src/sp-radial-gradient.cpp @@ -16,6 +16,7 @@ SPRadialGradient::SPRadialGradient() : SPGradient() { this->r.unset(SVGLength::PERCENT, 0.5, 0.5); this->fx.unset(SVGLength::PERCENT, 0.5, 0.5); this->fy.unset(SVGLength::PERCENT, 0.5, 0.5); + this->fr.unset(SVGLength::PERCENT, 0.5, 0.5); } SPRadialGradient::~SPRadialGradient() { @@ -32,6 +33,7 @@ void SPRadialGradient::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "r" ); this->readAttr( "fx" ); this->readAttr( "fy" ); + this->readAttr( "fr" ); } /** @@ -89,6 +91,13 @@ void SPRadialGradient::set(unsigned key, gchar const *value) { this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_FR: + if (!this->fr.read(value)) { + this->fr.unset(SVGLength::PERCENT, 0.5, 0.5); + } + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + default: SPGradient::set(key, value); break; @@ -123,6 +132,10 @@ Inkscape::XML::Node* SPRadialGradient::write(Inkscape::XML::Document *xml_doc, I sp_repr_set_svg_double(repr, "fy", this->fy.computed); } + if ((flags & SP_OBJECT_WRITE_ALL) || this->fr._set) { + sp_repr_set_svg_double(repr, "fr", this->fr.computed); + } + SPGradient::write(xml_doc, repr, flags); return repr; @@ -135,6 +148,7 @@ cairo_pattern_t* SPRadialGradient::pattern_new(cairo_t *ct, Geom::OptRect const Geom::Point center(this->cx.computed, this->cy.computed); double radius = this->r.computed; + double focusr = this->fr.computed; double scale = 1.0; double tolerance = cairo_get_tolerance(ct); @@ -159,8 +173,10 @@ cairo_pattern_t* SPRadialGradient::pattern_new(cairo_t *ct, Geom::OptRect const Geom::Point d(focus - center); Geom::Point d_user(d.length(), 0); Geom::Point r_user(radius, 0); + Geom::Point fr_user(focusr, 0); d_user *= gs2user.withoutTranslation(); r_user *= gs2user.withoutTranslation(); + fr_user *= gs2user.withoutTranslation(); double dx = d_user.x(), dy = d_user.y(); cairo_user_to_device_distance(ct, &dx, &dy); @@ -181,7 +197,7 @@ cairo_pattern_t* SPRadialGradient::pattern_new(cairo_t *ct, Geom::OptRect const } cairo_pattern_t *cp = cairo_pattern_create_radial( - scale * d.x() + center.x(), scale * d.y() + center.y(), 0, + scale * d.x() + center.x(), scale * d.y() + center.y(), focusr, center.x(), center.y(), radius); sp_gradient_pattern_common_setup(cp, this, bbox, opacity); diff --git a/src/sp-radial-gradient.h b/src/sp-radial-gradient.h index f753623b7..f90c8c7a9 100644 --- a/src/sp-radial-gradient.h +++ b/src/sp-radial-gradient.h @@ -25,6 +25,7 @@ public: SVGLength r; SVGLength fx; SVGLength fy; + SVGLength fr; // Focus radius. Added in SVG 2 virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity); -- cgit v1.2.3 From f0fb69a1720dc6cfdd1157ddf742e327c8601947 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Mon, 11 Jan 2016 14:17:25 +0000 Subject: Bump libgc dependency to 7.2 (see bug #1530286) (bzr r14570) --- src/inkgc/gc.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/inkgc/gc.cpp b/src/inkgc/gc.cpp index 9372ac693..ffa94ea2a 100644 --- a/src/inkgc/gc.cpp +++ b/src/inkgc/gc.cpp @@ -28,15 +28,9 @@ void display_warning(char *msg, GC_word arg) { } void do_init() { -#if WITH_GC_7_2 GC_set_no_dls(1); GC_set_all_interior_pointers(1); GC_set_finalize_on_demand(0); -#else - GC_no_dls = 1; - GC_all_interior_pointers = 1; - GC_finalize_on_demand = 0; -#endif GC_INIT(); -- cgit v1.2.3 From 78b881c48b66bde1a115e07169c36437ac428576 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Mon, 11 Jan 2016 14:19:35 +0000 Subject: Bump poppler dep to 0.12.2 (see bug #1419263) (bzr r14571) --- src/extension/internal/pdfinput/pdf-parser.cpp | 54 +++++--------------------- 1 file changed, 9 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index 836c34c32..8b0506406 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -927,10 +927,8 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) blendingColorSpace = GfxColorSpace::parse(NULL, &obj5, NULL, NULL); #elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) blendingColorSpace = GfxColorSpace::parse(&obj5, NULL, NULL); -#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) - blendingColorSpace = GfxColorSpace::parse(&obj5, NULL); #else - blendingColorSpace = GfxColorSpace::parse(&obj5); + blendingColorSpace = GfxColorSpace::parse(&obj5, NULL); #endif } obj5.free(); @@ -1173,18 +1171,12 @@ void PdfParser::opSetFillColorSpace(Object args[], int /*numArgs*/) } else { colorSpace = GfxColorSpace::parse(&obj, NULL, NULL); } -#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#else if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0], NULL); } else { colorSpace = GfxColorSpace::parse(&obj, NULL); } -#else - if (obj.isNull()) { - colorSpace = GfxColorSpace::parse(&args[0]); - } else { - colorSpace = GfxColorSpace::parse(&obj); - } #endif obj.free(); if (colorSpace) { @@ -1222,18 +1214,12 @@ void PdfParser::opSetStrokeColorSpace(Object args[], int /*numArgs*/) } else { colorSpace = GfxColorSpace::parse(&obj, NULL, NULL); } -#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#else if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0], NULL); } else { colorSpace = GfxColorSpace::parse(&obj, NULL); } -#else - if (obj.isNull()) { - colorSpace = GfxColorSpace::parse(&args[0]); - } else { - colorSpace = GfxColorSpace::parse(&obj); - } #endif obj.free(); if (colorSpace) { @@ -1322,15 +1308,9 @@ void PdfParser::opSetFillColorN(Object args[], int numArgs) { state->setFillPattern(pattern); builder->updateStyle(state); } -#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) - if (args[numArgs-1].isName() && - (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) { - state->setFillPattern(pattern); - builder->updateStyle(state); - } #else if (args[numArgs-1].isName() && - (pattern = res->lookupPattern(args[numArgs-1].getName()))) { + (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) { state->setFillPattern(pattern); builder->updateStyle(state); } @@ -1388,15 +1368,9 @@ void PdfParser::opSetStrokeColorN(Object args[], int numArgs) { state->setStrokePattern(pattern); builder->updateStyle(state); } -#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) - if (args[numArgs-1].isName() && - (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) { - state->setStrokePattern(pattern); - builder->updateStyle(state); - } #else if (args[numArgs-1].isName() && - (pattern = res->lookupPattern(args[numArgs-1].getName()))) { + (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) { state->setStrokePattern(pattern); builder->updateStyle(state); } @@ -1847,12 +1821,8 @@ void PdfParser::opShFill(Object args[], int /*numArgs*/) if (!(shading = res->lookupShading(args[0].getName(), NULL, NULL))) { return; } -#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) - if (!(shading = res->lookupShading(args[0].getName(), NULL))) { - return; - } #else - if (!(shading = res->lookupShading(args[0].getName()))) { + if (!(shading = res->lookupShading(args[0].getName(), NULL))) { return; } #endif @@ -2923,10 +2893,8 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) colorSpace = GfxColorSpace::parse(NULL, &obj1, NULL, NULL); #elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) colorSpace = GfxColorSpace::parse(&obj1, NULL, NULL); -#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) - colorSpace = GfxColorSpace::parse(&obj1, NULL); #else - colorSpace = GfxColorSpace::parse(&obj1); + colorSpace = GfxColorSpace::parse(&obj1, NULL); #endif } else if (csMode == streamCSDeviceGray) { colorSpace = new GfxDeviceGrayColorSpace(); @@ -3029,10 +2997,8 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) GfxColorSpace *maskColorSpace = GfxColorSpace::parse(NULL, &obj1, NULL, NULL); #elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL, NULL); -#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) - GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL); #else - GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1); + GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL); #endif obj1.free(); if (!maskColorSpace || maskColorSpace->getMode() != csDeviceGray) { @@ -3233,10 +3199,8 @@ void PdfParser::doForm(Object *str) { blendingColorSpace = GfxColorSpace::parse(NULL, &obj3, NULL, NULL); #elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) blendingColorSpace = GfxColorSpace::parse(&obj3, NULL, NULL); -#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) - blendingColorSpace = GfxColorSpace::parse(&obj3, NULL); #else - blendingColorSpace = GfxColorSpace::parse(&obj3); + blendingColorSpace = GfxColorSpace::parse(&obj3, NULL); #endif } obj3.free(); -- cgit v1.2.3 From bc664c1d06f311985502890cb25425f9bd340761 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Mon, 11 Jan 2016 14:29:11 +0000 Subject: Bump poppler dep to 0.15.1 (see bug #1419263) (bzr r14572) --- src/extension/internal/pdfinput/pdf-parser.cpp | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src') diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index 8b0506406..50d44d7a8 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -2131,9 +2131,7 @@ void PdfParser::fillPatch(GfxPatch *patch, int nComps, int depth) { GfxPatch patch01 = blankPatch(); GfxPatch patch10 = blankPatch(); GfxPatch patch11 = blankPatch(); -#ifdef POPPLER_NEW_GFXPATCH GfxColor color = {{0}}; -#endif double xx[4][8]; double yy[4][8]; double xxm; @@ -2153,16 +2151,10 @@ void PdfParser::fillPatch(GfxPatch *patch, int nComps, int depth) { > patchColorDelta) { break; } -#ifdef POPPLER_NEW_GFXPATCH color.c[i] = GfxColorComp(patch->color[0][0].c[i]); -#endif } if (i == nComps || depth == maxDepths[pdfPatchMeshShading-1]) { -#ifdef POPPLER_NEW_GFXPATCH state->setFillColor(&color); -#else - state->setFillColor(&patch->color[0][0]); -#endif state->moveTo(patch->x[0][0], patch->y[0][0]); state->curveTo(patch->x[0][1], patch->y[0][1], patch->x[0][2], patch->y[0][2], -- cgit v1.2.3 From 434246be06812392015321a5fa2175c4e32136fd Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Mon, 11 Jan 2016 14:40:38 +0000 Subject: Bump poppler dep to 0.20.0 Fixed bugs: - https://launchpad.net/bugs/1419263 (bzr r14573) --- src/extension/internal/pdfinput/pdf-parser.cpp | 196 ------------------------- 1 file changed, 196 deletions(-) (limited to 'src') diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index 50d44d7a8..5ede59bf3 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -416,22 +416,14 @@ void PdfParser::parse(Object *obj, GBool topLevel) { for (int i = 0; i < obj->arrayGetLength(); ++i) { obj->arrayGet(i, &obj2); if (!obj2.isStream()) { -#ifdef POPPLER_NEW_ERRORAPI error(errInternal, -1, "Weird page contents"); -#else - error(-1, const_cast("Weird page contents")); -#endif obj2.free(); return; } obj2.free(); } } else if (!obj->isStream()) { -#ifdef POPPLER_NEW_ERRORAPI error(errInternal, -1, "Weird page contents"); -#else - error(-1, const_cast("Weird page contents")); -#endif return; } parser = new Parser(xref, new Lexer(xref, obj), gFalse); @@ -476,11 +468,7 @@ void PdfParser::go(GBool /*topLevel*/) // too many arguments - something is wrong } else { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Too many args in content stream"); -#else - error(getPos(), const_cast("Too many args in content stream")); -#endif if (printCommands) { printf("throwing away arg: "); obj.print(stdout); @@ -497,11 +485,7 @@ void PdfParser::go(GBool /*topLevel*/) // args at end with no command if (numArgs > 0) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Leftover args in content stream"); -#else - error(getPos(), const_cast("Leftover args in content stream")); -#endif if (printCommands) { printf("%d leftovers:", numArgs); for (int i = 0; i < numArgs; ++i) { @@ -568,11 +552,7 @@ void PdfParser::execOp(Object *cmd, Object args[], int numArgs) { name = cmd->getCmd(); if (!(op = findOp(name))) { if (ignoreUndef == 0) -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Unknown operator '{0:s}'", name); -#else - error(getPos(), const_cast("Unknown operator '%s'"), name); -#endif return; } @@ -580,42 +560,26 @@ void PdfParser::execOp(Object *cmd, Object args[], int numArgs) { argPtr = args; if (op->numArgs >= 0) { if (numArgs < op->numArgs) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Too few ({0:d}) args to '{1:d}' operator", numArgs, name); -#else - error(getPos(), const_cast("Too few (%d) args to '%s' operator"), numArgs, name); -#endif return; } if (numArgs > op->numArgs) { #if 0 -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Too many ({0:d}) args to '{1:s}' operator", numArgs, name); -#else - error(getPos(), "Too many (%d) args to '%s' operator", numArgs, name); -#endif #endif argPtr += numArgs - op->numArgs; numArgs = op->numArgs; } } else { if (numArgs > -op->numArgs) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Too many ({0:d}) args to '{1:s}' operator", -#else - error(getPos(), const_cast("Too many (%d) args to '%s' operator"), -#endif numArgs, name); return; } } for (i = 0; i < numArgs; ++i) { if (!checkArg(&argPtr[i], op->tchk[i])) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Arg #{0:d} to '{1:s}' operator is wrong type ({2:s})", -#else - error(getPos(), const_cast("Arg #%d to '%s' operator is wrong type (%s)"), -#endif i, name, argPtr[i].getTypeName()); return; } @@ -784,11 +748,7 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) return; } if (!obj1.isDict()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "ExtGState '{0:s}' is wrong type"), args[0].getName(); -#else - error(getPos(), const_cast("ExtGState '%s' is wrong type"), args[0].getName()); -#endif obj1.free(); return; } @@ -804,11 +764,7 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) if (state->parseBlendMode(&obj2, &mode)) { state->setBlendMode(mode); } else { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Invalid blend mode in ExtGState"); -#else - error(getPos(), const_cast("Invalid blend mode in ExtGState")); -#endif } } obj2.free(); @@ -870,11 +826,7 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) state->setTransfer(funcs); } } else if (!obj2.isNull()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Invalid transfer function in ExtGState"); -#else - error(getPos(), const_cast("Invalid transfer function in ExtGState")); -#endif } obj2.free(); @@ -894,11 +846,7 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) funcs[0] = Function::parse(&obj3); if (funcs[0]->getInputSize() != 1 || funcs[0]->getOutputSize() != 1) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Invalid transfer function in soft mask in ExtGState"); -#else - error(getPos(), const_cast("Invalid transfer function in soft mask in ExtGState")); -#endif delete funcs[0]; funcs[0] = NULL; } @@ -956,27 +904,15 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) delete funcs[0]; } } else { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Invalid soft mask in ExtGState - missing group"); -#else - error(getPos(), const_cast("Invalid soft mask in ExtGState - missing group")); -#endif } obj4.free(); } else { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Invalid soft mask in ExtGState - missing group"); -#else - error(getPos(), const_cast("Invalid soft mask in ExtGState - missing group")); -#endif } obj3.free(); } else if (!obj2.isNull()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Invalid soft mask in ExtGState"); -#else - error(getPos(), const_cast("Invalid soft mask in ExtGState")); -#endif } } obj2.free(); @@ -1004,11 +940,7 @@ void PdfParser::doSoftMask(Object *str, GBool alpha, // check form type dict->lookup(const_cast("FormType"), &obj1); if (!(obj1.isNull() || (obj1.isInt() && obj1.getInt() == 1))) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Unknown form type"); -#else - error(getPos(), const_cast("Unknown form type")); -#endif } obj1.free(); @@ -1016,11 +948,7 @@ void PdfParser::doSoftMask(Object *str, GBool alpha, dict->lookup(const_cast("BBox"), &obj1); if (!obj1.isArray()) { obj1.free(); -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Bad form bounding box"); -#else - error(getPos(), const_cast("Bad form bounding box")); -#endif return; } for (i = 0; i < 4; ++i) { @@ -1186,11 +1114,7 @@ void PdfParser::opSetFillColorSpace(Object args[], int /*numArgs*/) state->setFillColor(&color); builder->updateStyle(state); } else { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Bad color space (fill)"); -#else - error(getPos(), const_cast("Bad color space (fill)")); -#endif } } @@ -1229,11 +1153,7 @@ void PdfParser::opSetStrokeColorSpace(Object args[], int /*numArgs*/) state->setStrokeColor(&color); builder->updateStyle(state); } else { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Bad color space (stroke)"); -#else - error(getPos(), const_cast("Bad color space (stroke)")); -#endif } } @@ -1242,11 +1162,7 @@ void PdfParser::opSetFillColor(Object args[], int numArgs) { int i; if (numArgs != state->getFillColorSpace()->getNComps()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Incorrect number of arguments in 'sc' command"); -#else - error(getPos(), const_cast("Incorrect number of arguments in 'sc' command")); -#endif return; } state->setFillPattern(NULL); @@ -1262,11 +1178,7 @@ void PdfParser::opSetStrokeColor(Object args[], int numArgs) { int i; if (numArgs != state->getStrokeColorSpace()->getNComps()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SC' command"); -#else - error(getPos(), const_cast("Incorrect number of arguments in 'SC' command")); -#endif return; } state->setStrokePattern(NULL); @@ -1286,11 +1198,7 @@ void PdfParser::opSetFillColorN(Object args[], int numArgs) { if (!((GfxPatternColorSpace *)state->getFillColorSpace())->getUnder() || numArgs - 1 != ((GfxPatternColorSpace *)state->getFillColorSpace()) ->getUnder()->getNComps()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Incorrect number of arguments in 'scn' command"); -#else - error(getPos(), const_cast("Incorrect number of arguments in 'scn' command")); -#endif return; } for (i = 0; i < numArgs - 1 && i < gfxColorMaxComps; ++i) { @@ -1318,11 +1226,7 @@ void PdfParser::opSetFillColorN(Object args[], int numArgs) { } else { if (numArgs != state->getFillColorSpace()->getNComps()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Incorrect number of arguments in 'scn' command"); -#else - error(getPos(), const_cast("Incorrect number of arguments in 'scn' command")); -#endif return; } state->setFillPattern(NULL); @@ -1346,11 +1250,7 @@ void PdfParser::opSetStrokeColorN(Object args[], int numArgs) { ->getUnder() || numArgs - 1 != ((GfxPatternColorSpace *)state->getStrokeColorSpace()) ->getUnder()->getNComps()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SCN' command"); -#else - error(getPos(), const_cast("Incorrect number of arguments in 'SCN' command")); -#endif return; } for (i = 0; i < numArgs - 1 && i < gfxColorMaxComps; ++i) { @@ -1378,11 +1278,7 @@ void PdfParser::opSetStrokeColorN(Object args[], int numArgs) { } else { if (numArgs != state->getStrokeColorSpace()->getNComps()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SCN' command"); -#else - error(getPos(), const_cast("Incorrect number of arguments in 'SCN' command")); -#endif return; } state->setStrokePattern(NULL); @@ -1410,11 +1306,7 @@ void PdfParser::opMoveTo(Object args[], int /*numArgs*/) void PdfParser::opLineTo(Object args[], int /*numArgs*/) { if (!state->isCurPt()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "No current point in lineto"); -#else - error(getPos(), const_cast("No current point in lineto")); -#endif return; } state->lineTo(args[0].getNum(), args[1].getNum()); @@ -1424,11 +1316,7 @@ void PdfParser::opLineTo(Object args[], int /*numArgs*/) void PdfParser::opCurveTo(Object args[], int /*numArgs*/) { if (!state->isCurPt()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "No current point in curveto"); -#else - error(getPos(), const_cast("No current point in curveto")); -#endif return; } double x1 = args[0].getNum(); @@ -1444,11 +1332,7 @@ void PdfParser::opCurveTo(Object args[], int /*numArgs*/) void PdfParser::opCurveTo1(Object args[], int /*numArgs*/) { if (!state->isCurPt()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "No current point in curveto1"); -#else - error(getPos(), const_cast("No current point in curveto1")); -#endif return; } double x1 = state->getCurX(); @@ -1464,11 +1348,7 @@ void PdfParser::opCurveTo1(Object args[], int /*numArgs*/) void PdfParser::opCurveTo2(Object args[], int /*numArgs*/) { if (!state->isCurPt()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "No current point in curveto2"); -#else - error(getPos(), const_cast("No current point in curveto2")); -#endif return; } double x1 = args[0].getNum(); @@ -1497,11 +1377,7 @@ void PdfParser::opRectangle(Object args[], int /*numArgs*/) void PdfParser::opClosePath(Object /*args*/[], int /*numArgs*/) { if (!state->isCurPt()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "No current point in closepath"); -#else - error(getPos(), const_cast("No current point in closepath")); -#endif return; } state->closePath(); @@ -1667,11 +1543,7 @@ void PdfParser::doPatternFillFallback(GBool eoFill) { doShadingPatternFillFallback(static_cast(pattern), gFalse, eoFill); break; default: -#ifdef POPPLER_NEW_ERRORAPI error(errUnimplemented, getPos(), "Unimplemented pattern type (%d) in fill", -#else - error(getPos(), const_cast("Unimplemented pattern type (%d) in fill"), -#endif pattern->getType()); break; } @@ -1690,11 +1562,7 @@ void PdfParser::doPatternStrokeFallback() { doShadingPatternFillFallback(static_cast(pattern), gTrue, gFalse); break; default: -#ifdef POPPLER_NEW_ERRORAPI error(errUnimplemented, getPos(), "Unimplemented pattern type ({0:d}) in stroke", -#else - error(getPos(), const_cast("Unimplemented pattern type (%d) in stroke"), -#endif pattern->getType()); break; } @@ -2435,11 +2303,7 @@ void PdfParser::opTextNextLine(Object /*args*/[], int /*numArgs*/) void PdfParser::opShowText(Object args[], int /*numArgs*/) { if (!state->getFont()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "No font in show"); -#else - error(getPos(), const_cast("No font in show")); -#endif return; } if (fontChanged) { @@ -2456,11 +2320,7 @@ void PdfParser::opMoveShowText(Object args[], int /*numArgs*/) double ty = 0; if (!state->getFont()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "No font in move/show"); -#else - error(getPos(), const_cast("No font in move/show")); -#endif return; } if (fontChanged) { @@ -2481,11 +2341,7 @@ void PdfParser::opMoveSetShowText(Object args[], int /*numArgs*/) double ty = 0; if (!state->getFont()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "No font in move/set/show"); -#else - error(getPos(), const_cast("No font in move/set/show")); -#endif return; } if (fontChanged) { @@ -2509,11 +2365,7 @@ void PdfParser::opShowSpaceText(Object args[], int /*numArgs*/) int wMode = 0; if (!state->getFont()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "No font in show/space"); -#else - error(getPos(), const_cast("No font in show/space")); -#endif return; } if (fontChanged) { @@ -2538,11 +2390,7 @@ void PdfParser::opShowSpaceText(Object args[], int /*numArgs*/) } else if (obj.isString()) { doShowText(obj.getString()); } else { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Element of show/space array must be number or string"); -#else - error(getPos(), const_cast("Element of show/space array must be number or string")); -#endif } obj.free(); } @@ -2624,11 +2472,7 @@ void PdfParser::doShowText(GooString *s) { if (charProc.isStream()) { //parse(&charProc, gFalse); // TODO: parse into SVG font } else { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Missing or bad Type3 CharProc entry"); -#else - error(getPos(), const_cast("Missing or bad Type3 CharProc entry")); -#endif } //out->endType3Char(state); if (resDict) { @@ -2701,11 +2545,7 @@ void PdfParser::opXObject(Object args[], int /*numArgs*/) return; } if (!obj1.isStream()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "XObject '{0:s}' is wrong type", name); -#else - error(getPos(), const_cast("XObject '%s' is wrong type"), name); -#endif obj1.free(); return; } @@ -2721,17 +2561,9 @@ void PdfParser::opXObject(Object args[], int /*numArgs*/) /* out->psXObject(obj1.getStream(), obj3.isStream() ? obj3.getStream() : (Stream *)NULL);*/ } else if (obj2.isName()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Unknown XObject subtype '{0:s}'", obj2.getName()); -#else - error(getPos(), const_cast("Unknown XObject subtype '%s'"), obj2.getName()); -#endif } else { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "XObject subtype is missing or wrong type"); -#else - error(getPos(), const_cast("XObject subtype is missing or wrong type")); -#endif } obj2.free(); obj1.free(); @@ -3106,11 +2938,7 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) err2: obj1.free(); err1: -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Bad image parameters"); -#else - error(getPos(), const_cast("Bad image parameters")); -#endif } void PdfParser::doForm(Object *str) { @@ -3135,11 +2963,7 @@ void PdfParser::doForm(Object *str) { // check form type dict->lookup(const_cast("FormType"), &obj1); if (!(obj1.isNull() || (obj1.isInt() && obj1.getInt() == 1))) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Unknown form type"); -#else - error(getPos(), const_cast("Unknown form type")); -#endif } obj1.free(); @@ -3147,11 +2971,7 @@ void PdfParser::doForm(Object *str) { dict->lookup(const_cast("BBox"), &bboxObj); if (!bboxObj.isArray()) { bboxObj.free(); -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Bad form bounding box"); -#else - error(getPos(), const_cast("Bad form bounding box")); -#endif return; } for (i = 0; i < 4; ++i) { @@ -3350,11 +3170,7 @@ Stream *PdfParser::buildImageStream() { parser->getObj(&obj); while (!obj.isCmd(const_cast("ID")) && !obj.isEOF()) { if (!obj.isName()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "Inline image dictionary key must be a name object"); -#else - error(getPos(), const_cast("Inline image dictionary key must be a name object")); -#endif obj.free(); } else { key = copyString(obj.getName()); @@ -3369,11 +3185,7 @@ Stream *PdfParser::buildImageStream() { parser->getObj(&obj); } if (obj.isEOF()) { -#ifdef POPPLER_NEW_ERRORAPI error(errSyntaxError, getPos(), "End of file in inline image"); -#else - error(getPos(), const_cast("End of file in inline image")); -#endif obj.free(); dict.free(); return NULL; @@ -3389,20 +3201,12 @@ Stream *PdfParser::buildImageStream() { void PdfParser::opImageData(Object /*args*/[], int /*numArgs*/) { -#ifdef POPPLER_NEW_ERRORAPI error(errInternal, getPos(), "Internal: got 'ID' operator"); -#else - error(getPos(), const_cast("Internal: got 'ID' operator")); -#endif } void PdfParser::opEndImage(Object /*args*/[], int /*numArgs*/) { -#ifdef POPPLER_NEW_ERRORAPI error(errInternal, getPos(), "Internal: got 'EI' operator"); -#else - error(getPos(), const_cast("Internal: got 'EI' operator")); -#endif } //------------------------------------------------------------------------ -- cgit v1.2.3 From db8882765491df58a53f249c21a5d0ed51b99ede Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 14 Jan 2016 09:56:09 +0100 Subject: Allow one more digit of precission for 'stdDeviation'. (bzr r14575) --- src/ui/dialog/filter-effects-dialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index e3196bf59..7e9d8481a 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -2899,7 +2899,7 @@ void FilterEffectsDialog::init_settings_widgets() _settings->add_spinscale(1, SP_PROP_FLOOD_OPACITY, _("Opacity:"), 0, 1, 0.1, 0.01, 2); _settings->type(NR_FILTER_GAUSSIANBLUR); - _settings->add_dualspinscale(SP_ATTR_STDDEVIATION, _("Standard Deviation:"), 0.01, 100, 1, 0.01, 1, _("The standard deviation for the blur operation.")); + _settings->add_dualspinscale(SP_ATTR_STDDEVIATION, _("Standard Deviation:"), 0.01, 100, 1, 0.01, 2, _("The standard deviation for the blur operation.")); _settings->type(NR_FILTER_MERGE); _settings->add_no_params(); -- cgit v1.2.3 From 63f2eef423ef7de34a1c0e1410e8281472d4f20d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 14 Jan 2016 12:14:51 +0100 Subject: Correct writing of blur value when display units are not user units. (bzr r14576) --- src/ui/dialog/objects.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 726df9a61..891048beb 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -1583,6 +1583,10 @@ void ObjectsPanel::_blurChangedIter(const Gtk::TreeIter& iter, double blur) } if (radius != 0) { + // The modify function expects radius to be in display pixels. + Geom::Affine i2d (item->i2dt_affine()); + double expansion = i2d.descrim(); + radius *= expansion; SPFilter *filter = modify_filter_gaussian_blur_from_item(_document, item, radius); sp_style_set_property_url(item, "filter", filter, false); } else if (item->style->filter.set && item->style->getFilter()) { -- cgit v1.2.3 From cbf36bcb4c4458c0eb9db0f4ffdf158611ee52c8 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 15 Jan 2016 11:16:12 +0100 Subject: More subtle checkerboard pattern centered around 50% gray. Makes editing nodes more visible. Note, input values are in sRGB. (bzr r14584) --- src/display/cairo-utils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 59e190676..24a75de4c 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -1120,9 +1120,9 @@ ink_cairo_pattern_create_checkerboard() cairo_t *ct = cairo_create(s); cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE); - cairo_set_source_rgb(ct, 0.75, 0.75, 0.75); + cairo_set_source_rgb(ct, 0.77, 0.77, 0.77); cairo_paint(ct); - cairo_set_source_rgb(ct, 0.5, 0.5, 0.5); + cairo_set_source_rgb(ct, 0.69, 0.69, 0.69); cairo_rectangle(ct, 0, 0, w, h); cairo_rectangle(ct, w, h, w, h); cairo_fill(ct); -- cgit v1.2.3 From 1aa94f627221dff927966c6df8f9e53d917b57df Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 15 Jan 2016 22:17:48 -0500 Subject: Remove buggy and presumptuous usage of SP_ACTIVE_DESKTOP in renderer code; fixes 1526701 Fixed bugs: - https://launchpad.net/bugs/1526701 (bzr r14585.1.1) --- src/display/guideline.cpp | 48 +++++++++++++++++++++-------------------------- src/display/guideline.h | 5 +++-- src/sp-guide.cpp | 5 +++-- 3 files changed, 27 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 4b573a586..00fcfea6a 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -17,13 +17,8 @@ #include <2geom/coord.h> #include <2geom/transforms.h> #include "sp-canvas-util.h" -#include "knot.h" #include "guideline.h" #include "display/cairo-utils.h" - -#include "inkscape.h" // for inkscape_active_desktop() -#include "desktop.h" -#include "sp-namedview.h" #include "display/sp-canvas.h" #include "display/sodipodi-ctrl.h" #include "ui/control-manager.h" @@ -37,7 +32,7 @@ static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf); static double sp_guideline_point(SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); -static gboolean sp_guideline_origin_move(SPKnot *knot, Geom::Point *position, guint state, SPGuideLine *data); +//static gboolean sp_guideline_origin_move(SPKnot *knot, Geom::Point *position, guint state, SPGuideLine *data); static void sp_guideline_drawline (SPCanvasBuf *buf, gint x0, gint y0, gint x1, gint y1, guint32 rgba); G_DEFINE_TYPE(SPGuideLine, sp_guideline, SP_TYPE_CANVAS_ITEM); @@ -72,8 +67,8 @@ static void sp_guideline_destroy(SPCanvasItem *object) SPGuideLine *gl = SP_GUIDELINE(object); - if (gl->origin != NULL && SP_IS_KNOT(gl->origin)) { - knot_unref(gl->origin); + if (gl->origin) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(gl->origin)); } if (gl->label) { @@ -172,28 +167,19 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, if ((SP_CANVAS_ITEM_CLASS(sp_guideline_parent_class))->update) { (SP_CANVAS_ITEM_CLASS(sp_guideline_parent_class))->update(item, affine, flags); } - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop && item->visible) { - if (!gl->origin) { - gl->origin = new SPKnot(desktop, "No tip yet!! XXX"); - - gl->origin->setAnchor(SP_ANCHOR_CENTER); - gl->origin->setMode(SP_CTRL_MODE_COLOR); - gl->origin->setFill(0xffffff80, 0xffffffff, 0xffffff80); - gl->origin->request_signal.connect(sigc::bind(sigc::ptr_fun(sp_guideline_origin_move), gl)); - } + if (item->visible) { if (gl->locked) { - gl->origin->setStroke(0x0000ff88, 0x0000ff88, 0x0000ff88); - gl->origin->setShape(SP_CTRL_SHAPE_CROSS); - gl->origin->setSize(6); + g_object_set(G_OBJECT(gl->origin), "stroke_color", 0x0000ff88, + "shape", SP_CTRL_SHAPE_CROSS, + "size", 6., NULL); } else { - gl->origin->setStroke(0xff000088, 0xff0000ff, 0xff0000ff); - gl->origin->setShape(SP_CTRL_SHAPE_CIRCLE); - gl->origin->setSize(4); + g_object_set(G_OBJECT(gl->origin), "stroke_color", 0xff000088, + "shape", SP_CTRL_SHAPE_CIRCLE, + "size", 4., NULL); } gl->origin->moveto(gl->point_on_line); - gl->origin->updateCtrl(); + sp_canvas_item_request_update(SP_CANVAS_ITEM(gl->origin)); } gl->affine = affine; @@ -236,17 +222,24 @@ SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point p gl->angle = tan( -gl->normal_to_line[Geom::X] / gl->normal_to_line[Geom::Y]); sp_guideline_set_position(gl, point_on_line); + gl->origin = (SPCtrl *)sp_canvas_item_new(parent, SP_TYPE_CTRL, NULL); + g_object_set(G_OBJECT(gl->origin), "anchor", SP_ANCHOR_CENTER, + "mode", SP_CTRL_MODE_COLOR, + "filled", FALSE, + "stroked", TRUE, + "stroke_color", 0x01000000, NULL); + return item; } -static gboolean sp_guideline_origin_move(SPKnot *knot, Geom::Point *position, guint state, SPGuideLine *gl) +/*static gboolean sp_guideline_origin_move(SPKnot *knot, Geom::Point *position, guint state, SPGuideLine *gl) { if(gl->locked) { return true; } sp_guideline_set_position(gl, *position); return false; -} +}*/ void sp_guideline_set_label(SPGuideLine *gl, const char* label) { @@ -281,6 +274,7 @@ void sp_guideline_set_normal(SPGuideLine *gl, Geom::Point normal_to_line) void sp_guideline_set_color(SPGuideLine *gl, unsigned int rgba) { gl->rgba = rgba; + g_object_set(G_OBJECT(gl->origin), "stroke_color", rgba, NULL); sp_canvas_item_request_update(SP_CANVAS_ITEM(gl)); } diff --git a/src/display/guideline.h b/src/display/guideline.h index d58821fc8..44aed88d9 100644 --- a/src/display/guideline.h +++ b/src/display/guideline.h @@ -16,17 +16,18 @@ #include <2geom/point.h> #include "sp-canvas-item.h" -#include "knot.h" #define SP_TYPE_GUIDELINE (sp_guideline_get_type()) #define SP_GUIDELINE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_GUIDELINE, SPGuideLine)) #define SP_IS_GUIDELINE(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_GUIDELINE)) +struct SPCtrl; + struct SPGuideLine { SPCanvasItem item; Geom::Affine affine; - SPKnot *origin; // unlike 'item', this is only held locally + SPCtrl *origin; // unlike 'item', this is only held locally guint32 rgba; diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index a57947e01..2bfd0c656 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -25,6 +25,7 @@ #include "display/sp-canvas.h" #include "display/guideline.h" +#include "display/sodipodi-ctrl.h" #include "svg/svg.h" #include "svg/svg-color.h" #include "svg/stringstream.h" @@ -289,7 +290,7 @@ void SPGuide::showSPGuide() for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { sp_canvas_item_show(SP_CANVAS_ITEM(*it)); if((*it)->origin) { - (*it)->origin->show(); + sp_canvas_item_show(SP_CANVAS_ITEM((*it)->origin)); } else { //reposition to same place to show knots sp_guideline_set_position(*it, point_on_line); @@ -317,7 +318,7 @@ void SPGuide::hideSPGuide() for(std::vector::const_iterator it = this->views.begin(); it != this->views.end(); ++it) { sp_canvas_item_hide(SP_CANVAS_ITEM(*it)); if ((*it)->origin) { - (*it)->origin->hide(); + sp_canvas_item_hide(SP_CANVAS_ITEM((*it)->origin)); } } } -- cgit v1.2.3 From b4153318caa10997f2288bba57fce9fab106b0dc Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 15 Jan 2016 22:19:49 -0500 Subject: Dead code cleanup (bzr r14585.1.2) --- src/display/guideline.cpp | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'src') diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 00fcfea6a..b3b0869b6 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -32,7 +32,6 @@ static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf); static double sp_guideline_point(SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); -//static gboolean sp_guideline_origin_move(SPKnot *knot, Geom::Point *position, guint state, SPGuideLine *data); static void sp_guideline_drawline (SPCanvasBuf *buf, gint x0, gint y0, gint x1, gint y1, guint32 rgba); G_DEFINE_TYPE(SPGuideLine, sp_guideline, SP_TYPE_CANVAS_ITEM); @@ -232,15 +231,6 @@ SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point p return item; } -/*static gboolean sp_guideline_origin_move(SPKnot *knot, Geom::Point *position, guint state, SPGuideLine *gl) -{ - if(gl->locked) { - return true; - } - sp_guideline_set_position(gl, *position); - return false; -}*/ - void sp_guideline_set_label(SPGuideLine *gl, const char* label) { if (gl->label) { -- cgit v1.2.3 From 99c7ac2b88a264d1415dacb073b5b1a8da4bf85e Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 16 Jan 2016 10:56:00 -0500 Subject: Header cleanup (bzr r14585.1.3) --- src/display/guideline.cpp | 3 --- src/sp-guide.cpp | 1 - 2 files changed, 4 deletions(-) (limited to 'src') diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index b3b0869b6..d34112046 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -21,9 +21,6 @@ #include "display/cairo-utils.h" #include "display/sp-canvas.h" #include "display/sodipodi-ctrl.h" -#include "ui/control-manager.h" - -using Inkscape::ControlManager; static void sp_guideline_destroy(SPCanvasItem *object); diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 2bfd0c656..d1e101fd5 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -25,7 +25,6 @@ #include "display/sp-canvas.h" #include "display/guideline.h" -#include "display/sodipodi-ctrl.h" #include "svg/svg.h" #include "svg/svg-color.h" #include "svg/stringstream.h" -- cgit v1.2.3 From d7f53de7a19a00bf0f01f4824498ae64d9cd12a6 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 16 Jan 2016 11:13:25 -0500 Subject: Coalesce g_object_new/g_object_set calls; change guide origin pickable to false so that guides can be grabbed by the origin again (bzr r14593) --- src/display/guideline.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index d34112046..126fcf87c 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -218,12 +218,13 @@ SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point p gl->angle = tan( -gl->normal_to_line[Geom::X] / gl->normal_to_line[Geom::Y]); sp_guideline_set_position(gl, point_on_line); - gl->origin = (SPCtrl *)sp_canvas_item_new(parent, SP_TYPE_CTRL, NULL); - g_object_set(G_OBJECT(gl->origin), "anchor", SP_ANCHOR_CENTER, - "mode", SP_CTRL_MODE_COLOR, - "filled", FALSE, - "stroked", TRUE, - "stroke_color", 0x01000000, NULL); + gl->origin = (SPCtrl *) sp_canvas_item_new(parent, SP_TYPE_CTRL, + "anchor", SP_ANCHOR_CENTER, + "mode", SP_CTRL_MODE_COLOR, + "filled", FALSE, + "stroked", TRUE, + "stroke_color", 0x01000000, NULL); + gl->origin->pickable = false; return item; } -- cgit v1.2.3 From f05f886e8bd15df056f2318f99eae920d9cd20d4 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Sat, 16 Jan 2016 18:25:53 -0800 Subject: patch probably fixes bug 1534833 (bzr r14594) --- src/extension/internal/emf-print.cpp | 2 +- src/extension/internal/wmf-print.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index cc798cc5f..53120637c 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -1955,7 +1955,7 @@ unsigned int PrintEmf::print_pathv(Geom::PathVector const &pathv, const Geom::Af unsigned int PrintEmf::text(Inkscape::Extension::Print * /*mod*/, char const *text, Geom::Point const &p, SPStyle const *const style) { - if (!et) { + if (!et || !text) { return 0; } diff --git a/src/extension/internal/wmf-print.cpp b/src/extension/internal/wmf-print.cpp index 431053085..3d913bf1e 100644 --- a/src/extension/internal/wmf-print.cpp +++ b/src/extension/internal/wmf-print.cpp @@ -1325,7 +1325,7 @@ unsigned int PrintWmf::print_pathv(Geom::PathVector const &pathv, const Geom::Af unsigned int PrintWmf::text(Inkscape::Extension::Print * /*mod*/, char const *text, Geom::Point const &p, SPStyle const *const style) { - if (!wt) { + if (!wt || !text) { return 0; } @@ -1369,6 +1369,9 @@ unsigned int PrintWmf::text(Inkscape::Extension::Print * /*mod*/, char const *te char *latin1_text = U_Utf16leToLatin1(unicode_text, 0, NULL); free(unicode_text); + // in some cases a UTF string may reduce to NO latin1 characters, which returns NULL + if(!latin1_text){ return 0; } + //PPT gets funky with text within +-1 degree of a multiple of 90, but only for SOME fonts.Snap those to the central value //Some funky ones: Arial, Times New Roman //Some not funky ones: Symbol and Verdana. -- cgit v1.2.3 From 90577b7848b02830973da377bc9ceff09aa1f039 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 17 Jan 2016 11:05:43 -0500 Subject: Follow-up commit to 14529. From std::list documentation: list::insert - The container is extended by inserting new elements before the element at the specified position. (bzr r14601) --- src/display/sp-canvas.cpp | 73 ++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 6441ea68b..e94133b28 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -109,7 +109,7 @@ struct SPCanvasGroup { SPCanvasItem item; - std::list *items; + std::list items; }; @@ -603,14 +603,14 @@ void sp_canvas_item_raise(SPCanvasItem *item, int positions) } SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); - std::list::iterator l = std::find(parent->items->begin(),parent->items->end(), item); - g_assert (l != parent->items->end()); + std::list::iterator l = std::find(parent->items.begin(),parent->items.end(), item); + g_assert (l != parent->items.end()); - for (int i=0; iitems->end(); ++i) + for (int i=0; iitems.end(); ++i) l++; - parent->items->remove(item); - parent->items->insert(l, item); + parent->items.remove(item); + parent->items.insert(++l, item); redraw_if_visible (item); item->canvas->need_repick = TRUE; @@ -623,8 +623,8 @@ void sp_canvas_item_raise_to_top(SPCanvasItem *item) if (!item->parent) return; SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); - parent->items->remove(item); - parent->items->insert(parent->items->end(),item); + parent->items.remove(item); + parent->items.push_back(item); redraw_if_visible (item); item->canvas->need_repick = TRUE; } @@ -646,23 +646,25 @@ void sp_canvas_item_lower(SPCanvasItem *item, int positions) g_return_if_fail (SP_IS_CANVAS_ITEM (item)); g_return_if_fail (positions >= 1); - if (!item->parent || positions == 0 || item == SP_CANVAS_GROUP(item->parent)->items->front() ) { + SPCanvasGroup *parent = SP_CANVAS_GROUP(item->parent); + + if (!parent || positions == 0 || item == parent->items.front() ) { return; } - SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); - std::list::iterator l = std::find(parent->items->begin(),parent->items->end(), item); - g_assert (l != parent->items->end()); + std::list::iterator l = std::find(parent->items.begin(), parent->items.end(), item); + g_assert (l != parent->items.end()); - for (int i=0; iitems->begin(); ++i) + for (int i=0; iitems.begin(); ++i) l--; - parent->items->remove(item); - parent->items->insert(l, item); + parent->items.remove(item); + parent->items.insert(l, item); redraw_if_visible (item); item->canvas->need_repick = TRUE; } + void sp_canvas_item_lower_to_bottom(SPCanvasItem *item) { g_return_if_fail (item != NULL); @@ -670,15 +672,15 @@ void sp_canvas_item_lower_to_bottom(SPCanvasItem *item) if (!item->parent) return; SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); - parent->items->remove(item); - parent->items->insert(parent->items->begin(),item); + parent->items.remove(item); + parent->items.push_front(item); redraw_if_visible (item); item->canvas->need_repick = TRUE; } bool sp_canvas_item_is_visible(SPCanvasItem *item) { - return item->visible; + return item->visible; } /** @@ -872,7 +874,14 @@ void sp_canvas_item_request_update(SPCanvasItem *item) gint sp_canvas_item_order (SPCanvasItem * item) { SPCanvasGroup * p = SP_CANVAS_GROUP(item->parent); - return std::distance(p->items->begin(), std::find(p->items->begin(), p->items->end(), item)); + size_t index = 0; + for (std::list::const_iterator it = p->items.begin(); it != p->items.end(); ++it, ++index) { + if ((*it) == item) { + return index; + } + } + + return -1; } // SPCanvasGroup @@ -891,7 +900,7 @@ static void sp_canvas_group_class_init(SPCanvasGroupClass *klass) static void sp_canvas_group_init(SPCanvasGroup * group) { - group->items = new std::list; + new (&group->items) std::list; } void SPCanvasGroup::destroy(SPCanvasItem *object) @@ -899,16 +908,14 @@ void SPCanvasGroup::destroy(SPCanvasItem *object) g_return_if_fail(object != NULL); g_return_if_fail(SP_IS_CANVAS_GROUP(object)); - SPCanvasGroup const *group = SP_CANVAS_GROUP(object); + SPCanvasGroup *group = SP_CANVAS_GROUP(object); - std::list *list = group->items; - for (std::list::iterator it = list->begin(); it != list->end(); ++it) { - SPCanvasItem *child = *it; - sp_canvas_item_destroy(child); + for (std::list::iterator it = group->items.begin(); it != group->items.end(); ++it) { + sp_canvas_item_destroy(*it); } - group->items->clear(); - delete group->items; + group->items.clear(); + group->items.~list(); // invoke manually if (SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy) { (* SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy)(object); @@ -920,7 +927,7 @@ void SPCanvasGroup::update(SPCanvasItem *item, Geom::Affine const &affine, unsig SPCanvasGroup const *group = SP_CANVAS_GROUP(item); Geom::OptRect bounds; - for (std::list::const_iterator it = group->items->begin(); it != group->items->end(); ++it) { + for (std::list::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { SPCanvasItem *i = *it; sp_canvas_item_invoke_update (i, affine, flags); @@ -956,7 +963,7 @@ double SPCanvasGroup::point(SPCanvasItem *item, Geom::Point p, SPCanvasItem **ac *actual_item = NULL; double dist = 0.0; - for (std::list::const_iterator it = group->items->begin(); it != group->items->end(); ++it) { + for (std::list::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { SPCanvasItem *child = *it; if ((child->x1 <= x2) && (child->y1 <= y2) && (child->x2 >= x1) && (child->y2 >= y1)) { @@ -990,7 +997,7 @@ void SPCanvasGroup::render(SPCanvasItem *item, SPCanvasBuf *buf) { SPCanvasGroup const *group = SP_CANVAS_GROUP(item); - for (std::list::const_iterator it = group->items->begin(); it != group->items->end(); ++it) { + for (std::list::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { SPCanvasItem *child = *it; if (child->visible) { if ((child->x1 < buf->rect.right()) && @@ -1009,7 +1016,7 @@ void SPCanvasGroup::viewboxChanged(SPCanvasItem *item, Geom::IntRect const &new_ { SPCanvasGroup *group = SP_CANVAS_GROUP(item); - for (std::list::const_iterator it = group->items->begin(); it != group->items->end(); ++it) { + for (std::list::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { SPCanvasItem *child = *it; if (child->visible) { if (SP_CANVAS_ITEM_GET_CLASS(child)->viewbox_changed) { @@ -1024,7 +1031,7 @@ void SPCanvasGroup::add(SPCanvasItem *item) g_object_ref(item); g_object_ref_sink(item); - items->push_back(item); + items.push_back(item); sp_canvas_item_request_update(item); } @@ -1033,7 +1040,7 @@ void SPCanvasGroup::remove(SPCanvasItem *item) { g_return_if_fail(item != NULL); - items->remove(item); + items.remove(item); // Unparent the child item->parent = NULL; -- cgit v1.2.3 From dc064a944edab7902196389912222b63826ee3a9 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 17 Jan 2016 11:17:12 -0500 Subject: Less derp, can't iterate past the end of the list (bzr r14602) --- src/display/sp-canvas.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index e94133b28..f33428295 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -606,11 +606,11 @@ void sp_canvas_item_raise(SPCanvasItem *item, int positions) std::list::iterator l = std::find(parent->items.begin(),parent->items.end(), item); g_assert (l != parent->items.end()); - for (int i=0; iitems.end(); ++i) + for (int i=0; i<=positions && l != parent->items.end(); ++i) l++; parent->items.remove(item); - parent->items.insert(++l, item); + parent->items.insert(l, item); redraw_if_visible (item); item->canvas->need_repick = TRUE; -- cgit v1.2.3 From b3719f65d1bb2ee5ab7fd3bc67f92a657732580d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 17 Jan 2016 20:18:53 +0100 Subject: Add option to Lattice2 to update LPE only on release knot. This could be useful if item is too complex, making previous knots unusable This can be used in other LPE if anyone want or ping me to it. Maybe could be usefull add similar thing to path parameter, Same slow item become tooooo slow with bend path. (bzr r14604) --- src/live_effects/lpe-lattice2.cpp | 37 +++++++++++++++++++++++++++++++----- src/live_effects/lpe-lattice2.h | 1 + src/live_effects/parameter/point.cpp | 16 ++++++++++++---- src/live_effects/parameter/point.h | 7 +++++-- 4 files changed, 50 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp index 8c7f46cbd..b749370fa 100644 --- a/src/live_effects/lpe-lattice2.cpp +++ b/src/live_effects/lpe-lattice2.cpp @@ -46,6 +46,7 @@ LPELattice2::LPELattice2(LivePathEffectObject *lpeobject) : Effect(lpeobject), horizontal_mirror(_("Mirror movements in horizontal"), _("Mirror movements in horizontal"), "horizontal_mirror", &wr, this, false), vertical_mirror(_("Mirror movements in vertical"), _("Mirror movements in vertical"), "vertical_mirror", &wr, this, false), + live_update(_("Update while moving knots (maybe slow)"), _("Update while moving knots (maybe slow)"), "live_update", &wr, this, true), grid_point_0(_("Control 0:"), _("Control 0 - Ctrl+Alt+Click: reset, Ctrl: move along axes"), "gridpoint0", &wr, this), grid_point_1(_("Control 1:"), _("Control 1 - Ctrl+Alt+Click: reset, Ctrl: move along axes"), "gridpoint1", &wr, this), grid_point_2(_("Control 2:"), _("Control 2 - Ctrl+Alt+Click: reset, Ctrl: move along axes"), "gridpoint2", &wr, this), @@ -76,6 +77,7 @@ LPELattice2::LPELattice2(LivePathEffectObject *lpeobject) : // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter(&horizontal_mirror); registerParameter(&vertical_mirror); + registerParameter(&live_update); registerParameter(&grid_point_0); registerParameter(&grid_point_1); registerParameter(&grid_point_2); @@ -248,7 +250,7 @@ LPELattice2::newWidget() } Glib::ustring * tip = param->param_getTooltip(); if (widg) { - if (param->param_key == "horizontal_mirror" || param->param_key == "vertical_mirror") { + if (param->param_key == "horizontal_mirror" || param->param_key == "vertical_mirror" || param->param_key == "live_update") { vbox->pack_start(*widg, true, true, 2); } else { vbox_expander->pack_start(*widg, true, true, 2); @@ -300,8 +302,8 @@ LPELattice2::vertical(PointParam ¶m_one, PointParam ¶m_two, Geom::Line v } A[Geom::X] = nearest[Geom::X] - distance_middle; B[Geom::X] = nearest[Geom::X] + distance_middle; - param_one.param_setValue(A, true); - param_two.param_setValue(B, true); + param_one.param_setValue(A, live_update); + param_two.param_setValue(B, live_update); } void @@ -321,8 +323,8 @@ LPELattice2::horizontal(PointParam ¶m_one, PointParam ¶m_two, Geom::Line } A[Geom::Y] = nearest[Geom::Y] - distance_middle; B[Geom::Y] = nearest[Geom::Y] + distance_middle; - param_one.param_setValue(A, true); - param_two.param_setValue(B, true); + param_one.param_setValue(A, live_update); + param_two.param_setValue(B, live_update); } void @@ -464,6 +466,31 @@ LPELattice2::setDefaults() grid_point_28x30.param_update_default(gp28x30); grid_point_29x31.param_update_default(gp29x31); grid_point_32x33x34x35.param_update_default(gp32x33x34x35); + grid_point_0.param_set_liveupdate(live_update); + grid_point_1.param_set_liveupdate(live_update); + grid_point_2.param_set_liveupdate(live_update); + grid_point_3.param_set_liveupdate(live_update); + grid_point_4.param_set_liveupdate(live_update); + grid_point_5.param_set_liveupdate(live_update); + grid_point_6.param_set_liveupdate(live_update); + grid_point_7.param_set_liveupdate(live_update); + grid_point_8x9.param_set_liveupdate(live_update); + grid_point_10x11.param_set_liveupdate(live_update); + grid_point_12.param_set_liveupdate(live_update); + grid_point_13.param_set_liveupdate(live_update); + grid_point_14.param_set_liveupdate(live_update); + grid_point_15.param_set_liveupdate(live_update); + grid_point_16.param_set_liveupdate(live_update); + grid_point_17.param_set_liveupdate(live_update); + grid_point_18.param_set_liveupdate(live_update); + grid_point_19.param_set_liveupdate(live_update); + grid_point_20x21.param_set_liveupdate(live_update); + grid_point_22x23.param_set_liveupdate(live_update); + grid_point_24x26.param_set_liveupdate(live_update); + grid_point_25x27.param_set_liveupdate(live_update); + grid_point_28x30.param_set_liveupdate(live_update); + grid_point_29x31.param_set_liveupdate(live_update); + grid_point_32x33x34x35.param_set_liveupdate(live_update); } void diff --git a/src/live_effects/lpe-lattice2.h b/src/live_effects/lpe-lattice2.h index b32903c9e..8d0c18a3a 100644 --- a/src/live_effects/lpe-lattice2.h +++ b/src/live_effects/lpe-lattice2.h @@ -63,6 +63,7 @@ private: BoolParam horizontal_mirror; BoolParam vertical_mirror; + BoolParam live_update; PointParam grid_point_0; PointParam grid_point_1; PointParam grid_point_2; diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index 4c4d2cd9c..ca3471b29 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -25,9 +25,11 @@ namespace LivePathEffect { PointParam::PointParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, const gchar *htip, Geom::Point default_value) + Effect* effect, const gchar *htip, Geom::Point default_value, + bool live_update ) : Parameter(label, tip, key, wr, effect), defvalue(default_value), + liveupdate(live_update), knoth(NULL) { knot_shape = SP_KNOT_SHAPE_DIAMOND; @@ -48,6 +50,12 @@ PointParam::param_set_default() param_setValue(defvalue,true); } +void +PointParam::param_set_liveupdate( bool live_update) +{ + liveupdate = live_update; +} + Geom::Point PointParam::param_get_default() const{ return defvalue; @@ -70,7 +78,7 @@ PointParam::param_setValue(Geom::Point newpoint, bool write) param_write_to_repr(str); g_free(str); } - if(knoth){ + if(knoth && liveupdate){ knoth->update_knots(); } } @@ -166,9 +174,9 @@ PointParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &or s = A; } } - pparam->param_setValue(s, true); + pparam->param_setValue(s, this->pparam->liveupdate); SPLPEItem * splpeitem = dynamic_cast(item); - if(splpeitem){ + if(splpeitem && this->pparam->liveupdate){ sp_lpe_item_update_patheffect(splpeitem, false, false); } } diff --git a/src/live_effects/parameter/point.h b/src/live_effects/parameter/point.h index 471fbc993..4329e0bcd 100644 --- a/src/live_effects/parameter/point.h +++ b/src/live_effects/parameter/point.h @@ -29,8 +29,9 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - const gchar *handle_tip = NULL, - Geom::Point default_value = Geom::Point(0,0) ); // tip for automatically associated on-canvas handle + const gchar *handle_tip = NULL,// tip for automatically associated on-canvas handle + Geom::Point default_value = Geom::Point(0,0), + bool live_update = true ); virtual ~PointParam(); virtual Gtk::Widget * param_newWidget(); @@ -41,6 +42,7 @@ public: void param_setValue(Geom::Point newpoint, bool write = false); void param_set_default(); Geom::Point param_get_default() const; + void param_set_liveupdate(bool live_update); void param_update_default(Geom::Point newpoint); virtual void param_transform_multiply(Geom::Affine const& /*postmul*/, bool /*set*/); @@ -54,6 +56,7 @@ private: PointParam(const PointParam&); PointParam& operator=(const PointParam&); Geom::Point defvalue; + bool liveupdate; KnotHolder *knoth; SPKnotShapeType knot_shape; SPKnotModeType knot_mode; -- cgit v1.2.3 From 81f350e17e3398c1a5f3fb5254acc5e0ad7caf23 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Tue, 26 Jan 2016 17:05:21 -0800 Subject: patch should fix bug 1480651 (bzr r14617) --- src/libuemf/uemf.c | 6 +++--- src/libuemf/uemf_print.c | 18 ++++++++++++------ src/libuemf/uemf_safe.c | 8 +++++--- src/libuemf/upmf.c | 16 ++++++---------- src/libuemf/upmf.h | 11 +++++------ src/libuemf/upmf_print.c | 14 +++++++------- 6 files changed, 38 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/libuemf/uemf.c b/src/libuemf/uemf.c index afa116e75..fa7689bb6 100644 --- a/src/libuemf/uemf.c +++ b/src/libuemf/uemf.c @@ -16,11 +16,11 @@ /* File: uemf.c -Version: 0.0.30 -Date: 20-MAR-2015 +Version: 0.0.31 +Date: 26-JAN-2016 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu -Copyright: 2015 David Mathog and California Institute of Technology (Caltech) +Copyright: 2016 David Mathog and California Institute of Technology (Caltech) */ #ifdef __cplusplus diff --git a/src/libuemf/uemf_print.c b/src/libuemf/uemf_print.c index 4bc9f0206..28fe0b7c3 100644 --- a/src/libuemf/uemf_print.c +++ b/src/libuemf/uemf_print.c @@ -6,11 +6,11 @@ /* File: uemf_print.c -Version: 0.0.20 -Date: 21-MAY-2015 +Version: 0.0.21 +Date: 26-JAN-2016 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu -Copyright: 2015 David Mathog and California Institute of Technology (Caltech) +Copyright: 2016 David Mathog and California Institute of Technology (Caltech) */ #ifdef __cplusplus @@ -1884,15 +1884,21 @@ void U_EMRPAINTRGN_print(const char *contents){ */ void U_EMREXTSELECTCLIPRGN_print(const char *contents){ PU_EMREXTSELECTCLIPRGN pEmr = (PU_EMREXTSELECTCLIPRGN) (contents); - if(pEmr->emr.nSize < sizeof(U_EMREXTSELECTCLIPRGN)){ + if(pEmr->emr.nSize < U_SIZE_EMREXTSELECTCLIPRGN){ printf(" record corruption HERE\n"); return; } const char *blimit = contents + pEmr->emr.nSize; printf(" cbRgnData: %u\n",pEmr->cbRgnData); printf(" iMode: %u\n",pEmr->iMode); - const char *minptr = MAKE_MIN_PTR(((const char *) &pEmr->RgnData + pEmr->cbRgnData),blimit); - printf(" RegionData: "); rgndata_print(pEmr->RgnData, minptr); printf("\n"); + if(pEmr->iMode == U_RGN_COPY && !pEmr->cbRgnData){ + printf(" RegionData: none (Clip region becomes NULL)\n"); + } + else { + const char *minptr = MAKE_MIN_PTR(((const char *) &pEmr->RgnData + pEmr->cbRgnData),blimit); + printf(" RegionData: "); rgndata_print(pEmr->RgnData, minptr); printf("\n"); + } + } // U_EMRBITBLT 76 diff --git a/src/libuemf/uemf_safe.c b/src/libuemf/uemf_safe.c index 36284d60e..a3e050282 100644 --- a/src/libuemf/uemf_safe.c +++ b/src/libuemf/uemf_safe.c @@ -15,11 +15,11 @@ /* File: uemf_safe.c -Version: 0.0.4 -Date: 23-APR-2015 +Version: 0.0.5 +Date: 26-JAN-2016 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu -Copyright: 2015 David Mathog and California Institute of Technology (Caltech) +Copyright: 2016 David Mathog and California Institute of Technology (Caltech) */ #ifdef __cplusplus @@ -740,6 +740,8 @@ int U_EMREXTSELECTCLIPRGN_safe(const char *record){ if(!core5_safe(record, U_SIZE_EMREXTSELECTCLIPRGN))return(0); PU_EMREXTSELECTCLIPRGN pEmr = (PU_EMREXTSELECTCLIPRGN)(record); int cbRgnData = pEmr->cbRgnData; + /* data size can be 0 with COPY mode, it means clear the clip region. */ + if(pEmr->iMode == U_RGN_COPY && !cbRgnData)return(1); const char *blimit = record + pEmr->emr.nSize; if(IS_MEM_UNSAFE(pEmr->RgnData, cbRgnData, blimit))return(0); return(rgndata_safe(pEmr->RgnData, cbRgnData)); diff --git a/src/libuemf/upmf.c b/src/libuemf/upmf.c index fe929e443..5cb558ac6 100644 --- a/src/libuemf/upmf.c +++ b/src/libuemf/upmf.c @@ -21,11 +21,11 @@ /* File: upmf.c -Version: 0.0.11 -Date: 28-MAY-2015 +Version: 0.0.12 +Date: 26-JAN-2016 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu -Copyright: 2015 David Mathog and California Institute of Technology (Caltech) +Copyright: 2016 David Mathog and California Institute of Technology (Caltech) */ #ifdef __cplusplus @@ -4125,7 +4125,6 @@ U_PSEUDO_OBJ *U_PMR_DRAWCURVE_set(uint32_t PenID, U_FLOAT Tension, uint32_t Offs \brief Create and set a U_PMR_DRAWDRIVERSTRING PseudoObject \return Pointer to PseudoObject, NULL on error \param FontID U_PMF_FONT object in the EMF+ object table (0-63, inclusive) - \param Tension Controls splines, 0 is straight line, >0 is curved \param BrushID U_PSEUDO_OBJ containing a U_PMF_ARGB or a U_PMF_4NUM. Color or U_PMF_BRUSH object in the EMF+ object table (0-63, inclusive) \param DSOFlags DriverStringOptions flags \param HasMatrix If 1 record contains a TransformMatrix field, if 0 it does not. @@ -4137,7 +4136,7 @@ U_PSEUDO_OBJ *U_PMR_DRAWCURVE_set(uint32_t PenID, U_FLOAT Tension, uint32_t Offs EMF+ manual 2.3.4.6, Microsoft name: EmfPlusDrawDriverString Record, Index 0x36 */ -U_PSEUDO_OBJ *U_PMR_DRAWDRIVERSTRING_set(uint32_t FontID, U_FLOAT Tension, const U_PSEUDO_OBJ *BrushID, +U_PSEUDO_OBJ *U_PMR_DRAWDRIVERSTRING_set(uint32_t FontID, const U_PSEUDO_OBJ *BrushID, uint32_t DSOFlags, uint32_t HasMatrix, uint32_t GlyphCount, const uint16_t *Glyphs, const U_PSEUDO_OBJ *Points, const U_PSEUDO_OBJ *Tm){ int btype; @@ -4163,7 +4162,6 @@ U_PSEUDO_OBJ *U_PMR_DRAWDRIVERSTRING_set(uint32_t FontID, U_FLOAT Tension, const U_PSEUDO_OBJ *ph = U_PMR_CMN_HDR_set(U_PMR_DRAWDRIVERSTRING,utmp16,Size); const U_SERIAL_DESC List[] = { {ph->Data,ph->Used, 1, U_XE}, - {&Tension, 4, 1, U_LE}, {BrushID->Data, BrushID->Used, 1, U_XE}, {&DSOFlags, 4, 1, U_LE}, {&HasMatrix, 4, 1, U_LE}, @@ -7469,7 +7467,6 @@ int U_PMR_DRAWCURVE_get(const char *contents, U_PMF_CMN_HDR *Header, \param Header Common header \param FontID U_PMF_FONT object in the EMF+ object table (0-63, inclusive) \param btype Set: BrushID is an U_PFM_ARGB; Clear: index of U_PMF_BRUSH object in EMF+ object table. - \param Tension Controls splines, 0 is straight line, >0 is curved \param BrushID Color or index of U_PMF_BRUSH object in the EMF+ object table, depends on Flags bit0 \param DSOFlags DriverStringOptions flags \param HasMatrix If 1 record contains a TransformMatrix field, if 0 it does not. @@ -7482,9 +7479,9 @@ int U_PMR_DRAWCURVE_get(const char *contents, U_PMF_CMN_HDR *Header, */ int U_PMR_DRAWDRIVERSTRING_get(const char *contents, U_PMF_CMN_HDR *Header, uint32_t *FontID, int *btype, - U_FLOAT *Tension, uint32_t *BrushID, uint32_t *DSOFlags, uint32_t *HasMatrix, uint32_t *Elements, + uint32_t *BrushID, uint32_t *DSOFlags, uint32_t *HasMatrix, uint32_t *Elements, uint16_t **Glyphs, U_PMF_POINTF **Points, U_PMF_TRANSFORMMATRIX **Matrix){ - if(!contents || !FontID || !btype || !Tension || !BrushID || + if(!contents || !FontID || !btype || !BrushID || !DSOFlags || !HasMatrix || !Elements || !Glyphs || !Points || !Matrix){ return(0); } const char *blimit = contents; @@ -7496,7 +7493,6 @@ int U_PMR_DRAWDRIVERSTRING_get(const char *contents, U_PMF_CMN_HDR *Header, *btype = (lclHeader.Flags & U_PPF_B ? 1 : 0 ); *FontID = (lclHeader.Flags >> U_FF_SHFT_OID8) & U_FF_MASK_OID8; - U_PMF_SERIAL_get(&contents, Tension, 4, 1, U_LE); U_PMF_SERIAL_get(&contents, BrushID, 4, 1, (*btype ? U_XE : U_LE)); /* color is not byte swapped, ID integer is */ U_PMF_SERIAL_get(&contents, DSOFlags, 4, 1, U_LE); U_PMF_SERIAL_get(&contents, HasMatrix, 4, 1, U_LE); diff --git a/src/libuemf/upmf.h b/src/libuemf/upmf.h index dbda02ba7..4fb7ad492 100644 --- a/src/libuemf/upmf.h +++ b/src/libuemf/upmf.h @@ -27,11 +27,11 @@ /* File: upmf.h -Version: 0.0.4 -Date: 17-MAR-2015 +Version: 0.0.5 +Date: 26-JAN-2016 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu -Copyright: 2015 David Mathog and California Institute of Technology (Caltech) +Copyright: 2016 David Mathog and California Institute of Technology (Caltech) */ #ifndef _UPMF_ @@ -2289,7 +2289,6 @@ typedef struct { */ typedef struct { U_PMF_CMN_HDR Header; //!< Common header - U_FLOAT Tension; //!< Controls splines, 0 is straight line, >0 is curved uint32_t BrushID; //!< Color or index to Brush object, depends on Flags bit0 uint32_t DSOFlags; //!< DriverStringOptions flags uint32_t HasMatrix; //!< If 1 record contains a TransformMatrix field, if 0 it does not. @@ -2987,7 +2986,7 @@ U_PSEUDO_OBJ *U_PMR_DRAWARC_set(uint32_t PenID, U_FLOAT Start, U_FLOAT Sweep, co U_PSEUDO_OBJ *U_PMR_DRAWBEZIERS_set(uint32_t PenID, const U_PSEUDO_OBJ *Points); U_PSEUDO_OBJ *U_PMR_DRAWCLOSEDCURVE_set(uint32_t PenID, U_FLOAT Tension, const U_PSEUDO_OBJ *Points); U_PSEUDO_OBJ *U_PMR_DRAWCURVE_set(uint32_t PenID, U_FLOAT Tension,uint32_t Offset, uint32_t NSegs, const U_PSEUDO_OBJ *Points); -U_PSEUDO_OBJ *U_PMR_DRAWDRIVERSTRING_set(uint32_t FontID, U_FLOAT Tension, const U_PSEUDO_OBJ *BrushID, +U_PSEUDO_OBJ *U_PMR_DRAWDRIVERSTRING_set(uint32_t FontID, const U_PSEUDO_OBJ *BrushID, uint32_t DSOFlags, uint32_t HasMatrix, uint32_t GlyphCount, const uint16_t *Glyphs, const U_PSEUDO_OBJ *Points, const U_PSEUDO_OBJ *Tm); U_PSEUDO_OBJ *U_PMR_DRAWELLIPSE_set(uint32_t PenID, const U_PSEUDO_OBJ *Rect); @@ -3125,7 +3124,7 @@ int U_PMR_DRAWARC_get(const char *contents, U_PMF_CMN_HDR *Header, uint32_t *Pen int U_PMR_DRAWBEZIERS_get(const char *contents, U_PMF_CMN_HDR *Header, uint32_t *PenID, int *ctype, int *RelAbs, uint32_t *Elements, U_PMF_POINTF **Points); int U_PMR_DRAWCLOSEDCURVE_get(const char *contents, U_PMF_CMN_HDR *Header, uint32_t *PenID, int *ctype, int *RelAbs, U_FLOAT *Tension, uint32_t *Elements, U_PMF_POINTF **Points); int U_PMR_DRAWCURVE_get(const char *contents, U_PMF_CMN_HDR *Header, uint32_t *PenID, int *ctype, U_FLOAT *Tension, uint32_t *Offset, uint32_t *NSegs, uint32_t *Elements, U_PMF_POINTF **Points); -int U_PMR_DRAWDRIVERSTRING_get(const char *contents, U_PMF_CMN_HDR *Header, uint32_t *FontID, int *btype, U_FLOAT *Tension, uint32_t *BrushID, uint32_t *DSOFlags, uint32_t *HasMatrix, uint32_t *Elements, uint16_t **Glyphs, U_PMF_POINTF **Points, U_PMF_TRANSFORMMATRIX **Matrix); +int U_PMR_DRAWDRIVERSTRING_get(const char *contents, U_PMF_CMN_HDR *Header, uint32_t *FontID, int *btype, uint32_t *BrushID, uint32_t *DSOFlags, uint32_t *HasMatrix, uint32_t *Elements, uint16_t **Glyphs, U_PMF_POINTF **Points, U_PMF_TRANSFORMMATRIX **Matrix); int U_PMR_DRAWELLIPSE_get(const char *contents, U_PMF_CMN_HDR *Header, uint32_t *PenID, int *ctype, U_PMF_RECTF *Rect); int U_PMR_DRAWIMAGE_get(const char *contents, U_PMF_CMN_HDR *Header, uint32_t *ImgID, int *ctype, uint32_t *ImgAttrID, int32_t *SrcUnit, U_PMF_RECTF *SrcRect, U_PMF_RECTF *DstRect); int U_PMR_DRAWIMAGEPOINTS_get(const char *contents, U_PMF_CMN_HDR *Header, uint32_t *ImgID, int *ctype, int *etype, int *RelAbs, uint32_t *ImgAttrID, int32_t *SrcUnit, U_PMF_RECTF *SrcRect, uint32_t *Elements, U_PMF_POINTF **Points); diff --git a/src/libuemf/upmf_print.c b/src/libuemf/upmf_print.c index 58ff4edd0..69fad3691 100644 --- a/src/libuemf/upmf_print.c +++ b/src/libuemf/upmf_print.c @@ -6,11 +6,11 @@ /* File: upmf_print.c -Version: 0.0.7 -Date: 21-MAY-2015 +Version: 0.0.8 +Date: 26-JAN-2016 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu -Copyright: 2015 David Mathog and California Institute of Technology (Caltech) +Copyright: 2016 David Mathog and California Institute of Technology (Caltech) */ /* compiler options: @@ -2379,19 +2379,19 @@ int U_PMR_DRAWDRIVERSTRING_print(const char *contents){ unsigned int i; uint32_t FontID; int btype; - U_FLOAT Tension; uint32_t BrushID, DSOFlags, HasMatrix, Elements; uint16_t *Glyphs; + uint16_t *GlyphsIter; U_PMF_POINTF *Points; U_PMF_TRANSFORMMATRIX *Matrix; int status = U_PMR_DRAWDRIVERSTRING_get(contents, NULL, &FontID, &btype, - &Tension, &BrushID, &DSOFlags, &HasMatrix, &Elements,&Glyphs, &Points, &Matrix); + &BrushID, &DSOFlags, &HasMatrix, &Elements,&Glyphs, &Points, &Matrix); if(status){ - printf(" + FontID:%u btype:%d Tension:%f BrushID:%u DSOFlags:%X Elements:%u\n", FontID,btype,Tension, BrushID, DSOFlags, Elements); + printf(" + FontID:%u btype:%d BrushID:%u DSOFlags:%X Elements:%u\n", FontID,btype, BrushID, DSOFlags, Elements); printf(" + Glyphs:"); if(*Glyphs){ - for(i=0; i Date: Wed, 27 Jan 2016 10:07:29 -0800 Subject: patch should fix bug 1538361 (bzr r14618) --- src/libuemf/uemf.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libuemf/uemf.h b/src/libuemf/uemf.h index f6ed7da03..1f5255891 100644 --- a/src/libuemf/uemf.h +++ b/src/libuemf/uemf.h @@ -95,11 +95,11 @@ these WMF enumerations is by referencing the following table: /* File: uemf.h -Version: 0.0.32 -Date: 28-APR-2015 +Version: 0.0.33 +Date: 27-JAN-2016 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu -Copyright: 2015 David Mathog and California Institute of Technology (Caltech) +Copyright: 2016 David Mathog and California Institute of Technology (Caltech) */ #ifndef _UEMF_ @@ -2017,6 +2017,7 @@ typedef struct { U_STYLEENTRY elpStyleEntry[1]; //!< Array of StyleEntry (For user specified dot/dash patterns) } U_EXTLOGPEN, *PU_EXTLOGPEN; //!< EMF manual 2.2.20 +#define U_SIZE_EXTLOGPEN (sizeof(U_EXTLOGPEN) - sizeof(U_STYLEENTRY)) // there may not be any style entries /** \brief For U_EMR_* OffBmi* fields @@ -3029,7 +3030,9 @@ typedef struct { //!< Record may include optional DIB bitmap } U_EMREXTCREATEPEN, *PU_EMREXTCREATEPEN; //!< EMF manual 2.3.7.9 -#define U_SIZE_EMREXTCREATEPEN (sizeof(U_EMREXTCREATEPEN)) +/* extlogpen has a field on the end which may or may not be present in a record, so use the predefined size instead +of the struct size */ +#define U_SIZE_EMREXTCREATEPEN (sizeof(U_EMREXTCREATEPEN) - sizeof(U_EXTLOGPEN) + U_SIZE_EXTLOGPEN) /* Index 96.97 */ /** EMF manual 2.3.5.32 -- cgit v1.2.3 From 28d527218e877a018255618f4cf467a75e22b4e9 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Wed, 27 Jan 2016 12:01:29 -0800 Subject: sync Inkscape to libUEMF changes (bzr r14619) --- src/libuemf/uemf.h | 19 ++++++++++++------- src/libuemf/uwmf.h | 9 +++++---- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/libuemf/uemf.h b/src/libuemf/uemf.h index 1f5255891..82fd0990c 100644 --- a/src/libuemf/uemf.h +++ b/src/libuemf/uemf.h @@ -426,6 +426,7 @@ typedef struct { uint32_t biClrImportant; //!< Number of bmciColors needed (0 means all). } U_BITMAPINFOHEADER, *PU_BITMAPINFOHEADER; //!< WMF manual 2.2.2.3 +#define U_SIZE_BITMAPINFOHEADER (sizeof(U_BITMAPINFOHEADER)) /** WMF manual 2.2.2.6 \brief For U_CIEXYZTRIPLE (all) fields @@ -1678,6 +1679,7 @@ typedef struct { U_FNTAXES Values[1]; //!< Optional. Array of font axes for opentype font } U_DESIGNVECTOR, *PU_DESIGNVECTOR; //!< EMF manual 2.2.3 +#define U_SIZE_DESIGNVECTOR (sizeof(uint32_t) + sizeof(U_NUM_FNTAXES)) /** \brief For U_EMR_COMMENT_MULTIFORMATS record, where an array of these is used @@ -1901,6 +1903,7 @@ typedef struct { U_LOGPLTNTRY palPalEntry[1]; //!< PC_Entry Enumeration } U_LOGPALETTE, *PU_LOGPALETTE; //!< EMF manual 2.2.17 +#define U_SIZE_LOGPALETTE (2*sizeof(uint16_t)) // Microsoft name: LogPaletteEntry Object, EMF manual 2.2.18, defined above, before 2.2.17 @@ -1970,6 +1973,7 @@ typedef struct { U_RECTL rclBounds; //!< Region bounds } U_RGNDATAHEADER, *PU_RGNDATAHEADER; //!< EMF manual 2.2.25 +#define U_SIZE_RGNDATAHEADER (sizeof(U_RGNDATAHEADER)) /** \brief For U_EMRFILLRGN RgnData field(s) @@ -1982,6 +1986,7 @@ typedef struct { U_RECTL Buffer[1]; //!< Array of U_RECTL elements } U_RGNDATA, *PU_RGNDATA; //!< EMF manual 2.2.24 +#define U_SIZE_RGNDATA U_SIZE_RGNDATAHEADER // Microsoft name: RegionDataHeader Object. EMF manual 2.2.25, defined above, before 2.2.24 // Microsoft name: TriVertex Object. EMF manual 2.2.26, defined above, before 2.2.7 @@ -2031,6 +2036,7 @@ typedef struct { U_RGBQUAD bmiColors[1]; //!< Color table. 24 bit images do not use color table values. } U_BITMAPINFO, *PU_BITMAPINFO; //!< WMF Manual 2.2.2.9 +#define U_SIZE_BITMAPINFO U_SIZE_BITMAPINFOHEADER /** \brief U_EMRALPHABLEND Blend field @@ -2057,6 +2063,7 @@ typedef struct { uint32_t dParm[1]; //!< Data in record } U_ENHMETARECORD, *PU_ENHMETARECORD; //!< General form of an EMF record. +#define U_SIZE_ENHMETARECORD (2*sizeof(uint32_t)) /** First two fields of all EMF records, First two fields of all EMF+ records (1 or more within an EMF comment) @@ -2172,7 +2179,7 @@ typedef struct { U_EMRPOLYPOLYGON, //!< EMF manual 2.3.5.28 *PU_EMRPOLYPOLYLINE, //!< EMF manual 2.3.5.30 *PU_EMRPOLYPOLYGON; //!< EMF manual 2.3.5.28 -#define U_SIZE_EMRPOLYPOLYLINE (sizeof(U_EMR) + sizeof(U_RECTL) + sizeof(U_NUM_POLYCOUNTS) + sizeof(U_POLYCOUNTS)) +#define U_SIZE_EMRPOLYPOLYLINE (sizeof(U_EMR) + sizeof(U_RECTL) + sizeof(U_NUM_POLYCOUNTS) + sizeof(U_NUM_POINTL)) #define U_SIZE_EMRPOLYPOLYGON U_SIZE_EMRPOLYPOLYLINE /* Index 9,11 (numbers interleave with next one) */ @@ -2536,10 +2543,10 @@ typedef struct { typedef struct { U_EMR emr; //!< U_EMR uint32_t ihPal; //!< Index to place object in EMF object table (this entry must not yet exist) - U_LOGPALETTE lgpl; //!< Palette properties + U_LOGPALETTE lgpl; //!< Palette properties (variable size) } U_EMRCREATEPALETTE, *PU_EMRCREATEPALETTE; //!< EMF manual 2.3.7.6 -#define U_SIZE_EMRCREATEPALETTE (sizeof(U_EMRCREATEPALETTE)) +#define U_SIZE_EMRCREATEPALETTE (sizeof(U_EMR) + sizeof(uint32_t) + U_SIZE_LOGPALETTE) /* Index 50 */ /** EMF manual 2.3.8.8 @@ -3030,8 +3037,6 @@ typedef struct { //!< Record may include optional DIB bitmap } U_EMREXTCREATEPEN, *PU_EMREXTCREATEPEN; //!< EMF manual 2.3.7.9 -/* extlogpen has a field on the end which may or may not be present in a record, so use the predefined size instead -of the struct size */ #define U_SIZE_EMREXTCREATEPEN (sizeof(U_EMREXTCREATEPEN) - sizeof(U_EXTLOGPEN) + U_SIZE_EXTLOGPEN) /* Index 96.97 */ @@ -3087,7 +3092,7 @@ typedef struct { U_DATA Data[1]; //!< OpenGL data } U_EMRGLSRECORD, *PU_EMRGLSRECORD; //!< EMF manual 2.3.9.2 -#define U_SIZE_EMRGLSRECORD (sizeof(U_EMRGLSRECORD)) +#define U_SIZE_EMRGLSRECORD (sizeof(U_EMR) + sizeof(U_CBDATA)) /* Index 103 */ /** EMF manual 2.3.9.1 @@ -3170,7 +3175,7 @@ typedef struct { uint16_t Driver[1]; //!< Driver name in uint16_t characters, null terminated } U_EMRNAMEDESCAPE, *PU_EMRNAMEDESCAPE; //!< EMF manual 2.3.6.3 -#define U_SIZE_EMRNAMEDESCAPE (sizeof(U_EMRNAMEDESCAPE)) +#define U_SIZE_EMRNAMEDESCAPE (sizeof(U_EMR) + 2*sizeof(U_CBDATA)) /* Index 111-113 (not implemented ) EMF manual 2.3.8.1 diff --git a/src/libuemf/uwmf.h b/src/libuemf/uwmf.h index 027de8e06..138ffab37 100644 --- a/src/libuemf/uwmf.h +++ b/src/libuemf/uwmf.h @@ -36,11 +36,11 @@ /* File: uwmf.h -Version: 0.0.12 -Date: 28-APR-2015 +Version: 0.0.13 +Date: 26-JAN-2016 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu -Copyright: 2015 David Mathog and California Institute of Technology (Caltech) +Copyright: 2016 David Mathog and California Institute of Technology (Caltech) */ #ifndef _UWMF_ @@ -643,7 +643,8 @@ enum U_WMR_TYPES{ #define U_SIZE_REGION 20 /**< X 22 20 is minums the variable part */ #define U_SIZE_BITMAP16 10 /**< + 10 */ #define U_SIZE_BITMAPCOREHEADER 12 /**< + 12 */ -#define U_SIZE_BITMAPINFOHEADER 40 /**< + 40 */ +// also defined in uemf.h, avoid redefining. Same value in both places, of course. +// # define U_SIZE_BITMAPINFOHEADER 40 /**< + 40 */ #define U_SIZE_BITMAPV4HEADER 108 /**< ? 108 not tested */ #define U_SIZE_BITMAPV5HEADER 124 /**< ? 124 not tested */ #define U_SIZE_WLOGBRUSH 8 /**< + 8 */ -- cgit v1.2.3 From d5c14417a51b4ce3a3c9a788353c004377ec31d2 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Wed, 27 Jan 2016 15:01:00 -0800 Subject: patch fixes bug 1538786 (bzr r14620) --- src/extension/internal/emf-print.cpp | 49 ++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index 53120637c..3dfa5cb23 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -792,9 +792,9 @@ void PrintEmf::destroy_pen() } } -/* Return a Path consisting of just the corner points of the single path in a a PathVector. If the +/* Return a Path consisting of just the corner points of the single path in a PathVector. If the PathVector has more than one path, or that one path is open, or any of its segments are curved, then the -returned PathVector is . If the input path is already just straight lines and vertices the output will be the +returned PathVector is an empty path. If the input path is already just straight lines and vertices the output will be the same as the sole path in the input. */ Geom::Path PrintEmf::pathv_to_simple_polygon(Geom::PathVector const &pathv, int *vertices) @@ -808,6 +808,7 @@ Geom::Path PrintEmf::pathv_to_simple_polygon(Geom::PathVector const &pathv, int Geom::PathVector pv = pathv_to_linear_and_cubic_beziers(pathv); Geom::PathVector::const_iterator pit = pv.begin(); Geom::PathVector::const_iterator pit2 = pv.begin(); + int first_seg=1; ++pit2; *vertices = 0; if(pit->end_closed() != pit->end_default())return(bad); // path must be closed @@ -833,9 +834,17 @@ Geom::Path PrintEmf::pathv_to_simple_polygon(Geom::PathVector const &pathv, int output.start( P1 ); output.close( pit->closed() ); } - *vertices += 1; - Geom::LineSegment ls(P1_trail, P1); - output.append(ls); + if(!Geom::are_near(P1, P1_trail, 1e-5)){ // possible for P1 to start on the end point + Geom::LineSegment ls(P1_trail, P1); + output.append(ls); + if(first_seg){ + *vertices += 2; + first_seg=0; + } + else { + *vertices += 1; + } + } P1_trail = P1; P1 = P1_lead; } @@ -850,7 +859,6 @@ Geom::Path PrintEmf::pathv_to_rect(Geom::PathVector const &pathv, bool *is_rect, { Geom::Point P1_trail; Geom::Point P1; - Geom::Point P1_lead; Geom::Point v1,v2; int vertices; Geom::Path pR = pathv_to_simple_polygon(pathv, &vertices); @@ -860,7 +868,7 @@ Geom::Path PrintEmf::pathv_to_rect(Geom::PathVector const &pathv, bool *is_rect, /* Get the ends of the LAST line segment. Find minimum rotation to align rectangle with X,Y axes. (Very degenerate if it is rotated 45 degrees.) */ *angle = 10.0; /* must be > than the actual angle in radians. */ - for(Geom::Path::iterator cit = pR.begin(); cit != pR.end_open(); ++cit){ + for(Geom::Path::iterator cit = pR.begin();; ++cit){ P1_trail = cit->initialPoint(); P1 = cit->finalPoint(); v1 = unit_vector(P1 - P1_trail); @@ -868,21 +876,23 @@ Geom::Path PrintEmf::pathv_to_rect(Geom::PathVector const &pathv, bool *is_rect, double ang = asin(v1[Geom::Y]); // because component is rotation by ang of {1,0| vector if(fabs(ang) < fabs(*angle))*angle = -ang; // y increases down, flips sign on angle } + if(cit == pR.end_open())break; } /* For increased numerical stability, snap the angle to the nearest 1/100th of a degree. */ double convert = 36000.0/ (2.0 * M_PI); *angle = round(*angle * convert)/convert; - for(Geom::Path::iterator cit = pR.begin(); cit != pR.end_open();++cit) { - P1_lead = cit->finalPoint(); + // at this stage v1 holds the last vector in the path, whichever direction it points. + for(Geom::Path::iterator cit = pR.begin(); ;++cit) { + v2 = v1; + P1_trail = cit->initialPoint(); + P1 = cit->finalPoint(); v1 = unit_vector(P1 - P1_trail); - v2 = unit_vector(P1_lead - P1 ); // P1 is center of a turn that is not 90 degrees. Limit comes from cos(89.9) = .001745 if(!Geom::are_near(dot(v1,v2), 0.0, 2e-3))break; - P1_trail = P1; - P1 = P1_lead; vertex_count++; + if(cit == pR.end_open())break; } if(vertex_count == 4){ *is_rect=true; @@ -903,13 +913,11 @@ int PrintEmf::vector_rect_alignment(double angle, Geom::Point vtest){ int stat = 0; Geom::Point v1 = Geom::unit_vector(vtest); // unit vector to test alignment Geom::Point v2 = Geom::Point(1,0) * Geom::Rotate(-angle); // unit horizontal side (sign change because Y increases DOWN) + Geom::Point v3 = Geom::Point(0,1) * Geom::Rotate(-angle); // unit horizontal side (sign change because Y increases DOWN) if( Geom::are_near(dot(v1,v2), 1.0, 1e-5)){ stat = 1; } else if(Geom::are_near(dot(v1,v2),-1.0, 1e-5)){ stat = 2; } - if(!stat){ - v2 = Geom::Point(0,1) * Geom::Rotate(-angle); // unit vertical side - if( Geom::are_near(dot(v1,v2), 1.0, 1e-5)){ stat = 3; } - else if(Geom::are_near(dot(v1,v2),-1.0, 1e-5)){ stat = 4; } - } + else if(Geom::are_near(dot(v1,v3), 1.0, 1e-5)){ stat = 3; } + else if(Geom::are_near(dot(v1,v3),-1.0, 1e-5)){ stat = 4; } return(stat); } @@ -924,8 +932,9 @@ int PrintEmf::vector_rect_alignment(double angle, Geom::Point vtest){ */ Geom::Point PrintEmf::get_pathrect_corner(Geom::Path pathRect, double angle, int corner){ Geom::Point center(0,0); - for(Geom::Path::iterator cit = pathRect.begin(); cit != pathRect.end_open(); ++cit) { + for(Geom::Path::iterator cit = pathRect.begin(); ; ++cit) { center += cit->initialPoint()/4.0; + if(cit == pathRect.end_open())break; } int LR; // 1 if Left, 0 if Right @@ -952,11 +961,12 @@ Geom::Point PrintEmf::get_pathrect_corner(Geom::Path pathRect, double angle, int Geom::Point v1 = Geom::Point(1,0) * Geom::Rotate(-angle); // unit horizontal side (sign change because Y increases DOWN) Geom::Point v2 = Geom::Point(0,1) * Geom::Rotate(-angle); // unit vertical side (sign change because Y increases DOWN) Geom::Point P1; - for(Geom::Path::iterator cit = pathRect.begin(); cit != pathRect.end_open(); ++cit) { + for(Geom::Path::iterator cit = pathRect.begin(); ; ++cit) { P1 = cit->initialPoint(); if ( ( LR == (dot(P1 - center,v1) > 0 ? 0 : 1) ) && ( UL == (dot(P1 - center,v2) > 0 ? 1 : 0) ) ) break; + if(cit == pathRect.end_open())break; } return(P1); } @@ -1279,6 +1289,7 @@ unsigned int PrintEmf::fill( outLR = Geom::Point(wRect,doff_range*hRect); gMode = U_GRADIENT_FILL_RECT_V; } + doff_base = doff_range; rcb.left = round(outUL[X]); // use explicit round for better stability rcb.top = round(outUL[Y]); -- cgit v1.2.3 From b15f26139abe930cb84d986c262302a9a1c18c04 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 28 Jan 2016 17:42:16 +0100 Subject: Add dinamic toolbar to spray,poligon/star and wrap tools (bzr r14621) --- src/widgets/spray-toolbar.cpp | 107 ++++++++++++++++++++++-------------------- src/widgets/star-toolbar.cpp | 12 ++--- src/widgets/toolbox.cpp | 4 +- src/widgets/tweak-toolbar.cpp | 18 +++---- 4 files changed, 74 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index c4fbbca82..4ff469257 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -58,58 +58,69 @@ using Inkscape::UI::PrefPusher; //## Spray ## //######################## -static void sp_stb_sensitivize( GObject *tbl ) +static void sp_stb_update_widgets( GObject *tbl ) { GtkAction* offset = GTK_ACTION( g_object_get_data(tbl, "offset") ); GtkAction* spray_scale = GTK_ACTION( g_object_get_data(tbl, "spray_scale") ); GtkAdjustment *adj_offset = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(offset) ); GtkAdjustment *adj_scale = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(spray_scale) ); + GtkAction *no_overlap_action = GTK_ACTION( g_object_get_data(tbl, "no_overlap") ); GtkToggleAction *no_overlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "no_overlap") ); + GtkAction *picker_action = GTK_ACTION( g_object_get_data(tbl, "picker") ); GtkToggleAction *picker = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "picker") ); - GtkAction* picker_action = GTK_ACTION( g_object_get_data(tbl, "picker") ); GtkToggleAction *usepressurescale = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "usepressurescale") ); GtkAction *pick_fill = GTK_ACTION( g_object_get_data(tbl, "pick_fill") ); GtkAction *pick_stroke = GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ); GtkAction *pick_inverse_value = GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ); GtkAction *pick_center = GTK_ACTION( g_object_get_data(tbl, "pick_center") ); gtk_adjustment_set_value( adj_offset, 100.0 ); - if (gtk_toggle_action_get_active(no_overlap) && gtk_action_get_sensitive(picker_action)) { - gtk_action_set_sensitive( offset, TRUE ); + if (gtk_toggle_action_get_active(no_overlap) && gtk_action_get_visible(no_overlap_action)) { + gtk_action_set_visible( offset, true ); } else { - gtk_action_set_sensitive( offset, FALSE ); + gtk_action_set_visible( offset, false ); } if (gtk_toggle_action_get_active(usepressurescale)) { gtk_adjustment_set_value( adj_scale, 0.0 ); - gtk_action_set_sensitive( spray_scale, FALSE ); + gtk_action_set_sensitive( spray_scale, false ); } else { - gtk_action_set_sensitive( spray_scale, TRUE ); + gtk_action_set_sensitive( spray_scale, true ); } - if(gtk_toggle_action_get_active(picker) && gtk_action_get_sensitive(picker_action)){ - gtk_action_set_sensitive( pick_fill, TRUE ); - gtk_action_set_sensitive( pick_stroke, TRUE ); - gtk_action_set_sensitive( pick_inverse_value, TRUE ); - gtk_action_set_sensitive( pick_center, TRUE ); + if(gtk_toggle_action_get_active(picker) && gtk_action_get_visible(picker_action)){ + gtk_action_set_visible( pick_fill, true ); + gtk_action_set_visible( pick_stroke, true ); + gtk_action_set_visible( pick_inverse_value, true ); + gtk_action_set_visible( pick_center, true ); } else { - gtk_action_set_sensitive( pick_fill, FALSE ); - gtk_action_set_sensitive( pick_stroke, FALSE ); - gtk_action_set_sensitive( pick_inverse_value, FALSE ); - gtk_action_set_sensitive( pick_center, FALSE ); + gtk_action_set_visible( pick_fill, false ); + gtk_action_set_visible( pick_stroke, false ); + gtk_action_set_visible( pick_inverse_value, false ); + gtk_action_set_visible( pick_center, false ); } } -static void sp_spray_erase_sensitivize( GObject *tbl, bool sensitive){ - gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "no_overlap") ), sensitive ); - gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "over_no_transparent") ), sensitive ); - gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "over_transparent") ), sensitive ); - gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "pick_no_overlap") ), sensitive ); - gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ), sensitive ); - gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "pick_fill") ), sensitive ); - gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ), sensitive ); - gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "pick_center") ), sensitive ); - gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "picker") ), sensitive ); - gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "offset") ), sensitive ); - gtk_action_set_sensitive( GTK_ACTION( g_object_get_data(tbl, "spray_rotation") ), sensitive ); - sp_stb_sensitivize( tbl ); +static void sp_spray_init( GObject *tbl){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int mode = prefs->getInt("/tools/spray/mode", 0); + bool show = true; + if(mode == 3){ + show = false; + } + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "no_overlap") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "over_no_transparent") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "over_transparent") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_no_overlap") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_fill") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_center") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "picker") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "offset") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "spray_rotation") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_fill") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_center") ), show ); + sp_stb_update_widgets( tbl ); } Inkscape::UI::Dialog::CloneTiler *get_clone_tiler_panel(SPDesktop *desktop) @@ -152,11 +163,7 @@ static void sp_spray_mode_changed( EgeSelectOneAction *act, GObject * tbl ) int mode = ege_select_one_action_get_active( act ); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setInt("/tools/spray/mode", mode); - if(mode != 3){ - sp_spray_erase_sensitivize(tbl, true); - } else { - sp_spray_erase_sensitivize(tbl, false); - } + sp_spray_init(tbl); } static void sp_spray_population_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) @@ -193,7 +200,7 @@ static void sp_toggle_no_overlap( GtkToggleAction* act, gpointer data) gboolean active = gtk_toggle_action_get_active(act); prefs->setBool("/tools/spray/no_overlap", active); GObject *tbl = G_OBJECT(data); - sp_stb_sensitivize(tbl); + sp_stb_update_widgets(tbl); } static void sp_toggle_pressure_scale( GtkToggleAction* act, gpointer data) @@ -205,7 +212,7 @@ static void sp_toggle_pressure_scale( GtkToggleAction* act, gpointer data) prefs->setDouble("/tools/spray/scale_variation", 0); } GObject *tbl = G_OBJECT(data); - sp_stb_sensitivize( tbl ); + sp_stb_update_widgets( tbl ); } static void sp_toggle_over_no_transparent( GtkToggleAction* act, gpointer data) @@ -237,7 +244,7 @@ static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) } } GObject *tbl = G_OBJECT(data); - sp_stb_sensitivize(tbl); + sp_stb_update_widgets(tbl); } static void sp_toggle_pick_center( GtkToggleAction* act, gpointer data ) @@ -286,13 +293,13 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj EgeAdjustmentAction *eact = create_adjustment_action( "SprayWidthAction", _("Width"), _("Width:"), _("The width of the spray area (relative to the visible canvas area)"), "/tools/spray/width", 15, - GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-spray", + GTK_WIDGET(desktop->canvas), holder, true, "altx-spray", 1, 100, 1.0, 10.0, labels, values, G_N_ELEMENTS(labels), sp_spray_width_value_changed, NULL /*unit tracker*/, 1, 0 ); ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + gtk_action_set_sensitive( GTK_ACTION(eact), true ); } /* Use Pressure Width button */ @@ -315,13 +322,13 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj EgeAdjustmentAction *eact = create_adjustment_action( "SprayMeanAction", _("Focus"), _("Focus:"), _("0 to spray a spot; increase to enlarge the ring radius"), "/tools/spray/mean", 0, - GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-mean", + GTK_WIDGET(desktop->canvas), holder, true, "spray-mean", 0, 100, 1.0, 10.0, labels, values, G_N_ELEMENTS(labels), sp_spray_mean_value_changed, NULL /*unit tracker*/, 1, 0 ); ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + gtk_action_set_sensitive( GTK_ACTION(eact), true ); } { @@ -331,13 +338,13 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj EgeAdjustmentAction *eact = create_adjustment_action( "SprayStandard_deviationAction", C_("Spray tool", "Scatter"), C_("Spray tool", "Scatter:"), _("Increase to scatter sprayed objects"), "/tools/spray/standard_deviation", 70, - GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-standard_deviation", + GTK_WIDGET(desktop->canvas), holder, true, "spray-standard_deviation", 1, 100, 1.0, 10.0, labels, values, G_N_ELEMENTS(labels), sp_spray_standard_deviation_value_changed, NULL /*unit tracker*/, 1, 0 ); ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + gtk_action_set_sensitive( GTK_ACTION(eact), true ); } /* Mode */ @@ -401,13 +408,13 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj _("Amount"), _("Amount:"), _("Adjusts the number of items sprayed per click"), "/tools/spray/population", 70, - GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-population", + GTK_WIDGET(desktop->canvas), holder, true, "spray-population", 1, 100, 1.0, 10.0, labels, values, G_N_ELEMENTS(labels), sp_spray_population_value_changed, NULL /*unit tracker*/, 1, 0 ); ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + gtk_action_set_sensitive( GTK_ACTION(eact), true ); g_object_set_data( holder, "spray_population", eact ); } @@ -432,13 +439,13 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj // xgettext:no-c-format _("Variation of the rotation of the sprayed objects; 0% for the same rotation than the original object"), "/tools/spray/rotation_variation", 0, - GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-rotation", + GTK_WIDGET(desktop->canvas), holder, true, "spray-rotation", 0, 100, 1.0, 10.0, labels, values, G_N_ELEMENTS(labels), sp_spray_rotation_value_changed, NULL /*unit tracker*/, 1, 0 ); ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + gtk_action_set_sensitive( GTK_ACTION(eact), true ); g_object_set_data( holder, "spray_rotation", eact ); } @@ -450,13 +457,13 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj // xgettext:no-c-format _("Variation in the scale of the sprayed objects; 0% for the same scale than the original object"), "/tools/spray/scale_variation", 0, - GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-scale", + GTK_WIDGET(desktop->canvas), holder, true, "spray-scale", 0, 100, 1.0, 10.0, labels, values, G_N_ELEMENTS(labels), sp_spray_scale_value_changed, NULL /*unit tracker*/, 1, 0 ); ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + gtk_action_set_sensitive( GTK_ACTION(eact), true ); g_object_set_data( holder, "spray_scale", eact ); } @@ -605,7 +612,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_object_set_data( holder, "offset", eact ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); } - sp_spray_erase_sensitivize(holder, prefs->getInt("/tools/spray/mode") != 3); + sp_spray_init(holder); } diff --git a/src/widgets/star-toolbar.cpp b/src/widgets/star-toolbar.cpp index 741fd38ad..982a3c854 100644 --- a/src/widgets/star-toolbar.cpp +++ b/src/widgets/star-toolbar.cpp @@ -182,7 +182,7 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d bool modmade = false; if ( prop_action ) { - gtk_action_set_sensitive( prop_action, !flat ); + gtk_action_set_visible( prop_action, !flat ); } std::vector itemlist=selection->itemList(); @@ -319,10 +319,10 @@ static void star_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *n EgeSelectOneAction* flat_action = EGE_SELECT_ONE_ACTION( g_object_get_data( G_OBJECT(tbl), "flat_action" ) ); if ( flatsides && !strcmp(flatsides,"false") ) { ege_select_one_action_set_active( flat_action, 1 ); - gtk_action_set_sensitive( prop_action, TRUE ); + gtk_action_set_visible( prop_action, TRUE ); } else { ege_select_one_action_set_active( flat_action, 0 ); - gtk_action_set_sensitive( prop_action, FALSE ); + gtk_action_set_visible( prop_action, FALSE ); } } else if ((!strcmp(name, "sodipodi:r1") || !strcmp(name, "sodipodi:r2")) && (!isFlatSided) ) { adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "proportion")); @@ -415,7 +415,7 @@ static void sp_stb_defaults( GtkWidget * /*widget*/, GObject *dataKludge ) ege_select_one_action_set_active( flat_action, flat ? 0 : 1 ); GtkAction* sb2 = GTK_ACTION( g_object_get_data( dataKludge, "prop_action" ) ); - gtk_action_set_sensitive( sb2, !flat ); + gtk_action_set_visible( sb2, !flat ); adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "magnitude" ) ); gtk_adjustment_set_value(adj, mag); @@ -521,9 +521,9 @@ void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje } if ( !isFlatSided ) { - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + gtk_action_set_visible( GTK_ACTION(eact), TRUE ); } else { - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + gtk_action_set_visible( GTK_ACTION(eact), FALSE ); } /* Roundedness */ diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index b75cdb4be..8367104d4 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -1468,7 +1468,7 @@ void setup_aux_toolbox(GtkWidget *toolbox, SPDesktop *desktop) #endif } - gtk_widget_show_all( holder ); + gtk_widget_show_now( holder ); sp_set_font_size_smaller( holder ); gtk_size_group_add_widget( grouper, holder ); @@ -1489,7 +1489,7 @@ void update_aux_toolbox(SPDesktop * /*desktop*/, ToolBase *eventcontext, GtkWidg for (int i = 0 ; aux_toolboxes[i].type_name ; i++ ) { GtkWidget *sub_toolbox = GTK_WIDGET(g_object_get_data(G_OBJECT(toolbox), aux_toolboxes[i].data_name)); if (tname && !strcmp(tname, aux_toolboxes[i].type_name)) { - gtk_widget_show_all(sub_toolbox); + gtk_widget_show_now(sub_toolbox); g_object_set_data(G_OBJECT(toolbox), "shows", sub_toolbox); } else { gtk_widget_hide(sub_toolbox); diff --git a/src/widgets/tweak-toolbar.cpp b/src/widgets/tweak-toolbar.cpp index e2c0daf6e..a185ea956 100644 --- a/src/widgets/tweak-toolbar.cpp +++ b/src/widgets/tweak-toolbar.cpp @@ -82,12 +82,12 @@ static void sp_tweak_mode_changed( EgeSelectOneAction *act, GObject *tbl ) for (size_t i = 0; i < G_N_ELEMENTS(names); ++i) { GtkAction *act = GTK_ACTION(g_object_get_data( tbl, names[i] )); if (act) { - gtk_action_set_sensitive(act, flag); + gtk_action_set_visible(act, flag); } } GtkAction *fid = GTK_ACTION(g_object_get_data( tbl, "tweak_fidelity")); if (fid) { - gtk_action_set_sensitive(fid, !flag); + gtk_action_set_visible(fid, !flag); } } @@ -276,7 +276,7 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj ege_output_action_set_use_markup( act, TRUE ); gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { - gtk_action_set_sensitive (GTK_ACTION(act), FALSE); + gtk_action_set_visible (GTK_ACTION(act), FALSE); } g_object_set_data( holder, "tweak_channels_label", act); } @@ -293,7 +293,7 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doh), desktop ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/doh", true) ); if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { - gtk_action_set_sensitive (GTK_ACTION(act), FALSE); + gtk_action_set_visible (GTK_ACTION(act), FALSE); } g_object_set_data( holder, "tweak_doh", act); } @@ -309,7 +309,7 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dos), desktop ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/dos", true) ); if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { - gtk_action_set_sensitive (GTK_ACTION(act), FALSE); + gtk_action_set_visible (GTK_ACTION(act), FALSE); } g_object_set_data( holder, "tweak_dos", act ); } @@ -325,7 +325,7 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dol), desktop ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/dol", true) ); if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { - gtk_action_set_sensitive (GTK_ACTION(act), FALSE); + gtk_action_set_visible (GTK_ACTION(act), FALSE); } g_object_set_data( holder, "tweak_dol", act ); } @@ -341,7 +341,7 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doo), desktop ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/doo", true) ); if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { - gtk_action_set_sensitive (GTK_ACTION(act), FALSE); + gtk_action_set_visible (GTK_ACTION(act), FALSE); } g_object_set_data( holder, "tweak_doo", act ); } @@ -358,9 +358,9 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj labels, values, G_N_ELEMENTS(labels), sp_tweak_fidelity_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + gtk_action_set_visible( GTK_ACTION(eact), TRUE ); if (mode == Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT || mode == Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { - gtk_action_set_sensitive (GTK_ACTION(eact), FALSE); + gtk_action_set_visible (GTK_ACTION(eact), FALSE); } g_object_set_data( holder, "tweak_fidelity", eact ); } -- cgit v1.2.3 From 6320a06b45bf73834150d2d335815d9fe732b904 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 28 Jan 2016 18:28:19 +0100 Subject: Fix a bug in eraser spray mode when no overlaps is disabled (bzr r14622) --- src/ui/tools/spray-tool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 71cad5c0d..9adaf3879 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -936,7 +936,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(mode == SPRAY_MODE_ERASER || no_overlap || picker || !over_transparent || !over_no_transparent){ if(!fit_item(desktop , item , a @@ -1072,7 +1072,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, 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(mode == SPRAY_MODE_ERASER || no_overlap || picker || !over_transparent || !over_no_transparent){ if(!fit_item(desktop , item , a -- cgit v1.2.3 From 61eff0365783b13f583255231684f76c653ce3d9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 29 Jan 2016 11:12:58 +0100 Subject: Add an advert to fillet chamfer users that the coming version in 'pointwise' branch is not compatible. I hope soon I can commit the code (bzr r14623) --- src/live_effects/lpe-fillet-chamfer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 209805da3..afa405b59 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -99,6 +99,14 @@ Gtk::Widget *LPEFilletChamfer::newWidget() vbox->set_border_width(5); vbox->set_homogeneous(false); vbox->set_spacing(2); + Gtk::HBox *advertaising = Gtk::manage(new Gtk::HBox(true, 0)); + Gtk::Button *advert = Gtk::manage(new Gtk::Button(Glib::ustring(_("IMPORTANT! New version soon...")))); + advertaising->pack_start(*advert, true, true, 2); + vbox->pack_start(*advertaising, true, true, 2); + Gtk::HBox *advertaising2 = Gtk::manage(new Gtk::HBox(true, 0)); + Gtk::Button *advert2 = Gtk::manage(new Gtk::Button(Glib::ustring(_("Not compatible. Convert works to paths.")))); + advertaising2->pack_start(*advert2, true, true, 2); + vbox->pack_start(*advertaising2, true, true, 2); std::vector::iterator it = param_vector.begin(); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { -- cgit v1.2.3 From 8d4150d5bdeace7250e9c41a6bc8a944c5df1726 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 29 Jan 2016 12:07:48 +0100 Subject: Fixed a bug related to windows position on dynamic toolbat commit (bzr r14624) --- src/widgets/toolbox.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 8367104d4..edee612e5 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -1467,8 +1467,11 @@ void setup_aux_toolbox(GtkWidget *toolbox, SPDesktop *desktop) gtk_table_attach( GTK_TABLE(holder), swatch_, 1, 2, 0, 1, (GtkAttachOptions)(GTK_SHRINK | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), AUX_BETWEEN_BUTTON_GROUPS, AUX_SPACING ); #endif } - - gtk_widget_show_now( holder ); + if(i==0){ + gtk_widget_show_all( holder ); + } else { + gtk_widget_show_now( holder ); + } sp_set_font_size_smaller( holder ); gtk_size_group_add_widget( grouper, holder ); -- cgit v1.2.3 From 895095e1a30ae78ec98d7a0e60af953c56abe02b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 29 Jan 2016 17:56:53 +0100 Subject: Improve advertaising to Fillet-Chamfer (bzr r14625) --- src/live_effects/lpe-fillet-chamfer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index afa405b59..07760b172 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -104,7 +104,7 @@ Gtk::Widget *LPEFilletChamfer::newWidget() advertaising->pack_start(*advert, true, true, 2); vbox->pack_start(*advertaising, true, true, 2); Gtk::HBox *advertaising2 = Gtk::manage(new Gtk::HBox(true, 0)); - Gtk::Button *advert2 = Gtk::manage(new Gtk::Button(Glib::ustring(_("Not compatible. Convert works to paths.")))); + Gtk::Button *advert2 = Gtk::manage(new Gtk::Button(Glib::ustring(_("Not compatible. Convert to path after.")))); advertaising2->pack_start(*advert2, true, true, 2); vbox->pack_start(*advertaising2, true, true, 2); std::vector::iterator it = param_vector.begin(); -- cgit v1.2.3 From 7a8702cfed2c7d18434ccfd639976061c3ae33be Mon Sep 17 00:00:00 2001 From: suv-lp <> Date: Sat, 30 Jan 2016 09:31:50 +0100 Subject: Fix for bug 1539704 (Crash when selecting the eraser tool). Fixed bugs: - https://launchpad.net/bugs/1539704 (bzr r14626) --- src/ui/tools-switch.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/ui/tools-switch.cpp b/src/ui/tools-switch.cpp index 11313f550..ea0431b0a 100644 --- a/src/ui/tools-switch.cpp +++ b/src/ui/tools-switch.cpp @@ -42,7 +42,11 @@ #include "ui/tools/connector-tool.h" #include "ui/tools/dropper-tool.h" #include "ui/tools/eraser-tool.h" + +#if HAVE_POTRACE #include "ui/tools/flood-tool.h" +#endif + #include "ui/tools/gradient-tool.h" #include "ui/tools/lpe-tool.h" #include "ui/tools/measure-tool.h" @@ -83,7 +87,9 @@ static char const *const tool_names[] = { "/tools/measure", "/tools/dropper", "/tools/connector", +#if HAVE_POTRACE "/tools/paintbucket", +#endif "/tools/eraser", "/tools/lpetool", NULL @@ -111,7 +117,9 @@ static char const *const tool_msg[] = { N_("Drag to measure the dimensions of objects."), N_("Click to set fill, Shift+click to set stroke; drag to average color in area; with Alt to pick inverse color; Ctrl+C to copy the color under mouse to clipboard"), N_("Click and drag between shapes to create a connector."), +#if HAVE_POTRACE N_("Click to paint a bounded area, Shift+click to union the new fill with the current selection, Ctrl+click to change the clicked object's fill and stroke to the current setting."), +#endif N_("Drag to erase."), N_("Choose a subtool from the toolbar"), }; -- cgit v1.2.3 From ea9f9278b956a270bcef15516b87831f1c6ca8fa Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 30 Jan 2016 12:27:30 +0100 Subject: Remove two warnings on compile (bzr r14627) --- src/ui/tools/measure-tool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 4d17a7ed5..7ca09b4d1 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -1218,9 +1218,9 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N if(to_guides) { gchar *cross_number; if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true)) { - cross_number= g_strdup_printf(_("Crossing %d"), idx); + cross_number= g_strdup_printf(_("Crossing %lu"), idx); } else { - cross_number= g_strdup_printf(_("Crossing %d"), idx + 1); + cross_number= g_strdup_printf(_("Crossing %lu"), idx + 1); } if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true) && idx == 0) { setGuide(desktop->doc2dt(intersections[idx]), angle + Geom::deg_to_rad(90), ""); -- cgit v1.2.3 From 2aa15e993a5babe61f7af4358ddae43afc3dc6b6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 1 Feb 2016 19:04:28 +0100 Subject: Dinamic toolbar enlacements, now in clone mode on spray tool and in pencil toolbar (bzr r14628) --- src/ui/tools/measure-tool.cpp | 4 ++-- src/widgets/pencil-toolbar.cpp | 7 ++++++- src/widgets/spray-toolbar.cpp | 9 ++++++--- 3 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 7ca09b4d1..07313874f 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -1218,9 +1218,9 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N if(to_guides) { gchar *cross_number; if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true)) { - cross_number= g_strdup_printf(_("Crossing %lu"), idx); + cross_number= g_strdup_printf(_("Crossing %u"), idx); } else { - cross_number= g_strdup_printf(_("Crossing %lu"), idx + 1); + cross_number= g_strdup_printf(_("Crossing %u"), idx + 1); } if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true) && idx == 0) { setGuide(desktop->doc2dt(intersections[idx]), angle + Geom::deg_to_rad(90), ""); diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index 94875ecc1..55127206c 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -164,6 +164,7 @@ static void freehand_simplify_lpe(InkToggleAction* itact, GObject *dataKludge) { gint simplify = gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(itact) ); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setInt(freehand_tool_name(dataKludge) + "/simplify", simplify); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "flatten_simplify") ), simplify ); } /** @@ -363,7 +364,7 @@ private: void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { sp_add_freehand_mode_toggle(mainActions, holder, true); - + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); EgeAdjustmentAction* eact = 0; /* Tolerance */ @@ -420,6 +421,10 @@ void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb Inkscape::ICON_SIZE_SMALL_TOOLBAR ); g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_simplify_flatten), holder ); gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + g_object_set_data( holder, "flatten_simplify", inky ); + if (!prefs->getInt("/tools/freehand/pencil/simplify", 0)) { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "flatten_simplify") ), false ); + } } g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 4ff469257..95b4df9a2 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -102,7 +102,7 @@ static void sp_spray_init( GObject *tbl){ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int mode = prefs->getInt("/tools/spray/mode", 0); bool show = true; - if(mode == 3){ + if(mode == 3 || mode == 2){ show = false; } gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "no_overlap") ), show ); @@ -115,11 +115,14 @@ static void sp_spray_init( GObject *tbl){ gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_center") ), show ); gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "picker") ), show ); gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "offset") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "spray_rotation") ), show ); gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_fill") ), show ); gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ), show ); gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ), show ); gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_center") ), show ); + if(mode == 2){ + show = true; + } + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "spray_rotation") ), show ); sp_stb_update_widgets( tbl ); } @@ -362,7 +365,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, 0, _("Spray with clones"), - 1, _("Spray clones of the initial selection"), + 1, _("Spray clones of the initial selection. Unset paint on fill or strokes to apply color picker changes"), 2, INKSCAPE_ICON("spray-mode-clone"), -1 ); -- cgit v1.2.3 From 259a21b46217fdb03e9d4759bd617200d09dd6b7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 1 Feb 2016 19:21:02 +0100 Subject: Remove duplicate mensage (bzr r14629) --- src/widgets/spray-toolbar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 95b4df9a2..9e142a8db 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -365,7 +365,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, 0, _("Spray with clones"), - 1, _("Spray clones of the initial selection. Unset paint on fill or strokes to apply color picker changes"), + 1, _("Spray clones of the initial selection"), 2, INKSCAPE_ICON("spray-mode-clone"), -1 ); -- cgit v1.2.3 From 91b80a234e552c57ad6029f54ee4014a7f79048d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 6 Feb 2016 01:45:54 +0100 Subject: Fix for meassure bug #1541963 Fixed bugs: - https://launchpad.net/bugs/1541963 (bzr r14632) --- src/ui/tools/measure-tool.cpp | 6 ++---- src/ui/tools/measure-tool.h | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 07313874f..e36cc294a 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -71,8 +71,6 @@ namespace Inkscape { namespace UI { namespace Tools { -std::vector measure_tmp_items; - const std::string& MeasureTool::getPrefsPath() { return MeasureTool::prefsPath; @@ -272,7 +270,7 @@ void setMeasureItem(Geom::PathVector pathv, bool is_curve, bool markers, guint32 * @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 ¢er, Geom::Point const &end, Geom::Point const &anchor, double angle, Inkscape::XML::Node *measure_repr = NULL) +void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom::Point const &end, Geom::Point const &anchor, double angle, std::vector &measure_tmp_items, 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. @@ -1244,7 +1242,7 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N * 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); + createAngleDisplayCurve(desktop, start_p, end_p, angleDisplayPt, angle, measure_tmp_items, measure_repr); } if (intersections.size() > 2) { diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index 3bdc9b9c4..fbabb304d 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -16,6 +16,7 @@ #include "ui/tools/tool-base.h" #include <2geom/point.h> #include "display/canvas-text.h" +#include "display/canvas-temporary-item.h" #include "ui/control-manager.h" #include @@ -68,6 +69,7 @@ private: gint dimension_offset; Geom::Point start_p; Geom::Point end_p; + std::vector measure_tmp_items; sigc::connection _knot_start_moved_connection; sigc::connection _knot_start_ungrabbed_connection; sigc::connection _knot_end_moved_connection; -- cgit v1.2.3 From f9eb607affbe54a128d09643e885bae2525ac36c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 6 Feb 2016 18:14:52 +0100 Subject: Remove duplicated variable on meassure (bzr r14633) --- src/ui/tools/measure-tool.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index e36cc294a..dae7a244d 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -592,7 +592,6 @@ bool MeasureTool::root_handler(GdkEvent* event) // 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)); end_p = motion_dt; -- cgit v1.2.3 From 8117b4c9cdc45fd1c277819e804511c1bbc68226 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 6 Feb 2016 21:43:47 +0100 Subject: Added phantom meassure feature to meassure tool (bzr r14634) --- src/ui/tools/measure-tool.cpp | 106 ++++++++++++++++++++++++++++++---------- src/ui/tools/measure-tool.h | 10 ++-- src/widgets/measure-toolbar.cpp | 18 +++++++ src/widgets/toolbox.cpp | 1 + 4 files changed, 104 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index dae7a244d..bc0ab6d46 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -18,6 +18,7 @@ #include "display/curve.h" #include "display/sodipodi-ctrl.h" #include "display/sp-ctrlline.h" +#include "display/sp-ctrlcurve.h" #include "display/sp-canvas.h" #include "display/sp-canvas-item.h" #include "display/sp-canvas-util.h" @@ -270,7 +271,7 @@ void setMeasureItem(Geom::PathVector pathv, bool is_curve, bool markers, guint32 * @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 ¢er, Geom::Point const &end, Geom::Point const &anchor, double angle, std::vector &measure_tmp_items, Inkscape::XML::Node *measure_repr = NULL) +void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom::Point const &end, Geom::Point const &anchor, double angle, bool to_phantom, std::vector &measure_phantom_items , std::vector &measure_tmp_items , 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. @@ -306,8 +307,12 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom Geom::Point p3(xc + bx + (k2 * by), yc + by - (k2 * bx)); 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(to_phantom){ + curve->rgba = 0x8888887f; + measure_phantom_items.push_back(desktop->add_temporary_canvasitem(SP_CANVAS_ITEM(curve), 0, true)); + } else { + measure_tmp_items.push_back(desktop->add_temporary_canvasitem(SP_CANVAS_ITEM(curve), 0, true)); + } if(measure_repr) { Geom::PathVector pathv; Geom::Path path; @@ -380,6 +385,10 @@ MeasureTool::~MeasureTool() desktop->remove_temporary_canvasitem(measure_tmp_items[idx]); } measure_tmp_items.clear(); + for (size_t idx = 0; idx < measure_phantom_items.size(); ++idx) { + desktop->remove_temporary_canvasitem(measure_phantom_items[idx]); + } + measure_phantom_items.clear(); } Geom::Point MeasureTool::readMeasurePoint(bool is_start) { @@ -730,6 +739,26 @@ void MeasureTool::toGuides() DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add guides from measure tool")); } +void MeasureTool::toPhantom() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if(!desktop || !start_p.isFinite() || !end_p.isFinite() || start_p == end_p) { + return; + } + SPDocument *doc = desktop->getDocument(); + for (size_t idx = 0; idx < measure_phantom_items.size(); ++idx) { + desktop->remove_temporary_canvasitem(measure_phantom_items[idx]); + } + measure_phantom_items.clear(); + for (size_t idx = 0; idx < measure_tmp_items.size(); ++idx) { + desktop->remove_temporary_canvasitem(measure_tmp_items[idx]); + } + measure_tmp_items.clear(); + showCanvasItems(false, false, true); + doc->ensureUpToDate(); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add Stored to measure tool")); +} + void MeasureTool::toItem() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; @@ -741,7 +770,7 @@ void MeasureTool::toItem() 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); + showCanvasItems(false, true, false, rgroup); setLine(start_p,end_p, false, line_color_primary, rgroup); SPItem *measure_item = SP_ITEM(desktop->currentLayer()->appendChildRepr(rgroup)); Inkscape::GC::release(rgroup); @@ -984,7 +1013,7 @@ void MeasureTool::reset() measure_tmp_items.clear(); } -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) +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, bool to_phantom, Inkscape::XML::Node *measure_repr) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; std::stringstream precision_str; @@ -1005,40 +1034,62 @@ void MeasureTool::setMeasureCanvasText(bool is_angle, double precision, double a 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_phantom){ + canvas_tooltip->rgba_background = 0x4444447f; + measure_phantom_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0, false)); + } else { + measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0, false)); + } if(to_item) { setLabelText(measure_str, position, fontsize, 0, background, measure_repr); } g_free(measure_str); } -void MeasureTool::setMeasureCanvasItem(Geom::Point position, bool to_item, Inkscape::XML::Node *measure_repr){ +void MeasureTool::setMeasureCanvasItem(Geom::Point position, bool to_item, bool to_phantom, Inkscape::XML::Node *measure_repr){ SPDesktop *desktop = SP_ACTIVE_DESKTOP; + guint32 color = 0xff0000ff; + if(to_phantom){ + color = 0x888888ff; + } SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 8.0, "stroked", TRUE, - "stroke_color", 0xff0000ff, + "stroke_color", color, "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_phantom){ + measure_phantom_items.push_back(desktop->add_temporary_canvasitem(canvasitem, 0)); + } else { + measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvasitem, 0)); + } + if(to_item) { setPoint(position, measure_repr); } } -void MeasureTool::setMeasureCanvasControlLine(Geom::Point start, Geom::Point end, bool to_item, Inkscape::CtrlLineType ctrl_line_type, Inkscape::XML::Node *measure_repr){ +void MeasureTool::setMeasureCanvasControlLine(Geom::Point start, Geom::Point end, bool to_item, bool to_phantom, Inkscape::CtrlLineType ctrl_line_type, Inkscape::XML::Node *measure_repr){ SPDesktop *desktop = SP_ACTIVE_DESKTOP; + gint32 color = ctrl_line_type == CTLINE_PRIMARY ? 0x0000ff7f : 0xff00007f; + if(to_phantom){ + color = ctrl_line_type == CTLINE_PRIMARY ? 0x4444447f : 0x8888887f; + } 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; + control_line->rgba = color; + if(to_phantom){ + measure_phantom_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); + } else { + measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); + } if(to_item) { setLine(start, end, @@ -1048,7 +1099,7 @@ void MeasureTool::setMeasureCanvasControlLine(Geom::Point start, Geom::Point end } } -void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::Node *measure_repr) +void MeasureTool::showCanvasItems(bool to_guides, bool to_item, bool to_phantom, Inkscape::XML::Node *measure_repr) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if(!desktop || !start_p.isFinite() || !end_p.isFinite() || start_p == end_p) { @@ -1181,37 +1232,38 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N repositionOverlappingLabels(placements, desktop, windowNormal, fontsize, precision); for (std::vector::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); + + setMeasureCanvasText(false, precision, place.lengthVal * scale, fontsize, unit_name, place.end, 0x0000007f, TEXT_ANCHOR_CENTER, to_item, to_phantom, 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); + setMeasureCanvasText(true, precision, Geom::rad_to_deg(angle), fontsize, unit_name, angleDisplayPt, 0x337f337f, TEXT_ANCHOR_CENTER, to_item, to_phantom, measure_repr); } { 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); + setMeasureCanvasText(false, precision, totallengthval * scale, fontsize, unit_name, origin, 0x3333337f, TEXT_ANCHOR_LEFT, to_item, to_phantom, measure_repr); } 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); + setMeasureCanvasText(false, precision, totallengthval * scale, fontsize, unit_name, origin, 0x33337f7f, TEXT_ANCHOR_CENTER, to_item, to_phantom, measure_repr); } // Initial point { - setMeasureCanvasItem(start_p, false, measure_repr); + setMeasureCanvasItem(start_p, false, to_phantom, 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) { - setMeasureCanvasItem(desktop->doc2dt(intersections[idx]), to_item, measure_repr); + setMeasureCanvasItem(desktop->doc2dt(intersections[idx]), to_item, to_phantom, measure_repr); if(to_guides) { gchar *cross_number; if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true)) { @@ -1231,7 +1283,7 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N // draw main control line { - setMeasureCanvasControlLine(start_p, end_p, false, CTLINE_PRIMARY, measure_repr); + setMeasureCanvasControlLine(start_p, end_p, false, to_phantom, CTLINE_PRIMARY, measure_repr); double length = std::abs((end_p - start_p).length()); Geom::Point anchorEnd = start_p; anchorEnd[Geom::X] += length; @@ -1240,28 +1292,28 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, Inkscape::XML::N * 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_tmp_items, measure_repr); + setMeasureCanvasControlLine(start_p, anchorEnd, to_item, to_phantom, CTLINE_SECONDARY, measure_repr); + createAngleDisplayCurve(desktop, start_p, end_p, angleDisplayPt, angle, to_phantom, measure_phantom_items, measure_tmp_items, measure_repr); } 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]) + normal * dimension_offset, desktop->doc2dt(intersections[intersections.size() - 1]) + normal * dimension_offset, to_item, to_phantom, CTLINE_PRIMARY , measure_repr); - setMeasureCanvasControlLine(desktop->doc2dt(intersections[0]), desktop->doc2dt(intersections[0]) + normal * dimension_offset, to_item, CTLINE_PRIMARY , measure_repr); + setMeasureCanvasControlLine(desktop->doc2dt(intersections[0]), desktop->doc2dt(intersections[0]) + normal * dimension_offset, to_item, to_phantom, CTLINE_PRIMARY , measure_repr); - setMeasureCanvasControlLine(desktop->doc2dt(intersections[intersections.size() - 1]), desktop->doc2dt(intersections[intersections.size() - 1]) + normal * dimension_offset, to_item, CTLINE_PRIMARY , measure_repr); + setMeasureCanvasControlLine(desktop->doc2dt(intersections[intersections.size() - 1]), desktop->doc2dt(intersections[intersections.size() - 1]) + normal * dimension_offset, to_item, to_phantom, CTLINE_PRIMARY , measure_repr); } // call-out lines for (std::vector::iterator it = placements.begin(); it != placements.end(); ++it) { LabelPlacement &place = *it; - setMeasureCanvasControlLine(place.start, place.end, to_item, CTLINE_SECONDARY, measure_repr); + setMeasureCanvasControlLine(place.start, place.end, to_item, to_phantom, CTLINE_SECONDARY, measure_repr); } { 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); + setMeasureCanvasControlLine(desktop->doc2dt(measure_text_pos), desktop->doc2dt(measure_text_pos) - (normal * dimension_offset / 2), to_item, to_phantom, CTLINE_SECONDARY, measure_repr); } } } diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index fbabb304d..b5e9f8a1b 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -38,9 +38,10 @@ public: 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 showCanvasItems(bool to_guides = false, bool to_item = false, bool to_phantom = false, Inkscape::XML::Node *measure_repr = NULL); virtual void reverseKnots(); virtual void toGuides(); + virtual void toPhantom(); virtual void toMarkDimension(); virtual void toItem(); virtual void reset(); @@ -52,9 +53,9 @@ public: 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 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, bool to_phantom, Inkscape::XML::Node *measure_repr); + void setMeasureCanvasItem(Geom::Point position, bool to_item, bool to_phantom, Inkscape::XML::Node *measure_repr); + void setMeasureCanvasControlLine(Geom::Point start, Geom::Point end, bool to_item, bool to_phantom, 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); @@ -70,6 +71,7 @@ private: Geom::Point start_p; Geom::Point end_p; std::vector measure_tmp_items; + std::vector measure_phantom_items; sigc::connection _knot_start_moved_connection; sigc::connection _knot_start_ungrabbed_connection; sigc::connection _knot_end_moved_connection; diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index f48dcd4e0..9bab3ad4a 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -241,6 +241,14 @@ sp_to_guides(void){ } } +static void +sp_to_phantom(void){ + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->toPhantom(); + } +} + static void sp_to_item(void){ MeasureTool *mt = get_measure_tool(); @@ -381,6 +389,16 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_reverse_knots), 0 ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } + /* phantom measure */ + { + InkAction* act = ink_action_new( "MeasureToPhantom", + _("Phantom measure"), + _("Phantom measure"), + INKSCAPE_ICON("selection-make-bitmap-copy"), + secondarySize ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_phantom), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } /* to guides */ { InkAction* act = ink_action_new( "MeasureToGuides", diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index edee612e5..88dc7a190 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -375,6 +375,7 @@ static gchar const * ui_descr = " " " " " " + " " " " " " " " -- cgit v1.2.3 From 7c5342d04a8c59714becfdf0ceb8ea1de4686736 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 7 Feb 2016 01:12:34 +0100 Subject: Fix for bug 1540518. Improved performance based on previous meassure code comment Fixed bugs: - https://launchpad.net/bugs/1540518 (bzr r14635) --- src/document.cpp | 14 +++--- src/document.h | 4 +- src/ui/tools/measure-tool.cpp | 105 +++++++++++++++++++----------------------- 3 files changed, 56 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 70fb56fe8..d4bd29386 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1262,14 +1262,14 @@ static bool overlaps(Geom::Rect const &area, Geom::Rect const &box) } static std::vector &find_items_in_area(std::vector &s, SPGroup *group, unsigned int dkey, Geom::Rect const &area, - bool (*test)(Geom::Rect const &, Geom::Rect const &), bool take_insensitive = false) + bool (*test)(Geom::Rect const &, Geom::Rect const &), bool take_insensitive = false, bool into_groups = false) { g_return_val_if_fail(SP_IS_GROUP(group), s); for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) { if ( SP_IS_ITEM(o) ) { - if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER ) { - s = find_items_in_area(s, SP_GROUP(o), dkey, area, test); + if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { + s = find_items_in_area(s, SP_GROUP(o), dkey, area, test, take_insensitive, into_groups); } else { SPItem *child = SP_ITEM(o); Geom::OptRect box = child->desktopVisualBounds(); @@ -1430,11 +1430,11 @@ static SPItem *find_group_at_point(unsigned int dkey, SPGroup *group, Geom::Poin * Assumes box is normalized (and g_asserts it!) * */ -std::vector SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect const &box) const +std::vector SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool into_groups) const { std::vector x; g_return_val_if_fail(this->priv != NULL, x); - return find_items_in_area(x, SP_GROUP(this->root), dkey, box, is_within); + return find_items_in_area(x, SP_GROUP(this->root), dkey, box, is_within, false, into_groups); } /* @@ -1444,11 +1444,11 @@ std::vector SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect con * */ -std::vector SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box) const +std::vector SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool into_groups) const { std::vector x; g_return_val_if_fail(this->priv != NULL, x); - return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps); + return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps, false, into_groups); } std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vector points, bool all_layers, size_t limit) const diff --git a/src/document.h b/src/document.h index cf8ebc3cb..b4a8a8e8e 100644 --- a/src/document.h +++ b/src/document.h @@ -260,8 +260,8 @@ public: bool addResource(char const *key, SPObject *object); bool removeResource(char const *key, SPObject *object); const std::set getResourceList(char const *key) const; - std::vector getItemsInBox(unsigned int dkey, Geom::Rect const &box) const; - std::vector getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box) const; + std::vector getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool into_groups = false) const; + std::vector getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool into_groups = false) const; SPItem *getItemAtPoint(unsigned int key, Geom::Point const &p, bool into_groups, SPItem *upto = NULL) const; std::vector getItemsAtPoints(unsigned const key, std::vector points, bool all_layers = true, size_t limit = 0) const; SPItem *getGroupAtPoint(unsigned int key, Geom::Point const &p) const; diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index bc0ab6d46..c40d2581e 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -1131,63 +1131,50 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, bool to_phantom, } std::vector 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 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(); + SPDocument *doc = desktop->getDocument(); + Geom::Rect rect(start_p, end_p); + items = doc->getItemsPartiallyInBox(desktop->dkey, rect, true); + Inkscape::LayerModel *layer_model = NULL; + SPObject *current_layer = NULL; + if(desktop){ + layer_model = desktop->layers; + current_layer = desktop->currentLayer(); } std::vector intersection_times; for (std::vector::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); + if(all_layers || (layer_model && layer_model->layerForObject(item) == current_layer)){ + 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); + } } } } @@ -1204,13 +1191,15 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, bool to_phantom, std::vector intersections; std::sort(intersection_times.begin(), intersection_times.end()); for (std::vector::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)); - } + 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])); + Geom::Point start = lineseg[0].pointAt(intersection_times[0]); + Geom::Point end = lineseg[0].pointAt(intersection_times[intersection_times.size()-1]); + intersections.clear(); + intersections.push_back(start); + intersections.push_back(end); } if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true)) { intersections.insert(intersections.begin(),lineseg[0].pointAt(0)); -- cgit v1.2.3 From 6dd9c76e7f80d1ff7bad7be293272802bb7c1ac7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 7 Feb 2016 16:49:01 +0100 Subject: Add knot position dialog to meassure with Shift+Click (bzr r14636) --- src/ui/CMakeLists.txt | 2 + src/ui/dialog/Makefile_insert | 4 +- src/ui/dialog/knot-properties.cpp | 213 ++++++++++++++++++++++++++++++++++++++ src/ui/dialog/knot-properties.h | 97 +++++++++++++++++ src/ui/tools/measure-tool.cpp | 24 ++++- src/ui/tools/measure-tool.h | 9 +- 6 files changed, 343 insertions(+), 6 deletions(-) create mode 100644 src/ui/dialog/knot-properties.cpp create mode 100644 src/ui/dialog/knot-properties.h (limited to 'src') diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 46b0af6bb..587974b90 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -80,6 +80,7 @@ set(ui_SRC dialog/icon-preview.cpp dialog/inkscape-preferences.cpp dialog/input.cpp + dialog/knot-properties.cpp dialog/layer-properties.cpp dialog/layers.cpp dialog/livepatheffect-add.cpp @@ -219,6 +220,7 @@ set(ui_SRC dialog/icon-preview.h dialog/inkscape-preferences.h dialog/input.h + dialog/knot-properties.h dialog/layer-properties.h dialog/layers.h dialog/livepatheffect-add.h diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index 793988a7d..1e719bbda 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -61,9 +61,11 @@ ink_common_sources += \ ui/dialog/inkscape-preferences.h \ ui/dialog/input.cpp \ ui/dialog/input.h \ + ui/dialog/knot-properties.cpp \ + ui/dialog/knot-properties.h \ ui/dialog/layer-properties.cpp \ ui/dialog/layer-properties.h \ - ui/dialog/layers.cpp \ + ui/dialog/layers.cpp \ ui/dialog/layers.h \ ui/dialog/livepatheffect-add.cpp \ ui/dialog/livepatheffect-add.h \ diff --git a/src/ui/dialog/knot-properties.cpp b/src/ui/dialog/knot-properties.cpp new file mode 100644 index 000000000..9c23c33e1 --- /dev/null +++ b/src/ui/dialog/knot-properties.cpp @@ -0,0 +1,213 @@ +/** + * @file + * Dialog for renaming layers. + */ +/* Author: + * Bryce W. Harrington + * Andrius R. + * Abhishek Sharma + * + * Copyright (C) 2004 Bryce Harrington + * Copyright (C) 2006 Andrius R. + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "ui/dialog/knot-properties.h" +#include +#include +#include +#include +#include "inkscape.h" +#include "util/units.h" +#include "desktop.h" +#include "document.h" +#include "document-undo.h" +#include "layer-manager.h" +#include "message-stack.h" + +#include "sp-object.h" +#include "sp-item.h" +#include "verbs.h" +#include "selection.h" +#include "selection-chemistry.h" +#include "ui/icon-names.h" +#include "ui/widget/imagetoggler.h" + +//#include "event-context.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +KnotPropertiesDialog::KnotPropertiesDialog() +: _desktop(NULL), _knotpoint(NULL), _position_visible(false) +{ + Gtk::Box *mainVBox = get_vbox(); + + _layout_table.set_spacings(4); + _layout_table.resize (2, 2); + _unit_name = ""; + // Layer name widgets + _knot_x_entry.set_activates_default(true); + _knot_x_entry.set_digits(4); + _knot_x_entry.set_increments(1,1); + _knot_x_entry.set_range(-G_MAXDOUBLE, G_MAXDOUBLE); + _knot_x_label.set_label(_("Position X:")); + _knot_x_label.set_alignment(1.0, 0.5); + + _knot_y_entry.set_activates_default(true); + _knot_y_entry.set_digits(4); + _knot_y_entry.set_increments(1,1); + _knot_y_entry.set_range(-G_MAXDOUBLE, G_MAXDOUBLE); + _knot_y_label.set_label(_("Position Y:")); + _knot_y_label.set_alignment(1.0, 0.5); + + _layout_table.attach(_knot_x_label, + 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); + _layout_table.attach(_knot_x_entry, + 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + + _layout_table.attach(_knot_y_label, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL); + _layout_table.attach(_knot_y_entry, 1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + + mainVBox->pack_start(_layout_table, true, true, 4); + + // Buttons + _close_button.set_use_stock(true); + _close_button.set_label(Gtk::Stock::CANCEL.id); + _close_button.set_can_default(); + + _apply_button.set_use_underline(true); + _apply_button.set_can_default(); + + _close_button.signal_clicked() + .connect(sigc::mem_fun(*this, &KnotPropertiesDialog::_close)); + _apply_button.signal_clicked() + .connect(sigc::mem_fun(*this, &KnotPropertiesDialog::_apply)); + + signal_delete_event().connect( + sigc::bind_return( + sigc::hide(sigc::mem_fun(*this, &KnotPropertiesDialog::_close)), + true + ) + ); + add_action_widget(_close_button, Gtk::RESPONSE_CLOSE); + add_action_widget(_apply_button, Gtk::RESPONSE_APPLY); + + _apply_button.grab_default(); + + show_all_children(); + + set_focus(_knot_y_entry); +} + +KnotPropertiesDialog::~KnotPropertiesDialog() { + + _setDesktop(NULL); +} + +void KnotPropertiesDialog::showDialog(SPDesktop *desktop, const SPKnot *pt, Glib::ustring const unit_name) +{ + KnotPropertiesDialog *dialog = new KnotPropertiesDialog(); + dialog->_setDesktop(desktop); + dialog->_setKnotPoint(pt->position(), unit_name); + dialog->_setPt(pt); + + dialog->set_title(_("Modify Knot Position")); + dialog->_apply_button.set_label(_("_Move")); + + dialog->set_modal(true); + desktop->setWindowTransient (dialog->gobj()); + dialog->property_destroy_with_parent() = true; + + dialog->show(); + dialog->present(); +} + +void +KnotPropertiesDialog::_apply() +{ + double d_x = Inkscape::Util::Quantity::convert(_knot_x_entry.get_value(), _unit_name, "px"); + double d_y = Inkscape::Util::Quantity::convert(_knot_y_entry.get_value(), _unit_name, "px"); + _knotpoint->moveto(Geom::Point(d_x, d_y)); + _knotpoint->moved_signal.emit(_knotpoint, _knotpoint->position(), 0); + _close(); +} + +void +KnotPropertiesDialog::_close() +{ + _setDesktop(NULL); + destroy_(); + Glib::signal_idle().connect( + sigc::bind_return( + sigc::bind(sigc::ptr_fun(&::operator delete), this), + false + ) + ); +} + +bool KnotPropertiesDialog::_handleKeyEvent(GdkEventKey * /*event*/) +{ + + /*switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: { + _apply(); + return true; + } + break; + }*/ + return false; +} + +void KnotPropertiesDialog::_handleButtonEvent(GdkEventButton* event) +{ + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + _apply(); + } +} + +void KnotPropertiesDialog::_setKnotPoint(Geom::Point knotpoint, Glib::ustring const unit_name) +{ + _unit_name = unit_name; + _knot_x_entry.set_value( Inkscape::Util::Quantity::convert(knotpoint.x(), "px", _unit_name)); + _knot_y_entry.set_value( Inkscape::Util::Quantity::convert(knotpoint.y(), "px", _unit_name)); + _knot_x_label.set_label(g_strdup_printf(_("Position X (%s):"), _unit_name.c_str())); + _knot_y_label.set_label(g_strdup_printf(_("Position Y (%s):"), _unit_name.c_str())); +} + +void KnotPropertiesDialog::_setPt(const SPKnot *pt) +{ + _knotpoint = const_cast(pt); +} + +void KnotPropertiesDialog::_setDesktop(SPDesktop *desktop) { + if (desktop) { + Inkscape::GC::anchor (desktop); + } + if (_desktop) { + Inkscape::GC::release (_desktop); + } + _desktop = desktop; +} + +} // namespace +} // namespace +} // namespace + + +/* + 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/dialog/knot-properties.h b/src/ui/dialog/knot-properties.h new file mode 100644 index 000000000..fd87df03d --- /dev/null +++ b/src/ui/dialog/knot-properties.h @@ -0,0 +1,97 @@ +/** @file + * @brief + */ +/* Author: + * Bryce W. Harrington + * + * Copyright (C) 2004 Bryce Harrington + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_DIALOG_KNOT_PROPERTIES_H +#define INKSCAPE_DIALOG_KNOT_PROPERTIES_H + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include <2geom/point.h> +#include "knot.h" +#include "ui/tools/measure-tool.h" + +class SPDesktop; + +namespace Inkscape { +namespace UI { +namespace Dialogs { + + +class KnotPropertiesDialog : public Gtk::Dialog { + public: + KnotPropertiesDialog(); + virtual ~KnotPropertiesDialog(); + + Glib::ustring getName() const { return "LayerPropertiesDialog"; } + + static void showDialog(SPDesktop *desktop, const SPKnot *pt, Glib::ustring const unit_name); + +protected: + + SPDesktop *_desktop; + SPKnot *_knotpoint; + + Gtk::Label _knot_x_label; + Gtk::SpinButton _knot_x_entry; + Gtk::Label _knot_y_label; + Gtk::SpinButton _knot_y_entry; + Gtk::Table _layout_table; + bool _position_visible; + + Gtk::Button _close_button; + Gtk::Button _apply_button; + Glib::ustring _unit_name; + + sigc::connection _destroy_connection; + + static KnotPropertiesDialog &_instance() { + static KnotPropertiesDialog instance; + return instance; + } + + void _setDesktop(SPDesktop *desktop); + void _setPt(const SPKnot *pt); + + void _apply(); + void _close(); + + void _setKnotPoint(Geom::Point knotpoint, Glib::ustring const unit_name); + void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); + + bool _handleKeyEvent(GdkEventKey *event); + void _handleButtonEvent(GdkEventButton* event); + friend class Inkscape::UI::Tools::MeasureTool; + +private: + KnotPropertiesDialog(KnotPropertiesDialog const &); // no copy + KnotPropertiesDialog &operator=(KnotPropertiesDialog const &); // no assign +}; + +} // namespace +} // namespace +} // namespace + + +#endif //INKSCAPE_DIALOG_LAYER_PROPERTIES_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/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index c40d2581e..e6e926d92 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -10,8 +10,11 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include +#endif - +#include #include #include #include "util/units.h" @@ -32,6 +35,7 @@ #include <2geom/crossing.h> #include <2geom/angle.h> #include <2geom/transforms.h> +#include "ui/dialog/knot-properties.h" #include "sp-namedview.h" #include "sp-shape.h" #include "sp-text.h" @@ -48,11 +52,11 @@ #include "document-undo.h" #include "viewbox.h" #include "snap.h" +#include "knot.h" #include "text-editing.h" #include "pixmaps/cursor-measure.xpm" #include "preferences.h" #include "inkscape.h" -#include "knot.h" #include "enums.h" #include "knot-enums.h" #include "desktop-style.h" @@ -338,13 +342,13 @@ MeasureTool::MeasureTool() end_p = readMeasurePoint(false); dimension_offset = 35; // create the knots - this->knot_start = new SPKnot(desktop, N_("Measure start")); + this->knot_start = new SPKnot(desktop, N_("Measure start, Shift+Click for position dialog")); 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 = new SPKnot(desktop, N_("Measure end, Shift+Click for position dialog")); 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); @@ -365,8 +369,10 @@ MeasureTool::MeasureTool() } this->_knot_start_moved_connection = this->knot_start->moved_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotStartMovedHandler)); + this->_knot_start_click_connection = this->knot_start->click_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotClickHandler)); 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_click_connection = this->knot_end->click_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotClickHandler)); this->_knot_end_ungrabbed_connection = this->knot_end->ungrabbed_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotUngrabbedHandler)); } @@ -444,6 +450,16 @@ void MeasureTool::reverseKnots() this->showCanvasItems(); } +void MeasureTool::knotClickHandler(SPKnot *knot, guint state) +{ + if (state & GDK_SHIFT_MASK) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring const unit_name = prefs->getString("/tools/measure/unit"); + Inkscape::UI::Dialogs::KnotPropertiesDialog::showDialog(desktop, knot, unit_name); + } +} + void MeasureTool::knotStartMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state) { Geom::Point point = this->knot_start->position(); diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index b5e9f8a1b..716e2cee8 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -11,6 +11,11 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ + +#ifdef HAVE_CONFIG_H +# include +#endif + #include #include #include "ui/tools/tool-base.h" @@ -59,8 +64,8 @@ public: 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 knotClickHandler(SPKnot *knot, guint state); void knotUngrabbedHandler(SPKnot */*knot*/, unsigned int /*state*/); - private: SPCanvasItem* grabbed; boost::optional explicitBase; @@ -74,7 +79,9 @@ private: std::vector measure_phantom_items; sigc::connection _knot_start_moved_connection; sigc::connection _knot_start_ungrabbed_connection; + sigc::connection _knot_start_click_connection; sigc::connection _knot_end_moved_connection; + sigc::connection _knot_end_click_connection; sigc::connection _knot_end_ungrabbed_connection; }; -- cgit v1.2.3 From 5cd75437cfc9fbc426a5e099a4dd5ebd31ace648 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 7 Feb 2016 17:13:37 +0100 Subject: Fix wrong replace of tab by spaces (bzr r14637) --- src/ui/dialog/Makefile_insert | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index 1e719bbda..71628973e 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -65,7 +65,7 @@ ink_common_sources += \ ui/dialog/knot-properties.h \ ui/dialog/layer-properties.cpp \ ui/dialog/layer-properties.h \ - ui/dialog/layers.cpp \ + ui/dialog/layers.cpp \ ui/dialog/layers.h \ ui/dialog/livepatheffect-add.cpp \ ui/dialog/livepatheffect-add.h \ -- cgit v1.2.3 From de2cf2716040fcc8eb3d18115bcaa76ee5d3f902 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 7 Feb 2016 18:56:35 +0100 Subject: Changed one icon/action in meassure toolbar to one more explicit (bzr r14638) --- src/ui/tools/measure-tool.cpp | 4 ++-- src/widgets/measure-toolbar.cpp | 20 ++++++++++---------- src/widgets/toolbox.cpp | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index e6e926d92..813b064aa 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -532,10 +532,10 @@ static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom: // Reconstruct and store the points of intersection Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool only_visible = prefs->getBool("/tools/measure/only_visible", false); + bool show_hidden = prefs->getBool("/tools/measure/show_hidden", true); SPDesktop *desktop = SP_ACTIVE_DESKTOP; for (Geom::Crossings::const_iterator m = cs[0].begin(); m != cs[0].end(); ++m) { - if(only_visible) { + if (!show_hidden) { double eps = 0.0001; if (((*m).ta > eps && item == desktop->getItemAtPoint(desktop->d2w(desktop->dt2doc(lineseg[0].pointAt((*m).ta - eps))), true, NULL)) || diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 9bab3ad4a..990989f4a 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -165,16 +165,16 @@ sp_toggle_ignore_1st_and_last( GtkToggleAction* act, gpointer data ) } static void -sp_toggle_only_visible( GtkToggleAction* act, gpointer data ) +sp_toggle_show_hidden( GtkToggleAction* act, gpointer data ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/measure/only_visible", active); + prefs->setBool("/tools/measure/show_hidden", active); SPDesktop *desktop = static_cast(data); if ( active ) { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Show only visible crossings.")); - } else { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Show all crossings.")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Show visible crossings.")); } MeasureTool *mt = get_measure_tool(); if (mt) { @@ -348,13 +348,13 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G } /* only visible */ { - InkToggleAction* act = ink_toggle_action_new( "MeasureOnlyVisible", - _("Only visible intersections"), - _("Only visible intersections"), - INKSCAPE_ICON("zoom"), + InkToggleAction* act = ink_toggle_action_new( "MeasureShowHidden", + _("Show hidden intersections"), + _("Show hidden intersections"), + INKSCAPE_ICON("object-hidden"), secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/only_visible", true) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_only_visible), desktop) ; + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/show_hidden", true) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_show_hidden), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } /* measure imbetweens */ diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 88dc7a190..6787ef6cc 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -372,7 +372,7 @@ static gchar const * ui_descr = " " " " " " - " " + " " " " " " " " -- cgit v1.2.3 From 0a2477feea6e1df586b926b8482afbf79e2355e1 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 7 Feb 2016 23:32:51 -0800 Subject: Sync 2Geom to commit 5ee51c1c4f2066faa3e2c82021fc92671ad44ba4 (bzr r14639) --- src/2geom/CMakeLists.txt | 1 - src/2geom/Makefile_insert | 2 - src/2geom/angle.h | 4 +- src/2geom/bezier-clipping.cpp | 4 +- src/2geom/bezier-curve.cpp | 98 +++++- src/2geom/bezier-curve.h | 14 +- src/2geom/crossing.h | 2 +- src/2geom/curve.cpp | 8 +- src/2geom/curve.h | 3 + src/2geom/d2-sbasis.cpp | 40 ++- src/2geom/d2-sbasis.h | 165 --------- src/2geom/d2.h | 81 ++++- src/2geom/ellipse.cpp | 78 +++-- src/2geom/ellipse.h | 3 + src/2geom/elliptical-arc.cpp | 303 +++++++++-------- src/2geom/elliptical-arc.h | 4 +- src/2geom/generic-interval.h | 2 - src/2geom/generic-rect.h | 2 +- src/2geom/int-point.h | 13 +- src/2geom/intersection-graph.cpp | 373 +++++++++++++-------- src/2geom/intersection-graph.h | 67 ++-- src/2geom/line.cpp | 14 + src/2geom/line.h | 2 + src/2geom/linear.h | 137 ++++---- src/2geom/path.cpp | 268 +++++++++------ src/2geom/path.h | 76 +++-- src/2geom/pathvector.cpp | 111 +++++- src/2geom/pathvector.h | 2 + src/2geom/piecewise.h | 2 +- src/2geom/rect.cpp | 78 +++++ src/2geom/rect.h | 57 +++- src/2geom/sbasis-curve.h | 5 + src/2geom/sbasis-math.cpp | 3 +- src/2geom/svg-path-parser.cpp | 4 +- src/2geom/svg-path-writer.cpp | 2 +- src/2geom/sweeper.h | 238 +++++-------- src/2geom/utils.h | 24 ++ src/2geom/viewbox.cpp | 133 -------- src/2geom/viewbox.h | 102 ------ src/display/canvas-axonomgrid.cpp | 8 +- src/display/nr-filter.cpp | 2 +- src/gradient-chemistry.cpp | 2 +- src/live_effects/lpe-bendpath.cpp | 4 +- src/live_effects/lpe-copy_rotate.cpp | 15 +- src/live_effects/lpe-dynastroke.cpp | 1 - src/live_effects/lpe-interpolate.cpp | 1 - src/live_effects/lpe-knot.cpp | 1 - src/live_effects/lpe-patternalongpath.cpp | 4 +- src/live_effects/lpe-simplify.cpp | 4 +- src/live_effects/lpe-transform_2pts.cpp | 8 +- .../parameter/filletchamferpointarray.cpp | 2 +- src/selection.cpp | 2 +- src/seltrans.cpp | 4 +- src/sp-guide.cpp | 2 +- src/svg/svg-affine.cpp | 2 +- src/svg/svg-path.cpp | 2 +- src/ui/dialog/guides.cpp | 4 +- src/ui/tools/measure-tool.cpp | 18 +- src/ui/tools/node-tool.cpp | 4 +- 59 files changed, 1406 insertions(+), 1209 deletions(-) delete mode 100644 src/2geom/d2-sbasis.h delete mode 100644 src/2geom/viewbox.cpp delete mode 100644 src/2geom/viewbox.h (limited to 'src') diff --git a/src/2geom/CMakeLists.txt b/src/2geom/CMakeLists.txt index eb7abb614..33f8baee6 100644 --- a/src/2geom/CMakeLists.txt +++ b/src/2geom/CMakeLists.txt @@ -48,7 +48,6 @@ set(2geom_SRC toposweep.cpp transforms.cpp utils.cpp - viewbox.cpp # ------- diff --git a/src/2geom/Makefile_insert b/src/2geom/Makefile_insert index e3c6836fd..b56942caa 100644 --- a/src/2geom/Makefile_insert +++ b/src/2geom/Makefile_insert @@ -120,8 +120,6 @@ 2geom/transforms.h \ 2geom/utils.cpp \ 2geom/utils.h \ - 2geom/viewbox.cpp \ - 2geom/viewbox.h \ 2geom/numeric/fitting-model.h \ 2geom/numeric/fitting-tool.h \ 2geom/numeric/linear_system.h \ diff --git a/src/2geom/angle.h b/src/2geom/angle.h index af4442e88..f0caaba6b 100644 --- a/src/2geom/angle.h +++ b/src/2geom/angle.h @@ -383,10 +383,10 @@ private: /** @brief Given an angle in degrees, return radians * @relates Angle */ -inline Coord deg_to_rad(Coord deg) { return deg*M_PI/180.0;} +inline Coord rad_from_deg(Coord deg) { return deg*M_PI/180.0;} /** @brief Given an angle in radians, return degrees * @relates Angle */ -inline Coord rad_to_deg(Coord rad) { return rad*180.0/M_PI;} +inline Coord deg_from_rad(Coord rad) { return rad*180.0/M_PI;} } // end namespace Geom diff --git a/src/2geom/bezier-clipping.cpp b/src/2geom/bezier-clipping.cpp index be8dd5a5f..03a6dfecd 100644 --- a/src/2geom/bezier-clipping.cpp +++ b/src/2geom/bezier-clipping.cpp @@ -788,7 +788,7 @@ void iterate (std::vector& domsA, #endif dom = clip(*C1, *C2, precision); - if (dom.isEmpty()) + if (dom.empty()) { #if VERBOSE std::cerr << "dom: empty" << std::endl; @@ -937,7 +937,7 @@ void iterate (std::vector& domsA, #endif dom = clip(*C1, *C2, precision); - if (dom.isEmpty()) { + if (dom.empty()) { #if VERBOSE std::cerr << "dom: empty" << std::endl; #endif diff --git a/src/2geom/bezier-curve.cpp b/src/2geom/bezier-curve.cpp index 17221264b..866263047 100644 --- a/src/2geom/bezier-curve.cpp +++ b/src/2geom/bezier-curve.cpp @@ -115,6 +115,17 @@ BezierCurve::BezierCurve(std::vector const &pts) } } +bool BezierCurve::isDegenerate() const +{ + for (unsigned d = 0; d < 2; ++d) { + Coord ic = inner[d][0]; + for (unsigned i = 1; i < size(); ++i) { + if (inner[d][i] != ic) return false; + } + } + return true; +} + Coord BezierCurve::length(Coord tolerance) const { switch (order()) @@ -169,6 +180,29 @@ BezierCurve::intersect(Curve const &other, Coord eps) const return result; } +bool BezierCurve::isNear(Curve const &c, Coord precision) const +{ + if (this == &c) return true; + + BezierCurve const *other = dynamic_cast(&c); + if (!other) return false; + + if (!are_near(inner.at0(), other->inner.at0(), precision)) return false; + if (!are_near(inner.at1(), other->inner.at1(), precision)) return false; + + if (size() == other->size()) { + for (unsigned i = 1; i < order(); ++i) { + if (!are_near(inner.point(i), other->inner.point(i), precision)) { + return false; + } + } + return true; + } else { + // TODO: comparison after degree elevation + return false; + } +} + bool BezierCurve::operator==(Curve const &c) const { if (this == &c) return true; @@ -280,6 +314,23 @@ std::vector BezierCurveN<1>::intersect(Curve const &other, Co return result; } +template <> +int BezierCurveN<1>::winding(Point const &p) const +{ + Point ip = inner.at0(), fp = inner.at1(); + if (p[Y] == std::max(ip[Y], fp[Y])) return 0; + + Point v = fp - ip; + assert(v[Y] != 0); + Coord t = (p[Y] - ip[Y]) / v[Y]; + assert(t >= 0 && t <= 1); + Coord xcross = lerp(t, ip[X], fp[X]); + if (xcross > p[X]) { + return v[Y] > 0 ? 1 : -1; + } + return 0; +} + template <> void BezierCurveN<1>::feed(PathSink &sink, bool moveto_initial) const { @@ -308,7 +359,7 @@ void BezierCurveN<3>::feed(PathSink &sink, bool moveto_initial) const } -static Coord bezier_length_internal(std::vector &v1, Coord tolerance) +static Coord bezier_length_internal(std::vector &v1, Coord tolerance, int level) { /* The Bezier length algorithm used in 2Geom utilizes a simple fact: * the Bezier curve is longer than the distance between its endpoints @@ -317,13 +368,15 @@ static Coord bezier_length_internal(std::vector &v1, Coord tolerance) * error tolerance, we can be sure that the true value is no further than * 0.5 * tolerance from their arithmetic mean. When it's larger, we recursively * subdivide the Bezier curve into two parts and add their lengths. + * + * We cap the maximum number of subdivisions at 256, which corresponds to 8 levels. */ Coord lower = distance(v1.front(), v1.back()); Coord upper = 0.0; for (size_t i = 0; i < v1.size() - 1; ++i) { upper += distance(v1[i], v1[i+1]); } - if (upper - lower < 2*tolerance) { + if (upper - lower <= 2*tolerance || level >= 8) { return (lower + upper) / 2; } @@ -381,7 +434,8 @@ static Coord bezier_length_internal(std::vector &v1, Coord tolerance) v2[i] = v1[0]; } - return bezier_length_internal(v1, 0.5*tolerance) + bezier_length_internal(v2, 0.5*tolerance); + return bezier_length_internal(v1, 0.5 * tolerance, level + 1) + + bezier_length_internal(v2, 0.5 * tolerance, level + 1); } /** @brief Compute the length of a bezier curve given by a vector of its control points @@ -390,17 +444,17 @@ Coord bezier_length(std::vector const &points, Coord tolerance) { if (points.size() < 2) return 0.0; std::vector v1 = points; - return bezier_length_internal(v1, tolerance); + return bezier_length_internal(v1, tolerance, 0); } -/** @brief Compute the length of a quadratic bezier curve given by its control points - * @relatesalso QuadraticBezier */ -Coord bezier_length(Point a0, Point a1, Point a2, Coord tolerance) +static Coord bezier_length_internal(Point a0, Point a1, Point a2, Coord tolerance, int level) { Coord lower = distance(a0, a2); Coord upper = distance(a0, a1) + distance(a1, a2); - if (upper - lower < 2*tolerance) return (lower + upper)/2; + if (upper - lower <= 2*tolerance || level >= 8) { + return (lower + upper) / 2; + } Point // Casteljau subdivision // b0 = a0, @@ -408,17 +462,25 @@ Coord bezier_length(Point a0, Point a1, Point a2, Coord tolerance) b1 = 0.5*(a0 + a1), c1 = 0.5*(a1 + a2), b2 = 0.5*(b1 + c1); // == c2 - return bezier_length(a0, b1, b2, 0.5*tolerance) + bezier_length(b2, c1, a2, 0.5*tolerance); + return bezier_length_internal(a0, b1, b2, 0.5 * tolerance, level + 1) + + bezier_length_internal(b2, c1, a2, 0.5 * tolerance, level + 1); } -/** @brief Compute the length of a cubic bezier curve given by its control points - * @relatesalso CubicBezier */ -Coord bezier_length(Point a0, Point a1, Point a2, Point a3, Coord tolerance) +/** @brief Compute the length of a quadratic bezier curve given by its control points + * @relatesalso QuadraticBezier */ +Coord bezier_length(Point a0, Point a1, Point a2, Coord tolerance) +{ + return bezier_length_internal(a0, a1, a2, tolerance, 0); +} + +static Coord bezier_length_internal(Point a0, Point a1, Point a2, Point a3, Coord tolerance, int level) { Coord lower = distance(a0, a3); Coord upper = distance(a0, a1) + distance(a1, a2) + distance(a2, a3); - if (upper - lower < 2*tolerance) return (lower + upper)/2; + if (upper - lower <= 2*tolerance || level >= 8) { + return (lower + upper) / 2; + } Point // Casteljau subdivision // b0 = a0, @@ -429,7 +491,15 @@ Coord bezier_length(Point a0, Point a1, Point a2, Point a3, Coord tolerance) b2 = 0.5*(b1 + t0), c2 = 0.5*(t0 + c1), b3 = 0.5*(b2 + c2); // == c3 - return bezier_length(a0, b1, b2, b3, 0.5*tolerance) + bezier_length(b3, c2, c1, a3, 0.5*tolerance); + return bezier_length_internal(a0, b1, b2, b3, 0.5 * tolerance, level + 1) + + bezier_length_internal(b3, c2, c1, a3, 0.5 * tolerance, level + 1); +} + +/** @brief Compute the length of a cubic bezier curve given by its control points + * @relatesalso CubicBezier */ +Coord bezier_length(Point a0, Point a1, Point a2, Point a3, Coord tolerance) +{ + return bezier_length_internal(a0, a1, a2, a3, tolerance, 0); } } // end namespace Geom diff --git a/src/2geom/bezier-curve.h b/src/2geom/bezier-curve.h index 9ac4d7b4d..9416ba78c 100644 --- a/src/2geom/bezier-curve.h +++ b/src/2geom/bezier-curve.h @@ -104,7 +104,7 @@ public: // implementation of virtual methods goes here virtual Point initialPoint() const { return inner.at0(); } virtual Point finalPoint() const { return inner.at1(); } - virtual bool isDegenerate() const { return inner.isConstant(0); } + virtual bool isDegenerate() const; virtual bool isLineSegment() const { return size() == 2; } virtual void setInitial(Point const &v) { setPoint(0, v); } virtual void setFinal(Point const &v) { setPoint(order(), v); } @@ -166,6 +166,7 @@ public: } virtual Coord valueAt(Coord t, Dim2 d) const { return inner[d].valueAt(t); } virtual D2 toSBasis() const {return inner.toSBasis(); } + virtual bool isNear(Curve const &c, Coord precision) const; virtual bool operator==(Curve const &c) const; virtual void feed(PathSink &sink, bool) const; }; @@ -244,6 +245,10 @@ public: BezierCurveN(sx.second, sy.second)); } + virtual bool isDegenerate() const { + return BezierCurve::isDegenerate(); + } + virtual bool isLineSegment() const { return size() == 2; } @@ -274,6 +279,9 @@ public: // call super. this is implemented only to allow specializations return BezierCurve::intersect(other, eps); } + virtual int winding(Point const &p) const { + return Curve::winding(p); + } virtual void feed(PathSink &sink, bool moveto_initial) const { // call super. this is implemented only to allow specializations BezierCurve::feed(sink, moveto_initial); @@ -304,10 +312,14 @@ Curve *BezierCurveN::derivative() const { } // optimized specializations +template <> inline bool BezierCurveN<1>::isDegenerate() const { + return inner[X][0] == inner[X][1] && inner[Y][0] == inner[Y][1]; +} template <> inline bool BezierCurveN<1>::isLineSegment() const { return true; } template <> Curve *BezierCurveN<1>::derivative() const; template <> Coord BezierCurveN<1>::nearestTime(Point const &, Coord, Coord) const; template <> std::vector BezierCurveN<1>::intersect(Curve const &, Coord) const; +template <> int BezierCurveN<1>::winding(Point const &) const; template <> void BezierCurveN<1>::feed(PathSink &sink, bool moveto_initial) const; template <> void BezierCurveN<2>::feed(PathSink &sink, bool moveto_initial) const; template <> void BezierCurveN<3>::feed(PathSink &sink, bool moveto_initial) const; diff --git a/src/2geom/crossing.h b/src/2geom/crossing.h index 425fa58f5..0f007b192 100644 --- a/src/2geom/crossing.h +++ b/src/2geom/crossing.h @@ -119,7 +119,7 @@ struct CrossingOrder { (ix == b.a ? b.ta : b.tb); else return (ix == a.a ? a.ta : a.tb) > - (ix == a.a ? a.ta : a.tb); + (ix == b.a ? b.ta : b.tb); } }; diff --git a/src/2geom/curve.cpp b/src/2geom/curve.cpp index 24c8be9f8..387a9180b 100644 --- a/src/2geom/curve.cpp +++ b/src/2geom/curve.cpp @@ -69,14 +69,14 @@ int Curve::winding(Point const &p) const // skip endpoint roots when they are local maxima on the Y axis // this follows the convention used in other winding routines, // i.e. that the bottommost coordinate is not part of the shape - bool ingore_0 = unitTangentAt(0)[Y] <= 0; + bool ignore_0 = unitTangentAt(0)[Y] <= 0; bool ignore_1 = unitTangentAt(1)[Y] >= 0; int wind = 0; for (std::size_t i = 0; i < ts.size(); ++i) { Coord t = ts[i]; //std::cout << t << std::endl; - if ((t == 0 && ingore_0) || (t == 1 && ignore_1)) continue; + if ((t == 0 && ignore_0) || (t == 1 && ignore_1)) continue; if (valueAt(t, X) > p[X]) { // root is ray intersection Point tangent = unitTangentAt(t); if (tangent[Y] > 0) { @@ -108,11 +108,7 @@ std::vector Curve::intersectSelf(Coord eps) const // Monotonic segments cannot have self-intersections. // Thus, we can split the curve at roots and intersect the portions. std::vector splits; -#if __cplusplus <= 199711L std::auto_ptr deriv(derivative()); -#else - std::unique_ptr deriv(derivative()); -#endif splits = deriv->roots(0, X); if (splits.empty()) { return result; diff --git a/src/2geom/curve.h b/src/2geom/curve.h index abbdb1100..41db9ca8a 100644 --- a/src/2geom/curve.h +++ b/src/2geom/curve.h @@ -333,6 +333,9 @@ public: * @return True if the curves are identical, false otherwise */ virtual bool operator==(Curve const &c) const = 0; + /** @brief Test whether two curves are approximately the same. */ + virtual bool isNear(Curve const &c, Coord precision) const = 0; + /** @brief Feed the curve to a PathSink */ virtual void feed(PathSink &sink, bool moveto_initial) const; /// @} diff --git a/src/2geom/d2-sbasis.cpp b/src/2geom/d2-sbasis.cpp index 4f00ff6a5..07eccce76 100644 --- a/src/2geom/d2-sbasis.cpp +++ b/src/2geom/d2-sbasis.cpp @@ -1,7 +1,41 @@ +/** + * \file + * \brief Some two-dimensional SBasis operations + *//* + * Authors: + * MenTaLguy + * Jean-FranƧois Barraud + * Johan Engelen + * + * Copyright 2007-2012 Authors + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, output to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + #include <2geom/d2.h> -/* One would think that we would include d2-sbasis.h, however, - * you cannot actually include it in anything - only d2 may import it. - * This is due to the trickinesses of template submatching. */ +#include <2geom/piecewise.h> namespace Geom { diff --git a/src/2geom/d2-sbasis.h b/src/2geom/d2-sbasis.h deleted file mode 100644 index a0769b314..000000000 --- a/src/2geom/d2-sbasis.h +++ /dev/null @@ -1,165 +0,0 @@ -/** - * \file - * \brief Do not include this file - * - * We don't actually want anyone to - * include this, other than D2.h. - *//* - * Authors: - * ? - * - * Copyright ?-? authors - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - */ - -#ifdef LIB2GEOM_SEEN_D2_H /*This is intentional: we don't actually want anyone to - include this, other than D2.h. If somone else tries, D2 - won't be defined. If it is, this will already be included. */ -#ifndef LIB2GEOM_SEEN_D2_SBASIS_H -#define LIB2GEOM_SEEN_D2_SBASIS_H - -#include <2geom/sbasis.h> -#include <2geom/sbasis-2d.h> -#include <2geom/piecewise.h> -#include <2geom/affine.h> - -//TODO: implement intersect - -namespace Geom { - -inline D2 compose(D2 const & a, SBasis const & b) { - return D2(compose(a[X], b), compose(a[Y], b)); -} - -SBasis L2(D2 const & a, unsigned k); -double L2(D2 const & a); - -D2 multiply(Linear const & a, D2 const & b); -inline D2 operator*(Linear const & a, D2 const & b) { return multiply(a, b); } -D2 multiply(SBasis const & a, D2 const & b); -inline D2 operator*(SBasis const & a, D2 const & b) { return multiply(a, b); } -D2 truncate(D2 const & a, unsigned terms); - -unsigned sbasis_size(D2 const & a); -double tail_error(D2 const & a, unsigned tail); - -//Piecewise > specific decls: - -Piecewise > sectionize(D2 > const &a); -D2 > make_cuts_independent(Piecewise > const &a); -Piecewise > rot90(Piecewise > const &a); -Piecewise dot(Piecewise > const &a, Piecewise > const &b); -Piecewise dot(Piecewise > const &a, Point const &b); -Piecewise cross(Piecewise > const &a, Piecewise > const &b); - -Piecewise > operator*(Piecewise > const &a, Affine const &m); - -Piecewise > force_continuity(Piecewise > const &f, double tol=0, bool closed=false); - -std::vector > > fuse_nearby_ends(std::vector > > const &f, double tol=0); - -std::vector > > split_at_discontinuities (Geom::Piecewise > const & pwsbin, double tol = .0001); - -/** -* note that -unitTangentAt(reverse(a),0.) == unitTangentAt(a,1.) but the former is more reliable (sometimes the sign is wrong for the latter) -*/ -Point unitTangentAt(D2 const & a, Coord t, unsigned n = 3); - -class CoordIterator -: public std::iterator -{ -public: - CoordIterator(std::vector >::const_iterator const &iter, unsigned d) : impl_(iter), ix_(d) {} - - inline bool operator==(CoordIterator const &other) { return other.impl_ == impl_; } - inline bool operator!=(CoordIterator const &other) { return other.impl_ != impl_; } - - inline SBasis operator*() const { - return (*impl_)[ix_]; - } - - inline CoordIterator &operator++() { - ++impl_; - return *this; - } - inline CoordIterator operator++(int) { - CoordIterator old=*this; - ++(*this); - return old; - } - -private: - std::vector >::const_iterator impl_; - unsigned ix_; -}; - -inline CoordIterator iterateCoord(Piecewise > const &a, unsigned d) { - return CoordIterator(a.segs.begin(), d); -} - -//bounds specializations with order -inline OptRect bounds_fast(D2 const & s, unsigned order=0) { - OptRect retval; - OptInterval xint = bounds_fast(s[X], order); - if (xint) { - OptInterval yint = bounds_fast(s[Y], order); - if (yint) { - retval = Rect(*xint, *yint); - } - } - return retval; -} -inline OptRect bounds_local(D2 const & s, OptInterval i, unsigned order=0) { - OptRect retval; - OptInterval xint = bounds_local(s[X], i, order); - OptInterval yint = bounds_local(s[Y], i, order); - if (xint && yint) { - retval = Rect(*xint, *yint); - } - return retval; -} - -std::vector level_set( D2 const &f, Rect region); -std::vector level_set( D2 const &f, Point p, double tol); -std::vector > level_sets( D2 const &f, std::vector regions); -std::vector > level_sets( D2 const &f, std::vector pts, double tol); - -} - -#endif // LIB2GEOM_SEEN_D2_SBASIS_H -#endif // LIB2GEOM_SEEN_D2_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/2geom/d2.h b/src/2geom/d2.h index dca6fa614..cd67ec65b 100644 --- a/src/2geom/d2.h +++ b/src/2geom/d2.h @@ -1,8 +1,12 @@ /** * \file - * \brief Lifts one dimensional objects into 2d + * \brief Lifts one dimensional objects into 2D *//* - * Copyright 2007 Michael Sloan + * Authors: + * Michael Sloan + * Krzysztof Kosiński + * + * Copyright 2007-2015 Authors * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public @@ -461,12 +465,6 @@ inline std::ostream &operator<< (std::ostream &out_file, const Geom::D2 &in_d return out_file; } -} //end namespace Geom - -#include <2geom/d2-sbasis.h> - -namespace Geom { - //Some D2 Fragment implementation which requires rect: template OptRect bounds_fast(const D2 &a) { @@ -484,6 +482,73 @@ OptRect bounds_local(const D2 &a, const OptInterval &t) { return OptRect(bounds_local(a[X], t), bounds_local(a[Y], t)); } + + +// SBasis-specific declarations + +inline D2 compose(D2 const & a, SBasis const & b) { + return D2(compose(a[X], b), compose(a[Y], b)); +} + +SBasis L2(D2 const & a, unsigned k); +double L2(D2 const & a); + +D2 multiply(Linear const & a, D2 const & b); +inline D2 operator*(Linear const & a, D2 const & b) { return multiply(a, b); } +D2 multiply(SBasis const & a, D2 const & b); +inline D2 operator*(SBasis const & a, D2 const & b) { return multiply(a, b); } +D2 truncate(D2 const & a, unsigned terms); + +unsigned sbasis_size(D2 const & a); +double tail_error(D2 const & a, unsigned tail); + +//Piecewise > specific declarations + +Piecewise > sectionize(D2 > const &a); +D2 > make_cuts_independent(Piecewise > const &a); +Piecewise > rot90(Piecewise > const &a); +Piecewise dot(Piecewise > const &a, Piecewise > const &b); +Piecewise dot(Piecewise > const &a, Point const &b); +Piecewise cross(Piecewise > const &a, Piecewise > const &b); + +Piecewise > operator*(Piecewise > const &a, Affine const &m); + +Piecewise > force_continuity(Piecewise > const &f, double tol=0, bool closed=false); + +std::vector > > fuse_nearby_ends(std::vector > > const &f, double tol=0); + +std::vector > > split_at_discontinuities (Geom::Piecewise > const & pwsbin, double tol = .0001); + +Point unitTangentAt(D2 const & a, Coord t, unsigned n = 3); + +//bounds specializations with order +inline OptRect bounds_fast(D2 const & s, unsigned order=0) { + OptRect retval; + OptInterval xint = bounds_fast(s[X], order); + if (xint) { + OptInterval yint = bounds_fast(s[Y], order); + if (yint) { + retval = Rect(*xint, *yint); + } + } + return retval; +} +inline OptRect bounds_local(D2 const & s, OptInterval i, unsigned order=0) { + OptRect retval; + OptInterval xint = bounds_local(s[X], i, order); + OptInterval yint = bounds_local(s[Y], i, order); + if (xint && yint) { + retval = Rect(*xint, *yint); + } + return retval; +} + +std::vector level_set( D2 const &f, Rect region); +std::vector level_set( D2 const &f, Point p, double tol); +std::vector > level_sets( D2 const &f, std::vector regions); +std::vector > level_sets( D2 const &f, std::vector pts, double tol); + + } // end namespace Geom #endif diff --git a/src/2geom/ellipse.cpp b/src/2geom/ellipse.cpp index 4b5ad9762..afde428b1 100644 --- a/src/2geom/ellipse.cpp +++ b/src/2geom/ellipse.cpp @@ -142,6 +142,24 @@ LineSegment Ellipse::semiaxis(Dim2 d, int sign) const return ls; } +Rect Ellipse::boundsExact() const +{ + Angle extremes[2][2]; + double sinrot, cosrot; + sincos(_angle, sinrot, cosrot); + + extremes[X][0] = std::atan2( -ray(Y) * sinrot, ray(X) * cosrot ); + extremes[X][1] = extremes[X][0] + M_PI; + extremes[Y][0] = std::atan2( ray(Y) * cosrot, ray(X) * sinrot ); + extremes[Y][1] = extremes[Y][0] + M_PI; + + Rect result; + for (unsigned d = 0; d < 2; ++d) { + result[d] = Interval(valueAt(extremes[d][0], d ? Y : X), + valueAt(extremes[d][1], d ? Y : X)); + } + return result; +} std::vector Ellipse::coefficients() const { @@ -396,45 +414,39 @@ std::vector Ellipse::intersect(Line const &line) const coefficients(A, B, C, D, E, F); Affine iuct = inverseUnitCircleTransform(); - if (line.isHorizontal()) { - // substitute y into the ellipse equation and solve - Coord y = line.initialPoint()[Y]; - std::vector xs = solve_quadratic(A, B*y + D, C*y*y + E*y + F); - for (unsigned i = 0; i < xs.size(); ++i) { - Point p(xs[i], y); - result.push_back(ShapeIntersection(atan2(p * iuct), line.timeAt(p), p)); - } - return result; - } - if (line.isVertical()) { - // substitute y into the ellipse equation and solve - Coord x = line.initialPoint()[X]; - std::vector ys = solve_quadratic(C, B*x + E, A*x*x + D*x + F); - for (unsigned i = 0; i < ys.size(); ++i) { - Point p(x, ys[i]); - result.push_back(ShapeIntersection(atan2(p * iuct), line.timeAt(p), p)); - } - return result; - } - // generic case Coord a, b, c; line.coefficients(a, b, c); + Point lv = line.versor(); - // y = -a/b x - C/B - // TODO: when is it better to substitute X? - Coord q = -a/b; - Coord r = -c/b; + if (fabs(lv[X]) > fabs(lv[Y])) { + // y = -a/b x - c/b + Coord q = -a/b; + Coord r = -c/b; - // substitute that into the ellipse equation, making it quadratic in x - Coord I = A + B*q + C*q*q; // x^2 terms - Coord J = B*r + C*2*q*r + D + E*q; // x^1 terms - Coord K = C*r*r + E*r + F; // x^0 terms - std::vector xs = solve_quadratic(I, J, K); + // substitute that into the ellipse equation, making it quadratic in x + Coord I = A + B*q + C*q*q; // x^2 terms + Coord J = B*r + C*2*q*r + D + E*q; // x^1 terms + Coord K = C*r*r + E*r + F; // x^0 terms + std::vector xs = solve_quadratic(I, J, K); - for (unsigned i = 0; i < xs.size(); ++i) { - Point p(xs[i], q*xs[i] + r); - result.push_back(ShapeIntersection(atan2(p * iuct), line.timeAt(p), p)); + for (unsigned i = 0; i < xs.size(); ++i) { + Point p(xs[i], q*xs[i] + r); + result.push_back(ShapeIntersection(atan2(p * iuct), line.timeAt(p), p)); + } + } else { + Coord q = -b/a; + Coord r = -c/a; + + Coord I = A*q*q + B*q + C; + Coord J = A*2*q*r + B*r + D*q + E; + Coord K = A*r*r + D*r + F; + std::vector xs = solve_quadratic(I, J, K); + + for (unsigned i = 0; i < xs.size(); ++i) { + Point p(q*xs[i] + r, xs[i]); + result.push_back(ShapeIntersection(atan2(p * iuct), line.timeAt(p), p)); + } } return result; } diff --git a/src/2geom/ellipse.h b/src/2geom/ellipse.h index 4b1701cce..f6089c944 100644 --- a/src/2geom/ellipse.h +++ b/src/2geom/ellipse.h @@ -171,6 +171,9 @@ public: LineSegment axis(Dim2 d) const; LineSegment semiaxis(Dim2 d, int sign = 1) const; + /// Get the tight-fitting bounding box of the ellipse. + Rect boundsExact() const; + /// Get the coefficients of the ellipse's implicit equation. std::vector coefficients() const; void coefficients(Coord &A, Coord &B, Coord &C, Coord &D, Coord &E, Coord &F) const; diff --git a/src/2geom/elliptical-arc.cpp b/src/2geom/elliptical-arc.cpp index 77d3d788d..a0e379a21 100644 --- a/src/2geom/elliptical-arc.cpp +++ b/src/2geom/elliptical-arc.cpp @@ -92,47 +92,58 @@ namespace Geom * @ingroup Curves */ + +/** @brief Compute bounds of an elliptical arc. + * The bounds computation works as follows. The extreme X and Y points + * are either the endpoints or local minima / maxima of the ellipse. + * We already have endpoints, and we can find the local extremes + * by computing a partial derivative with respect to the angle + * and equating that to zero: + * \f{align*}{ + x &= r_x \cos \varphi \cos \theta - r_y \sin \varphi \sin \theta + c_x \\ + \frac{\partial x}{\partial \theta} &= -r_x \cos \varphi \sin \theta - r_y \sin \varphi \cos \theta = 0 \\ + \frac{\sin \theta}{\cos \theta} &= \tan\theta = -\frac{r_y \sin \varphi}{r_x \cos \varphi} \\ + \theta &= \tan^{-1} \frac{-r_y \sin \varphi}{r_x \cos \varphi} + \f} + * The local extremes correspond to two angles separated by \f$\pi\f$. + * Once we compute these angles, we check whether they belong to the arc, + * and if they do, we evaluate the ellipse at these angles. + * The bounding box of the arc is equal to the bounding box of the endpoints + * and the local extrema that belong to the arc. + */ Rect EllipticalArc::boundsExact() const { if (isChord()) { return chord().boundsExact(); } - using std::swap; + Coord coord[2][4] = { + { _initial_point[X], _final_point[X], 0, 0 }, + { _initial_point[Y], _final_point[Y], 0, 0 } + }; + int ncoord[2] = { 2, 2 }; - // TODO: simplify / document what is going on here. - double extremes[4]; + Angle extremes[2][2]; double sinrot, cosrot; sincos(rotationAngle(), sinrot, cosrot); - extremes[0] = std::atan2( -ray(Y) * sinrot, ray(X) * cosrot ); - extremes[1] = extremes[0] + M_PI; - if ( extremes[0] < 0 ) extremes[0] += 2*M_PI; - extremes[2] = std::atan2( ray(Y) * cosrot, ray(X) * sinrot ); - extremes[3] = extremes[2] + M_PI; - if ( extremes[2] < 0 ) extremes[2] += 2*M_PI; - - - double arc_extremes[4]; - arc_extremes[0] = initialPoint()[X]; - arc_extremes[1] = finalPoint()[X]; - if ( arc_extremes[0] < arc_extremes[1] ) - swap(arc_extremes[0], arc_extremes[1]); - arc_extremes[2] = initialPoint()[Y]; - arc_extremes[3] = finalPoint()[Y]; - if ( arc_extremes[2] < arc_extremes[3] ) - swap(arc_extremes[2], arc_extremes[3]); - - if ( !are_near(initialPoint(), finalPoint()) ) { - for (unsigned i = 0; i < 4; ++i) { - if (containsAngle(extremes[i])) { - arc_extremes[i] = valueAtAngle(extremes[i], (i >> 1) ? Y : X); + extremes[X][0] = std::atan2( -ray(Y) * sinrot, ray(X) * cosrot ); + extremes[X][1] = extremes[X][0] + M_PI; + extremes[Y][0] = std::atan2( ray(Y) * cosrot, ray(X) * sinrot ); + extremes[Y][1] = extremes[Y][0] + M_PI; + + for (unsigned d = 0; d < 2; ++d) { + for (unsigned i = 0; i < 2; ++i) { + if (containsAngle(extremes[d][i])) { + coord[d][ncoord[d]++] = valueAtAngle(extremes[d][i], d ? Y : X); } } } - return Rect( Point(arc_extremes[1], arc_extremes[3]) , - Point(arc_extremes[0], arc_extremes[2]) ); + Interval xival = Interval::from_range(coord[X], coord[X] + ncoord[X]); + Interval yival = Interval::from_range(coord[Y], coord[Y] + ncoord[Y]); + Rect result(xival, yival); + return result; } @@ -149,116 +160,14 @@ Coord EllipticalArc::valueAtAngle(Coord t, Dim2 d) const std::vector EllipticalArc::roots(Coord v, Dim2 d) const { - if (isChord()) { - return chord().roots(v, d); - } - std::vector sol; - Interval unit_interval(0, 1); - if ( are_near(ray(X), 0) && are_near(ray(Y), 0) ) { - if ( center(d) == v ) - sol.push_back(0); + if (isChord()) { + sol = chord().roots(v, d); return sol; } - static const char* msg[2][2] = - { - { "d == X; ray(X) == 0; " - "s = (v - center(X)) / ( -ray(Y) * std::sin(_rot_angle) ); " - "s should be contained in [-1,1]", - "d == X; ray(Y) == 0; " - "s = (v - center(X)) / ( ray(X) * std::cos(_rot_angle) ); " - "s should be contained in [-1,1]" - }, - { "d == Y; ray(X) == 0; " - "s = (v - center(X)) / ( ray(Y) * std::cos(_rot_angle) ); " - "s should be contained in [-1,1]", - "d == Y; ray(Y) == 0; " - "s = (v - center(X)) / ( ray(X) * std::sin(_rot_angle) ); " - "s should be contained in [-1,1]" - }, - }; - - for ( unsigned int dim = 0; dim < 2; ++dim ) - { - if (ray((Dim2) dim) == 0) - { - if ( initialPoint()[d] == v && finalPoint()[d] == v ) - { - THROW_INFINITESOLUTIONS(0); - } - if ( (initialPoint()[d] < finalPoint()[d]) - && (initialPoint()[d] > v || finalPoint()[d] < v) ) - { - return sol; - } - if ( (initialPoint()[d] > finalPoint()[d]) - && (finalPoint()[d] > v || initialPoint()[d] < v) ) - { - return sol; - } - double ray_prj = 0.0; - switch(d) - { - case X: - switch(dim) - { - case X: ray_prj = -ray(Y) * std::sin(rotationAngle()); - break; - case Y: ray_prj = ray(X) * std::cos(rotationAngle()); - break; - } - break; - case Y: - switch(dim) - { - case X: ray_prj = ray(Y) * std::cos(rotationAngle()); - break; - case Y: ray_prj = ray(X) * std::sin(rotationAngle()); - break; - } - break; - } - - double s = (v - center(d)) / ray_prj; - if ( s < -1 || s > 1 ) - { - THROW_LOGICALERROR(msg[d][dim]); - } - switch(dim) - { - case X: - s = std::asin(s); // return a value in [-PI/2,PI/2] - if ( logical_xor( sweep(), are_near(initialAngle(), M_PI/2) ) ) - { - if ( s < 0 ) s += 2*M_PI; - } - else - { - s = M_PI - s; - if (!(s < 2*M_PI) ) s -= 2*M_PI; - } - break; - case Y: - s = std::acos(s); // return a value in [0,PI] - if ( logical_xor( sweep(), are_near(initialAngle(), 0) ) ) - { - s = 2*M_PI - s; - if ( !(s < 2*M_PI) ) s -= 2*M_PI; - } - break; - } - - //std::cerr << "s = " << rad_to_deg(s); - s = timeAtAngle(s); - //std::cerr << " -> t: " << s << std::endl; - if (unit_interval.contains(s)) { - sol.push_back(s); - } - return sol; - } - } + Interval unit_interval(0, 1); double rotx, roty; if (d == X) { @@ -278,10 +187,10 @@ std::vector EllipticalArc::roots(Coord v, Dim2 d) const //std::cerr << "b = " << b << std::endl; //std::cerr << "c = " << c << std::endl; - if ( are_near(a,0) ) + if (a == 0) { sol.push_back(M_PI); - if ( !are_near(b,0) ) + if (b != 0) { double s = 2 * std::atan(-c/(2*b)); if ( s < 0 ) s += 2*M_PI; @@ -292,8 +201,7 @@ std::vector EllipticalArc::roots(Coord v, Dim2 d) const { double delta = b * b - a * c; //std::cerr << "delta = " << delta << std::endl; - if ( are_near(delta, 0) ) - { + if (delta == 0) { double s = 2 * std::atan(-b/a); if ( s < 0 ) s += 2*M_PI; sol.push_back(s); @@ -312,7 +220,7 @@ std::vector EllipticalArc::roots(Coord v, Dim2 d) const std::vector arc_sol; for (unsigned int i = 0; i < sol.size(); ++i ) { - //std::cerr << "s = " << rad_to_deg(sol[i]); + //std::cerr << "s = " << deg_from_rad(sol[i]); sol[i] = timeAtAngle(sol[i]); //std::cerr << " -> t: " << sol[i] << std::endl; if (unit_interval.contains(sol[i])) { @@ -354,11 +262,7 @@ EllipticalArc::pointAndDerivatives(Coord t, unsigned int n) const std::vector result; result.reserve(nn); double angle = angleAt(t); -#if __cplusplus <= 199711L std::auto_ptr ea( static_cast(duplicate()) ); -#else - std::unique_ptr ea( static_cast(duplicate()) ); -#endif ea->_ellipse.setCenter(0, 0); unsigned int m = std::min(nn, 4u); for ( unsigned int i = 0; i < m; ++i ) @@ -890,6 +794,25 @@ bool EllipticalArc::operator==(Curve const &c) const return true; } +bool EllipticalArc::isNear(Curve const &c, Coord precision) const +{ + EllipticalArc const *other = dynamic_cast(&c); + if (!other) { + if (isChord()) { + return c.isNear(chord(), precision); + } + return false; + } + + if (!are_near(_initial_point, other->_initial_point, precision)) return false; + if (!are_near(_final_point, other->_final_point, precision)) return false; + if (isChord() && other->isChord()) return true; + + if (sweep() != other->sweep()) return false; + if (!are_near(_ellipse, other->_ellipse, precision)) return false; + return true; +} + void EllipticalArc::feed(PathSink &sink, bool moveto_initial) const { if (moveto_initial) { @@ -898,6 +821,104 @@ void EllipticalArc::feed(PathSink &sink, bool moveto_initial) const sink.arcTo(ray(X), ray(Y), rotationAngle(), _large_arc, sweep(), _final_point); } +int EllipticalArc::winding(Point const &p) const +{ + using std::swap; + + double sinrot, cosrot; + sincos(rotationAngle(), sinrot, cosrot); + + Angle ymin_a = std::atan2( ray(Y) * cosrot, ray(X) * sinrot ); + Angle ymax_a = ymin_a + M_PI; + + Point ymin = pointAtAngle(ymin_a); + Point ymax = pointAtAngle(ymax_a); + if (ymin[Y] > ymax[Y]) { + swap(ymin, ymax); + swap(ymin_a, ymax_a); + } + + Interval yspan(ymin[Y], ymax[Y]); + if (!yspan.lowerContains(p[Y])) return 0; + + bool left = cross(ymax - ymin, p - ymin) > 0; + bool inside = _ellipse.contains(p); + bool includes_ymin = _angles.contains(ymin_a); + bool includes_ymax = _angles.contains(ymax_a); + + AngleInterval rarc(ymin_a, ymax_a, true), + larc(ymax_a, ymin_a, true); + + // we'll compute the result for an arc in the direction of increasing angles + // and then negate if necessary + Angle ia = initialAngle(), fa = finalAngle(); + Point ip = _initial_point, fp = _final_point; + if (!sweep()) { + swap(ia, fa); + swap(ip, fp); + } + + bool initial_left = larc.contains(ia); + bool initial_right = !initial_left; //rarc.contains(ia); + bool final_right = rarc.contains(fa); + bool final_left = !final_right;//larc.contains(fa); + + int result = 0; + if (inside || left) { + if (includes_ymin && final_right) { + Interval ival(ymin[Y], fp[Y]); + if (ival.lowerContains(p[Y])) { + ++result; + } + } + if (initial_right && final_right && !largeArc()) { + Interval ival(ip[Y], fp[Y]); + if (ival.lowerContains(p[Y])) { + ++result; + } + } + if (initial_right && includes_ymax) { + Interval ival(ip[Y], ymax[Y]); + if (ival.lowerContains(p[Y])) { + ++result; + } + } + if (!initial_right && !final_right && includes_ymin && includes_ymax) { + Interval ival(ymax[Y], ymin[Y]); + if (ival.lowerContains(p[Y])) { + ++result; + } + } + } + if (left && !inside) { + if (includes_ymin && initial_left) { + Interval ival(ymin[Y], ip[Y]); + if (ival.lowerContains(p[Y])) { + --result; + } + } + if (initial_left && final_left && !largeArc()) { + Interval ival(ip[Y], fp[Y]); + if (ival.lowerContains(p[Y])) { + --result; + } + } + if (final_left && includes_ymax) { + Interval ival(fp[Y], ymax[Y]); + if (ival.lowerContains(p[Y])) { + --result; + } + } + if (!initial_left && !final_left && includes_ymin && includes_ymax) { + Interval ival(ymax[Y], ymin[Y]); + if (ival.lowerContains(p[Y])) { + --result; + } + } + } + return sweep() ? result : -result; +} + std::ostream &operator<<(std::ostream &out, EllipticalArc const &ea) { out << "EllipticalArc(" diff --git a/src/2geom/elliptical-arc.h b/src/2geom/elliptical-arc.h index fbb290dca..96a92eb88 100644 --- a/src/2geom/elliptical-arc.h +++ b/src/2geom/elliptical-arc.h @@ -215,7 +215,7 @@ public: /// Get the angular interval of the arc. AngleInterval angularInterval() const { return _angles; } - /// Evaluate the arc in the curve domain, i.e. \f$[0, 1]\$. + /// Evaluate the arc in the curve domain, i.e. \f$[0, 1]\f$. virtual Point pointAt(Coord t) const; /// Evaluate a single coordinate on the arc in the curve domain. @@ -300,7 +300,9 @@ public: virtual Curve *portion(double f, double t) const; virtual Curve *reverse() const; virtual bool operator==(Curve const &c) const; + virtual bool isNear(Curve const &other, Coord precision) const; virtual void feed(PathSink &sink, bool moveto_initial) const; + virtual int winding(Point const &p) const; private: void _updateCenterAndAngles(); diff --git a/src/2geom/generic-interval.h b/src/2geom/generic-interval.h index 716390e57..ce7945ab6 100644 --- a/src/2geom/generic-interval.h +++ b/src/2geom/generic-interval.h @@ -291,8 +291,6 @@ public: /// @} /** @brief Check whether this interval is empty. */ - bool isEmpty() { return !*this; }; - /// Alias of isEmpty() for STL similarity. bool empty() { return !*this; } /** @brief Union with another interval, gracefully handling empty ones. */ diff --git a/src/2geom/generic-rect.h b/src/2geom/generic-rect.h index f7d722757..afd2cb8a7 100644 --- a/src/2geom/generic-rect.h +++ b/src/2geom/generic-rect.h @@ -393,7 +393,7 @@ public: /// @name Check other rectangles and points for inclusion. /// @{ /** @brief Check for emptiness. */ - inline bool isEmpty() const { return !*this; }; + inline bool empty() const { return !*this; }; /** @brief Check whether the rectangles have any common points. * Empty rectangles will not intersect with any other rectangle. */ bool intersects(CRect const &r) const { return r.intersects(*this); } diff --git a/src/2geom/int-point.h b/src/2geom/int-point.h index 7c737b1d7..50d3a6720 100644 --- a/src/2geom/int-point.h +++ b/src/2geom/int-point.h @@ -60,15 +60,6 @@ public: _pt[X] = x; _pt[Y] = y; } - IntPoint(IntPoint const &p) { - _pt[X] = p._pt[X]; - _pt[Y] = p._pt[Y]; - } - IntPoint &operator=(IntPoint const &p) { - _pt[X] = p._pt[X]; - _pt[Y] = p._pt[Y]; - return *this; - } /// @} /// @name Access the coordinates of a point @@ -92,6 +83,10 @@ public: /// @name Vector-like arithmetic operations /// @{ + IntPoint operator-() const { + IntPoint ret(-_pt[X], -_pt[Y]); + return ret; + } IntPoint &operator+=(IntPoint const &o) { _pt[X] += o._pt[X]; _pt[Y] += o._pt[Y]; diff --git a/src/2geom/intersection-graph.cpp b/src/2geom/intersection-graph.cpp index e18561f67..d469d3ffc 100644 --- a/src/2geom/intersection-graph.cpp +++ b/src/2geom/intersection-graph.cpp @@ -34,6 +34,7 @@ #include <2geom/intersection-graph.h> #include <2geom/path.h> #include <2geom/pathvector.h> +#include <2geom/utils.h> #include #include @@ -56,101 +57,174 @@ struct PathIntersectionGraph::IntersectionVertexLess { */ PathIntersectionGraph::PathIntersectionGraph(PathVector const &a, PathVector const &b, Coord precision) - : _a(a) - , _b(b) + : _graph_valid(true) { if (a.empty() || b.empty()) return; + _pv[0] = a; + _pv[1] = b; + + _prepareArguments(); + bool has_intersections = _prepareIntersectionLists(precision); + if (!has_intersections) return; + + _assignEdgeWindingParities(precision); + _assignComponentStatusFromDegenerateIntersections(); + _removeDegenerateIntersections(); + if (_graph_valid) { + _verify(); + } +} + +void PathIntersectionGraph::_prepareArguments() +{ // all paths must be closed, otherwise we will miss some intersections - for (std::size_t i = 0; i < a.size(); ++i) { - _a[i].close(); + for (int w = 0; w < 2; ++w) { + for (std::size_t i = 0; i < _pv[w].size(); ++i) { + _pv[w][i].close(); + } } - for (std::size_t i = 0; i < b.size(); ++i) { - _b[i].close(); + // remove degenerate segments + for (int w = 0; w < 2; ++w) { + for (std::size_t i = _pv[w].size(); i > 0; --i) { + if (_pv[w][i-1].empty()) { + _pv[w].erase(_pv[w].begin() + (i-1)); + } + for (std::size_t j = _pv[w][i-1].size(); j > 0; --j) { + if (_pv[w][i-1][j-1].isDegenerate()) { + _pv[w][i-1].erase(_pv[w][i-1].begin() + (j-1)); + } + } + } } +} - std::vector pxs = _a.intersect(_b, precision); +bool PathIntersectionGraph::_prepareIntersectionLists(Coord precision) +{ + std::vector pxs = _pv[0].intersect(_pv[1], precision); // NOTE: this early return means that the path data structures will not be created // if there are no intersections at all! - if (pxs.empty()) return; + if (pxs.empty()) return false; // prepare intersection lists for each path component - for (std::size_t i = 0; i < _a.size(); ++i) { - _apaths.push_back(new PathData()); - } - for (std::size_t i = 0; i < _b.size(); ++i) { - _bpaths.push_back(new PathData()); + for (unsigned w = 0; w < 2; ++w) { + for (std::size_t i = 0; i < _pv[w].size(); ++i) { + _components[w].push_back(new PathData(w, i)); + } } + // create intersection vertices for (std::size_t i = 0; i < pxs.size(); ++i) { IntersectionVertex *xa, *xb; xa = new IntersectionVertex(); xb = new IntersectionVertex(); - xa->processed = xb->processed = false; + //xa->processed = xb->processed = false; + xa->which = 0; xb->which = 1; xa->pos = pxs[i].first; xb->pos = pxs[i].second; xa->p = xb->p = pxs[i].point(); xa->neighbor = xb; xb->neighbor = xa; + xa->next_edge = xb->next_edge = OUTSIDE; + xa->defective = xb->defective = false; _xs.push_back(xa); _xs.push_back(xb); - _apaths[xa->pos.path_index].xlist.push_back(*xa); - _bpaths[xb->pos.path_index].xlist.push_back(*xb); + _components[0][xa->pos.path_index].xlist.push_back(*xa); + _components[1][xb->pos.path_index].xlist.push_back(*xb); } - for (std::size_t i = 0; i < _apaths.size(); ++i) { - _apaths[i].xlist.sort(IntersectionVertexLess()); - } - for (std::size_t i = 0; i < _bpaths.size(); ++i) { - _bpaths[i].xlist.sort(IntersectionVertexLess()); + // sort components according to time value of intersections + for (unsigned w = 0; w < 2; ++w) { + for (std::size_t i = 0; i < _components[w].size(); ++i) { + _components[w][i].xlist.sort(IntersectionVertexLess()); + } } - typedef IntersectionList::iterator Iter; - - // determine in/out/on flags using winding - for (unsigned npv = 0; npv < 2; ++npv) { - boost::ptr_vector &ls = npv ? _bpaths : _apaths; - boost::ptr_vector &ols = npv ? _apaths : _bpaths; - PathVector const &pv = npv ? b : a; - PathVector const &other = npv ? a : b; - - for (unsigned li = 0; li < ls.size(); ++li) { - IntersectionList &xl = ls[li].xlist; - for (Iter i = xl.begin(); i != xl.end(); ++i) { - Iter n = boost::next(i); - if (n == xl.end()) { - n = xl.begin(); - } + return true; +} + +void PathIntersectionGraph::_assignEdgeWindingParities(Coord precision) +{ + // determine the winding numbers of path portions between intersections + for (unsigned w = 0; w < 2; ++w) { + unsigned ow = (w+1) % 2; + + for (unsigned li = 0; li < _components[w].size(); ++li) { + IntersectionList &xl = _components[w][li].xlist; + for (ILIter i = xl.begin(); i != xl.end(); ++i) { + ILIter n = cyclic_next(i, xl); std::size_t pi = i->pos.path_index; - PathInterval ival = forward_interval(i->pos, n->pos, pv[pi].size()); + PathInterval ival = forward_interval(i->pos, n->pos, _pv[w][pi].size()); PathTime mid = ival.inside(precision); - // TODO check for degenerate cases - int w = other.winding(pv[pi].pointAt(mid)); - if (w % 2) { - i->next = POINT_INSIDE; - n->previous = POINT_INSIDE; + Point wpoint = _pv[w][pi].pointAt(mid); + _winding_points.push_back(wpoint); + int wdg = _pv[ow].winding(wpoint); + if (wdg % 2) { + i->next_edge = INSIDE; } else { - i->next = POINT_OUTSIDE; - n->previous = POINT_OUTSIDE; + i->next_edge = OUTSIDE; } } + } + } +} + +void PathIntersectionGraph::_assignComponentStatusFromDegenerateIntersections() +{ + // If a path has only degenerate intersections, assign its status now. + // This protects against later accidentaly picking a point for winding + // determination that is exactly at a removed intersection. + for (unsigned w = 0; w < 2; ++w) { + for (unsigned li = 0; li < _components[w].size(); ++li) { + IntersectionList &xl = _components[w][li].xlist; + bool has_in = false; + bool has_out = false; + for (ILIter i = xl.begin(); i != xl.end(); ++i) { + has_in |= (i->next_edge == INSIDE); + has_out |= (i->next_edge == OUTSIDE); + } + if (has_in && !has_out) { + _components[w][li].status = INSIDE; + } + if (!has_in && has_out) { + _components[w][li].status = OUTSIDE; + } + } + } +} - // remove intersections that don't change between in/out - // and assign exit / entry flags - for (Iter i = xl.begin(); i != xl.end();) { - if (i->previous == i->next) { - IntersectionList &oxl = ols[i->neighbor->pos.path_index].xlist; - oxl.erase(oxl.iterator_to(*i->neighbor)); - xl.erase(i++); - if (i->next == POINT_INSIDE) { - ++ls[li].removed_in; - } else { - ++ls[li].removed_out; +void PathIntersectionGraph::_removeDegenerateIntersections() +{ + // remove intersections that don't change between in/out + for (unsigned w = 0; w < 2; ++w) { + for (unsigned li = 0; li < _components[w].size(); ++li) { + IntersectionList &xl = _components[w][li].xlist; + for (ILIter i = xl.begin(); i != xl.end();) { + ILIter n = cyclic_next(i, xl); + if (i->next_edge == n->next_edge) { + bool last_node = (i == n); + ILIter nn = _getNeighbor(n); + IntersectionList &oxl = _getPathData(nn).xlist; + + // When exactly 3 out of 4 edges adjacent to an intersection + // have the same winding, we have a defective intersection, + // which is neither degenerate nor normal. Those can occur in paths + // that contain overlapping segments. We cannot handle that case + // for now, so throw an exception. + if (cyclic_prior(nn, oxl)->next_edge != nn->next_edge) { + _graph_valid = false; + n->defective = true; + nn->defective = true; + ++i; + continue; } + + oxl.erase(nn); + xl.erase(n); + if (last_node) break; } else { - i->entry = ((i->next == POINT_INSIDE) && (i->previous == POINT_OUTSIDE)); ++i; } } @@ -158,6 +232,20 @@ PathIntersectionGraph::PathIntersectionGraph(PathVector const &a, PathVector con } } +void PathIntersectionGraph::_verify() +{ + for (unsigned w = 0; w < 2; ++w) { + for (unsigned li = 0; li < _components[w].size(); ++li) { + IntersectionList &xl = _components[w][li].xlist; + assert(xl.size() % 2 == 0); + for (ILIter i = xl.begin(); i != xl.end(); ++i) { + ILIter j = cyclic_next(i, xl); + assert(i->next_edge != j->next_edge); + } + } + } +} + PathVector PathIntersectionGraph::getUnion() { PathVector result = _getResult(false, false); @@ -192,8 +280,9 @@ PathVector PathIntersectionGraph::getBminusA() PathVector PathIntersectionGraph::getXOR() { - PathVector r1 = getAminusB(); - PathVector r2 = getBminusA(); + PathVector r1, r2; + r1 = getAminusB(); + r2 = getBminusA(); std::copy(r2.begin(), r2.end(), std::back_inserter(r1)); return r1; } @@ -201,37 +290,61 @@ PathVector PathIntersectionGraph::getXOR() std::size_t PathIntersectionGraph::size() const { std::size_t result = 0; - for (std::size_t i = 0; i < _apaths.size(); ++i) { - result += _apaths[i].xlist.size(); + for (std::size_t i = 0; i < _components[0].size(); ++i) { + result += _components[0][i].xlist.size(); } return result; } -std::vector PathIntersectionGraph::intersectionPoints() const +std::vector PathIntersectionGraph::intersectionPoints(bool defective) const { std::vector result; - typedef IntersectionList::const_iterator Iter; - for (std::size_t i = 0; i < _apaths.size(); ++i) { - for (Iter j = _apaths[i].xlist.begin(); j != _apaths[i].xlist.end(); ++j) { - result.push_back(j->p); + typedef IntersectionList::const_iterator CILIter; + for (std::size_t i = 0; i < _components[0].size(); ++i) { + for (CILIter j = _components[0][i].xlist.begin(); j != _components[0][i].xlist.end(); ++j) { + if (j->defective == defective) { + result.push_back(j->p); + } } } return result; } +void PathIntersectionGraph::fragments(PathVector &in, PathVector &out) const +{ + typedef boost::ptr_vector::const_iterator PIter; + for (unsigned w = 0; w < 2; ++w) { + for (PIter li = _components[w].begin(); li != _components[w].end(); ++li) { + for (CILIter k = li->xlist.begin(); k != li->xlist.end(); ++k) { + CILIter n = cyclic_next(k, li->xlist); + // TODO: investigate why non-contiguous paths are sometimes generated here + Path frag(k->p); + frag.setStitching(true); + PathInterval ival = forward_interval(k->pos, n->pos, _pv[w][k->pos.path_index].size()); + _pv[w][k->pos.path_index].appendPortionTo(frag, ival, k->p, n->p); + if (k->next_edge == INSIDE) { + in.push_back(frag); + } else { + out.push_back(frag); + } + } + } + } +} + PathVector PathIntersectionGraph::_getResult(bool enter_a, bool enter_b) { - typedef IntersectionList::iterator Iter; + typedef boost::ptr_vector::iterator PIter; PathVector result; if (_xs.empty()) return result; // reset processed status - for (unsigned npv = 0; npv < 2; ++npv) { - boost::ptr_vector &ls = npv ? _bpaths : _apaths; - for (std::size_t li = 0; li < ls.size(); ++li) { - for (Iter k = ls[li].xlist.begin(); k != ls[li].xlist.end(); ++k) { - k->processed = false; + _ulist.clear(); + for (unsigned w = 0; w < 2; ++w) { + for (PIter li = _components[w].begin(); li != _components[w].end(); ++li) { + for (ILIter k = li->xlist.begin(); k != li->xlist.end(); ++k) { + _ulist.push_back(*k); } } } @@ -239,18 +352,17 @@ PathVector PathIntersectionGraph::_getResult(bool enter_a, bool enter_b) unsigned n_processed = 0; while (true) { - PathVector const *cur = &_a, *other = &_b; - boost::ptr_vector *lscur = &_apaths, *lsother = &_bpaths; - - // find unprocessed intersection - Iter i; - if (!_findUnprocessed(i)) break; + // get unprocessed intersection + if (_ulist.empty()) break; + IntersectionVertex &iv = _ulist.front(); + unsigned w = iv.which; + ILIter i = _components[w][iv.pos.path_index].xlist.iterator_to(iv); result.push_back(Path(i->p)); result.back().setStitching(true); - while (!i->processed) { - Iter prev = i; + while (i->_proc_hook.is_linked()) { + ILIter prev = i; std::size_t pi = i->pos.path_index; // determine which direction to go // union: always go outside @@ -258,53 +370,55 @@ PathVector PathIntersectionGraph::_getResult(bool enter_a, bool enter_b) // a minus b: go inside in b, outside in a // b minus a: go inside in a, outside in b bool reverse = false; - if (cur == &_a) { - reverse = i->entry ^ enter_a; + if (w == 0) { + reverse = (i->next_edge == INSIDE) ^ enter_a; } else { - reverse = i->entry ^ enter_b; + reverse = (i->next_edge == INSIDE) ^ enter_b; } // get next intersection if (reverse) { - if (i == (*lscur)[pi].xlist.begin()) { - i = (*lscur)[pi].xlist.end(); - } - --i; + i = cyclic_prior(i, _components[w][pi].xlist); } else { - ++i; - if (i == (*lscur)[pi].xlist.end()) { - i = (*lscur)[pi].xlist.begin(); - } + i = cyclic_next(i, _components[w][pi].xlist); } // append portion of path PathInterval ival = PathInterval::from_direction( prev->pos.asPathTime(), i->pos.asPathTime(), - reverse, (*cur)[pi].size()); + reverse, _pv[i->which][pi].size()); - (*cur)[pi].appendPortionTo(result.back(), ival, prev->p, i->p); + _pv[i->which][pi].appendPortionTo(result.back(), ival, prev->p, i->p); // mark both vertices as processed - prev->processed = true; - i->processed = true; + //prev->processed = true; + //i->processed = true; n_processed += 2; + if (prev->_proc_hook.is_linked()) { + _ulist.erase(_ulist.iterator_to(*prev)); + } + if (i->_proc_hook.is_linked()) { + _ulist.erase(_ulist.iterator_to(*i)); + } // switch to the other path - i = (*lsother)[i->neighbor->pos.path_index].xlist.iterator_to(*i->neighbor); - std::swap(lscur, lsother); - std::swap(cur, other); + i = _getNeighbor(i); + w = i->which; } result.back().close(true); assert(!result.back().empty()); } + /*if (n_processed != size() * 2) { + std::cerr << "Processed " << n_processed << " intersections, expected " << (size() * 2) << std::endl; + }*/ assert(n_processed == size() * 2); return result; } -void PathIntersectionGraph::_handleNonintersectingPaths(PathVector &result, int which, bool inside) +void PathIntersectionGraph::_handleNonintersectingPaths(PathVector &result, unsigned which, bool inside) { /* Every component that has any intersections will be processed by _getResult. * Here we take care of paths that don't have any intersections. They are either @@ -312,68 +426,53 @@ void PathIntersectionGraph::_handleNonintersectingPaths(PathVector &result, int * evaluating the winding rule at the initial point. If inside is true and * the path is inside, we add it to the result. */ - boost::ptr_vector const &ls = which ? _bpaths : _apaths; - PathVector const &cur = which ? _b : _a; - PathVector const &other = which ? _a : _b; + unsigned w = which; + unsigned ow = (w+1) % 2; - for (std::size_t i = 0; i < cur.size(); ++i) { + for (std::size_t i = 0; i < _pv[w].size(); ++i) { // the path data vector might have been left empty if there were no intersections at all - bool has_path_data = !ls.empty(); + bool has_path_data = !_components[w].empty(); // Skip if the path has intersections - if (has_path_data && !ls[i].xlist.empty()) continue; + if (has_path_data && !_components[w][i].xlist.empty()) continue; bool path_inside = false; - // If the path had any intersections removed, use the result of that, - // since one of those might have been at the initial point. - // Also, it saves time. - if (has_path_data && ls[i].removed_in != 0) { + // Use the in/out determination from constructor, if available + if (has_path_data && _components[w][i].status == INSIDE) { path_inside = true; - } else if (has_path_data && ls[i].removed_out != 0) { + } else if (has_path_data && _components[w][i].status == OUTSIDE) { path_inside = false; } else { - int w = other.winding(cur[i].initialPoint()); - path_inside = w % 2 != 0; + int wdg = _pv[ow].winding(_pv[w][i].initialPoint()); + path_inside = wdg % 2 != 0; } if (path_inside == inside) { - result.push_back(cur[i]); + result.push_back(_pv[w][i]); } } } -bool PathIntersectionGraph::_findUnprocessed(IntersectionList::iterator &result) +PathIntersectionGraph::ILIter PathIntersectionGraph::_getNeighbor(ILIter iter) { - typedef IntersectionList::iterator Iter; - - Iter it, last; - - for (std::size_t k = 0; k < _apaths.size(); ++k) { - it = _apaths[k].xlist.begin(); - last = _apaths[k].xlist.end(); - for (; it != last; ++it) { - if (!it->_hook.is_linked()) { - // this intersection was removed since it did not change inside/outside status - continue; - } - if (!it->processed) { - result = it; - return true; - } - } - } - - return false; + unsigned ow = (iter->which + 1) % 2; + return _components[ow][iter->neighbor->pos.path_index].xlist.iterator_to(*iter->neighbor); } +PathIntersectionGraph::PathData & +PathIntersectionGraph::_getPathData(ILIter iter) +{ + return _components[iter->which][iter->pos.path_index]; +} std::ostream &operator<<(std::ostream &os, PathIntersectionGraph const &pig) { + typedef PathIntersectionGraph::IntersectionList::const_iterator CILIter; os << "Intersection graph:\n" << pig._xs.size()/2 << " total intersections\n" << pig.size() << " considered intersections\n"; - for (std::size_t i = 0; i < pig._apaths.size(); ++i) { - typedef PathIntersectionGraph::IntersectionList::const_iterator Iter; - for (Iter j = pig._apaths[i].xlist.begin(); j != pig._apaths[i].xlist.end(); ++j) { + for (std::size_t i = 0; i < pig._components[0].size(); ++i) { + PathIntersectionGraph::IntersectionList const &xl = pig._components[0][i].xlist; + for (CILIter j = xl.begin(); j != xl.end(); ++j) { os << j->pos << " - " << j->neighbor->pos << " @ " << j->p << "\n"; } } diff --git a/src/2geom/intersection-graph.h b/src/2geom/intersection-graph.h index bd9aaee81..332c83f18 100644 --- a/src/2geom/intersection-graph.h +++ b/src/2geom/intersection-graph.h @@ -58,23 +58,29 @@ public: /// Returns the number of intersections used when computing Boolean operations. std::size_t size() const; - std::vector intersectionPoints() const; + std::vector intersectionPoints(bool defective = false) const; + std::vector windingPoints() const { + return _winding_points; + } + void fragments(PathVector &in, PathVector &out) const; + bool valid() const { return _graph_valid; } private: enum InOutFlag { - POINT_INSIDE, - POINT_OUTSIDE + INSIDE, + OUTSIDE, + BOTH }; struct IntersectionVertex { boost::intrusive::list_member_hook<> _hook; + boost::intrusive::list_member_hook<> _proc_hook; PathVectorTime pos; Point p; // guarantees that endpoints are exact IntersectionVertex *neighbor; - bool entry; // going in +t direction enters the other path - InOutFlag previous; - InOutFlag next; - bool processed; // TODO: use intrusive unprocessed list instead + InOutFlag next_edge; + unsigned which; + bool defective; }; typedef boost::intrusive::list @@ -86,27 +92,50 @@ private: > > IntersectionList; + typedef boost::intrusive::list + < IntersectionVertex + , boost::intrusive::member_hook + < IntersectionVertex + , boost::intrusive::list_member_hook<> + , &IntersectionVertex::_proc_hook + > + > UnprocessedList; + struct PathData { IntersectionList xlist; - unsigned removed_in; - unsigned removed_out; - - PathData() - : removed_in(0) - , removed_out(0) + std::size_t path_index; + int which; + InOutFlag status; + + PathData(int w, std::size_t pi) + : path_index(pi) + , which(w) + , status(BOTH) {} }; struct IntersectionVertexLess; + typedef IntersectionList::iterator ILIter; + typedef IntersectionList::const_iterator CILIter; PathVector _getResult(bool enter_a, bool enter_b); - void _handleNonintersectingPaths(PathVector &result, int which, bool inside); - bool _findUnprocessed(IntersectionList::iterator &result); - - PathVector _a, _b; + void _handleNonintersectingPaths(PathVector &result, unsigned which, bool inside); + void _prepareArguments(); + bool _prepareIntersectionLists(Coord precision); + void _assignEdgeWindingParities(Coord precision); + void _assignComponentStatusFromDegenerateIntersections(); + void _removeDegenerateIntersections(); + void _verify(); + + ILIter _getNeighbor(ILIter iter); + PathData &_getPathData(ILIter iter); + + PathVector _pv[2]; boost::ptr_vector _xs; - boost::ptr_vector _apaths; - boost::ptr_vector _bpaths; + boost::ptr_vector _components[2]; + UnprocessedList _ulist; + bool _graph_valid; + std::vector _winding_points; friend std::ostream &operator<<(std::ostream &, PathIntersectionGraph const &); }; diff --git a/src/2geom/line.cpp b/src/2geom/line.cpp index bada8ef38..ee2edeba7 100644 --- a/src/2geom/line.cpp +++ b/src/2geom/line.cpp @@ -235,6 +235,20 @@ Coord Line::timeAt(Point const &p) const } } +/** @brief Create a transformation that maps one line to another. + * This will return a transformation \f$A\f$ such that + * \f$L_1(t) \cdot A = L_2(t)\f$, where \f$L_1\f$ is this line + * and \f$L_2\f$ is the line passed as the parameter. The returned + * transformation will preserve angles. */ +Affine Line::transformTo(Line const &other) const +{ + Affine result = Translate(-_initial); + result *= Rotate(angle_between(versor(), other.versor())); + result *= Scale(other.versor().length() / versor().length()); + result *= Translate(other._initial); + return result; +} + std::vector Line::intersect(Line const &other) const { std::vector result; diff --git a/src/2geom/line.h b/src/2geom/line.h index 7d4766e12..8a66d4472 100644 --- a/src/2geom/line.h +++ b/src/2geom/line.h @@ -359,6 +359,8 @@ public: Affine m = rotationToZero(other_dimension(d)); return m; } + + Affine transformTo(Line const &other) const; /// @} std::vector intersect(Line const &other) const; diff --git a/src/2geom/linear.h b/src/2geom/linear.h index b0306fb9f..316ed8639 100644 --- a/src/2geom/linear.h +++ b/src/2geom/linear.h @@ -5,8 +5,9 @@ * Authors: * Nathan Hurst * Michael Sloan + * Krzysztof Kosiński * - * Copyright (C) 2006-2007 authors + * Copyright (C) 2006-2015 authors * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public @@ -38,14 +39,6 @@ #include <2geom/interval.h> #include <2geom/math-utils.h> -//#define USE_SBASIS_OF - -#ifdef USE_SBASIS_OF - -#include "linear-of.h" - -#else - namespace Geom { class SBasis; @@ -54,26 +47,31 @@ class SBasis; * @brief Function that interpolates linearly between two values. * @ingroup Fragments */ -class Linear { +class Linear + : boost::additive< Linear + , boost::arithmetic< Linear, Coord + , boost::equality_comparable< Linear + > > > +{ public: - double a[2]; + Coord a[2]; Linear() {a[0]=0; a[1]=0;} - Linear(double aa, double b) {a[0] = aa; a[1] = b;} - Linear(double aa) {a[0] = aa; a[1] = aa;} + Linear(Coord aa, Coord b) {a[0] = aa; a[1] = b;} + Linear(Coord aa) {a[0] = aa; a[1] = aa;} - double operator[](unsigned i) const { + Coord operator[](unsigned i) const { assert(i < 2); return a[i]; } - double &operator[](unsigned i) { + Coord &operator[](unsigned i) { assert(i < 2); return a[i]; } //IMPL: FragmentConcept - typedef double output_type; - bool isZero(double eps=EPSILON) const { return are_near(a[0], 0., eps) && are_near(a[1], 0., eps); } - bool isConstant(double eps=EPSILON) const { return are_near(a[0], a[1], eps); } + typedef Coord output_type; + bool isZero(Coord eps=EPSILON) const { return are_near(a[0], 0., eps) && are_near(a[1], 0., eps); } + bool isConstant(Coord eps=EPSILON) const { return are_near(a[0], a[1], eps); } bool isFinite() const { return IS_FINITE(a[0]) && IS_FINITE(a[1]); } Coord at0() const { return a[0]; } @@ -81,10 +79,10 @@ public: Coord at1() const { return a[1]; } Coord &at1() { return a[1]; } - double valueAt(double t) const { return lerp(t, a[0], a[1]); } - double operator()(double t) const { return valueAt(t); } + Coord valueAt(Coord t) const { return lerp(t, a[0], a[1]); } + Coord operator()(Coord t) const { return valueAt(t); } - // not very useful, but required for ShapeConcept + // not very useful, but required for FragmentConcept std::vector valueAndDerivatives(Coord t, unsigned n) { std::vector result(n+1, 0.0); result[0] = valueAt(t); @@ -107,6 +105,44 @@ public: double hat() const { return (a[1] + a[0])/2; } + + // addition of other Linears + Linear &operator+=(Linear const &other) { + a[0] += other.a[0]; + a[1] += other.a[1]; + return *this; + } + Linear &operator-=(Linear const &other) { + a[0] -= other.a[0]; + a[1] -= other.a[1]; + return *this; + } + + // + Linear &operator+=(Coord x) { + a[0] += x; a[1] += x; + return *this; + } + Linear &operator-=(Coord x) { + a[0] -= x; a[1] -= x; + return *this; + } + Linear &operator*=(Coord x) { + a[0] *= x; a[1] *= x; + return *this; + } + Linear &operator/=(Coord x) { + a[0] /= x; a[1] /= x; + return *this; + } + Linear operator-() const { + Linear ret(-a[0], -a[1]); + return ret; + } + + bool operator==(Linear const &other) const { + return a[0] == other.a[0] && a[1] == other.a[1]; + } }; inline Linear reverse(Linear const &a) { return Linear(a[1], a[0]); } @@ -115,64 +151,7 @@ inline Linear portion(Linear const &a, Coord from, Coord to) { return result; } -//IMPL: AddableConcept -inline Linear operator+(Linear const & a, Linear const & b) { - return Linear(a[0] + b[0], a[1] + b[1]); -} -inline Linear operator-(Linear const & a, Linear const & b) { - return Linear(a[0] - b[0], a[1] - b[1]); -} -inline Linear& operator+=(Linear & a, Linear const & b) { - a[0] += b[0]; a[1] += b[1]; - return a; -} -inline Linear& operator-=(Linear & a, Linear const & b) { - a[0] -= b[0]; a[1] -= b[1]; - return a; -} -//IMPL: OffsetableConcept -inline Linear operator+(Linear const & a, double b) { - return Linear(a[0] + b, a[1] + b); -} -inline Linear operator-(Linear const & a, double b) { - return Linear(a[0] - b, a[1] - b); -} -inline Linear& operator+=(Linear & a, double b) { - a[0] += b; a[1] += b; - return a; -} -inline Linear& operator-=(Linear & a, double b) { - a[0] -= b; a[1] -= b; - return a; -} -//IMPL: boost::EqualityComparableConcept -inline bool operator==(Linear const & a, Linear const & b) { - return a[0] == b[0] && a[1] == b[1]; -} -inline bool operator!=(Linear const & a, Linear const & b) { - return a[0] != b[0] || a[1] != b[1]; -} -//IMPL: ScalableConcept -inline Linear operator-(Linear const &a) { - return Linear(-a[0], -a[1]); -} -inline Linear operator*(Linear const & a, double b) { - return Linear(a[0]*b, a[1]*b); -} -inline Linear operator/(Linear const & a, double b) { - return Linear(a[0]/b, a[1]/b); -} -inline Linear operator*=(Linear & a, double b) { - a[0] *= b; a[1] *= b; - return a; -} -inline Linear operator/=(Linear & a, double b) { - a[0] /= b; a[1] /= b; - return a; -} - -} -#endif +} // end namespace Geom #endif //LIB2GEOM_SEEN_LINEAR_H diff --git a/src/2geom/path.cpp b/src/2geom/path.cpp index 871441751..2e2bce9f1 100644 --- a/src/2geom/path.cpp +++ b/src/2geom/path.cpp @@ -98,6 +98,24 @@ bool PathInterval::contains(PathTime const &pos) const { } } +PathInterval::size_type PathInterval::curveCount() const +{ + if (isDegenerate()) return 0; + if (_cross_start) { + if (_reverse) { + return _path_size - _to.curve_index + _from.curve_index + 1; + } else { + return _path_size - _from.curve_index + _to.curve_index + 1; + } + } else { + if (_reverse) { + return _from.curve_index - _to.curve_index + 1; + } else { + return _to.curve_index - _from.curve_index + 1; + } + } +} + PathTime PathInterval::inside(Coord min_dist) const { // If there is some node further than min_dist (in time coord) from the ends, @@ -220,25 +238,25 @@ PathInterval PathInterval::from_direction(PathTime const &from, PathTime const & Path::Path(Rect const &r) - : _curves(new Sequence()) + : _data(new PathData()) , _closing_seg(new ClosingSegment(r.corner(3), r.corner(0))) , _closed(true) , _exception_on_stitch(true) { for (unsigned i = 0; i < 3; ++i) { - _curves->push_back(new LineSegment(r.corner(i), r.corner(i+1))); + _data->curves.push_back(new LineSegment(r.corner(i), r.corner(i+1))); } - _curves->push_back(_closing_seg); + _data->curves.push_back(_closing_seg); } Path::Path(ConvexHull const &ch) - : _curves(new Sequence()) + : _data(new PathData()) , _closing_seg(new ClosingSegment(Point(), Point())) , _closed(true) , _exception_on_stitch(true) { if (ch.empty()) { - _curves->push_back(_closing_seg); + _data->curves.push_back(_closing_seg); return; } @@ -248,52 +266,52 @@ Path::Path(ConvexHull const &ch) Point last = ch.front(); for (std::size_t i = 1; i < ch.size(); ++i) { - _curves->push_back(new LineSegment(last, ch[i])); + _data->curves.push_back(new LineSegment(last, ch[i])); last = ch[i]; } - _curves->push_back(_closing_seg); + _data->curves.push_back(_closing_seg); _closed = true; } Path::Path(Circle const &c) - : _curves(new Sequence()) + : _data(new PathData()) , _closing_seg(NULL) , _closed(true) , _exception_on_stitch(true) { Point p1 = c.pointAt(0); Point p2 = c.pointAt(M_PI); - _curves->push_back(new EllipticalArc(p1, c.radius(), c.radius(), 0, false, true, p2)); - _curves->push_back(new EllipticalArc(p2, c.radius(), c.radius(), 0, false, true, p1)); + _data->curves.push_back(new EllipticalArc(p1, c.radius(), c.radius(), 0, false, true, p2)); + _data->curves.push_back(new EllipticalArc(p2, c.radius(), c.radius(), 0, false, true, p1)); _closing_seg = new ClosingSegment(p1, p1); - _curves->push_back(_closing_seg); + _data->curves.push_back(_closing_seg); } Path::Path(Ellipse const &e) - : _curves(new Sequence()) + : _data(new PathData()) , _closing_seg(NULL) , _closed(true) , _exception_on_stitch(true) { Point p1 = e.pointAt(0); Point p2 = e.pointAt(M_PI); - _curves->push_back(new EllipticalArc(p1, e.rays(), e.rotationAngle(), false, true, p2)); - _curves->push_back(new EllipticalArc(p2, e.rays(), e.rotationAngle(), false, true, p1)); + _data->curves.push_back(new EllipticalArc(p1, e.rays(), e.rotationAngle(), false, true, p2)); + _data->curves.push_back(new EllipticalArc(p2, e.rays(), e.rotationAngle(), false, true, p1)); _closing_seg = new ClosingSegment(p1, p1); - _curves->push_back(_closing_seg); + _data->curves.push_back(_closing_seg); } void Path::close(bool c) { if (c == _closed) return; - if (c && _curves->size() >= 2) { + if (c && _data->curves.size() >= 2) { // when closing, if last segment is linear and ends at initial point, // replace it with the closing segment - Sequence::iterator last = _curves->end() - 2; + Sequence::iterator last = _data->curves.end() - 2; if (last->isLineSegment() && last->finalPoint() == initialPoint()) { _closing_seg->setInitial(last->initialPoint()); - _curves->erase(last); + _data->curves.erase(last); } } _closed = c; @@ -302,27 +320,35 @@ void Path::close(bool c) void Path::clear() { _unshare(); - _curves->pop_back().release(); - _curves->clear(); + _data->curves.pop_back().release(); + _data->curves.clear(); _closing_seg->setInitial(Point(0, 0)); _closing_seg->setFinal(Point(0, 0)); - _curves->push_back(_closing_seg); + _data->curves.push_back(_closing_seg); _closed = false; } OptRect Path::boundsFast() const { OptRect bounds; - if (empty()) + if (empty()) { return bounds; + } + // if the path is not empty, we look for cached bounds + if (_data->fast_bounds) { + return _data->fast_bounds; + } + bounds = front().boundsFast(); const_iterator iter = begin(); - // the closing path segment can be ignored, because it will always lie within the bbox of the rest of the path + // the closing path segment can be ignored, because it will always + // lie within the bbox of the rest of the path if (iter != end()) { for (++iter; iter != end(); ++iter) { bounds.unionWith(iter->boundsFast()); } } + _data->fast_bounds = bounds; return bounds; } @@ -377,11 +403,11 @@ bool Path::operator==(Path const &other) const return true; if (_closed != other._closed) return false; - return *_curves == *other._curves; + return _data->curves == other._data->curves; } void Path::start(Point const &p) { - if (_curves->size() > 1) { + if (_data->curves.size() > 1) { clear(); } _closing_seg->setInitial(p); @@ -442,86 +468,106 @@ std::vector Path::roots(Coord v, Dim2 d) const // Instead of O(N^2), this takes O(N + X), where X is the number of overlaps // between the bounding boxes of curves. -struct CurveSweepTraits { - struct Bound { - Rect r; +struct CurveIntersectionSweepSet +{ +public: + struct CurveRecord { + boost::intrusive::list_member_hook<> _hook; + Curve const *curve; + Rect bounds; std::size_t index; - int which; + unsigned which; + + CurveRecord(Curve const *pc, std::size_t idx, unsigned w) + : curve(pc) + , bounds(curve->boundsFast()) + , index(idx) + , which(w) + {} }; - typedef std::less Compare; - inline static Coord entry_value(Bound const &b) { return b.r[X].min(); } - inline static Coord exit_value(Bound const &b) { return b.r[X].max(); } -}; -class CurveSweeper - : public Sweeper -{ -public: - CurveSweeper(Path const &a, Path const &b, std::vector &result, Coord prec) + typedef std::vector::const_iterator ItemIterator; + + CurveIntersectionSweepSet(std::vector &result, + Path const &a, Path const &b, Coord precision) : _result(result) - , _precision(prec) + , _precision(precision) + , _sweep_dir(X) { - for (std::size_t i = 0; i < a.size(); ++i) { - Bound bound; - bound.r = a[i].boundsFast(); - bound.index = i; - bound.which = 0; - insert(bound, &a[i]); + std::size_t asz = a.size(), bsz = b.size(); + _records.reserve(asz + bsz); + + for (std::size_t i = 0; i < asz; ++i) { + _records.push_back(CurveRecord(&a[i], i, 0)); } - for (std::size_t i = 0; i < b.size(); ++i) { - Bound bound; - bound.r = b[i].boundsFast(); - bound.index = i; - bound.which = 1; - insert(bound, &b[i]); + for (std::size_t i = 0; i < bsz; ++i) { + _records.push_back(CurveRecord(&b[i], i, 1)); } - } -protected: - void _enter(Record const &record) { - int which = record.bound.which; - - for (RecordList::iterator i = _active_items.begin(); i != _active_items.end(); ++i) { - // do not intersect in the same path - if (i->bound.which == which) continue; - // do not intersect if boxes do not overlap in Y - if (!record.bound.r[Y].intersects(i->bound.r[Y])) continue; - - std::vector cx; - int ia = record.bound.index; - int ib = i->bound.index; + OptRect abb = a.boundsFast() | b.boundsFast(); + if (abb && abb->height() > abb->width()) { + _sweep_dir = Y; + } + } - if (which == 0) { - cx = record.item->intersect(*i->item, _precision); - } else { - cx = i->item->intersect(*record.item, _precision); - std::swap(ia, ib); - } + std::vector const &items() { return _records; } + Interval itemBounds(ItemIterator ii) { + return ii->bounds[_sweep_dir]; + } - for (std::size_t ci = 0; ci < cx.size(); ++ci) { - PathTime a(ia, cx[ci].first), b(ib, cx[ci].second); - PathIntersection px(a, b, cx[ci].point()); - _result.push_back(px); + void addActiveItem(ItemIterator ii) { + unsigned w = ii->which; + unsigned ow = (w+1) % 2; + + _active[w].push_back(const_cast(*ii)); + + for (ActiveCurveList::iterator i = _active[ow].begin(); i != _active[ow].end(); ++i) { + if (!ii->bounds.intersects(i->bounds)) continue; + std::vector cx = ii->curve->intersect(*i->curve, _precision); + for (std::size_t k = 0; k < cx.size(); ++k) { + PathTime tw(ii->index, cx[k].first), tow(i->index, cx[k].second); + _result.push_back(PathIntersection( + w == 0 ? tw : tow, + w == 0 ? tow : tw, + cx[k].point())); } } } + void removeActiveItem(ItemIterator ii) { + ActiveCurveList &acl = _active[ii->which]; + acl.erase(acl.iterator_to(*ii)); + } private: + typedef boost::intrusive::list + < CurveRecord + , boost::intrusive::member_hook + < CurveRecord + , boost::intrusive::list_member_hook<> + , &CurveRecord::_hook + > + > ActiveCurveList; + + std::vector _records; std::vector &_result; + ActiveCurveList _active[2]; Coord _precision; + Dim2 _sweep_dir; }; std::vector Path::intersect(Path const &other, Coord precision) const { std::vector result; - CurveSweeper sweeper(*this, other, result, precision); + CurveIntersectionSweepSet cisset(result, *this, other, precision); + Sweeper sweeper(cisset); sweeper.process(); // preprocessing to remove duplicate intersections at endpoints + std::size_t asz = size(), bsz = other.size(); for (std::size_t i = 0; i < result.size(); ++i) { - result[i].first.normalizeForward(size()); - result[i].second.normalizeForward(other.size()); + result[i].first.normalizeForward(asz); + result[i].second.normalizeForward(bsz); } std::sort(result.begin(), result.end()); result.erase(std::unique(result.begin(), result.end()), result.end()); @@ -672,7 +718,7 @@ PathTime Path::nearestTime(Point const &p, Coord *dist) const Coord mindist = std::numeric_limits::max(); PathTime ret; - if (_curves->size() == 1) { + if (_data->curves.size() == 1) { // naked moveto ret.curve_index = 0; ret.t = 0; @@ -701,6 +747,16 @@ PathTime Path::nearestTime(Point const &p, Coord *dist) const return ret; } +std::vector Path::nodes() const +{ + std::vector result; + size_type path_size = size_closed(); + for (size_type i = 0; i < path_size; ++i) { + result.push_back(_data->curves[i].initialPoint()); + } + return result; +} + void Path::appendPortionTo(Path &ret, double from, double to) const { if (!(from >= 0 && to >= 0)) { @@ -797,16 +853,16 @@ Path Path::reversed() const Path ret(finalPoint()); if (empty()) return ret; - ret._curves->pop_back(); // this also deletes the closing segment from ret + ret._data->curves.pop_back(); // this also deletes the closing segment from ret - RIter iter(_includesClosingSegment() ? _curves->end() : _curves->end() - 1); - RIter rend(_curves->begin()); + RIter iter(_includesClosingSegment() ? _data->curves.end() : _data->curves.end() - 1); + RIter rend(_data->curves.begin()); if (_closed) { // when the path is closed, there are two cases: if (front().isLineSegment()) { // 1. initial segment is linear: it becomes the new closing segment. - rend = RIter(_curves->begin() + 1); + rend = RIter(_data->curves.begin() + 1); ret._closing_seg = new ClosingSegment(front().finalPoint(), front().initialPoint()); } else { // 2. initial segment is not linear: the closing segment becomes degenerate. @@ -820,9 +876,9 @@ Path Path::reversed() const } for (; iter != rend; ++iter) { - ret._curves->push_back(iter->reverse()); + ret._data->curves.push_back(iter->reverse()); } - ret._curves->push_back(ret._closing_seg); + ret._data->curves.push_back(ret._closing_seg); ret._closed = _closed; return ret; } @@ -896,10 +952,10 @@ void Path::replace(iterator first, iterator last, Path const &path) void Path::snapEnds(Coord precision) { if (!_closed) return; - if (_curves->size() > 1 && are_near(_closing_seg->length(precision), 0, precision)) { + if (_data->curves.size() > 1 && are_near(_closing_seg->length(precision), 0, precision)) { _unshare(); _closing_seg->setInitial(_closing_seg->finalPoint()); - (_curves->end() - 1)->setFinal(_closing_seg->finalPoint()); + (_data->curves.end() - 1)->setFinal(_closing_seg->finalPoint()); } } @@ -908,7 +964,7 @@ void Path::snapEnds(Coord precision) void Path::do_update(Sequence::iterator first, Sequence::iterator last, Sequence &source) { // TODO: handle cases where first > last in closed paths? - bool last_beyond_closing_segment = (last == _curves->end()); + bool last_beyond_closing_segment = (last == _data->curves.end()); // special case: // if do_update replaces the closing segment, we have to regenerate it @@ -916,7 +972,7 @@ void Path::do_update(Sequence::iterator first, Sequence::iterator last, Sequence if (first == last) return; // nothing to do // only removing some segments - if ((!_closed && first == _curves->begin()) || (!_closed && last == _curves->end() - 1) || last_beyond_closing_segment) { + if ((!_closed && first == _data->curves.begin()) || (!_closed && last == _data->curves.end() - 1) || last_beyond_closing_segment) { // just adjust the closing segment // do nothing } else if (first->initialPoint() != (last - 1)->finalPoint()) { @@ -927,17 +983,17 @@ void Path::do_update(Sequence::iterator first, Sequence::iterator last, Sequence } } else { // replacing - if (first == _curves->begin() && last == _curves->end()) { + if (first == _data->curves.begin() && last == _data->curves.end()) { // special case: replacing everything should work the same in open and closed curves - _curves->erase(_curves->begin(), _curves->end() - 1); + _data->curves.erase(_data->curves.begin(), _data->curves.end() - 1); _closing_seg->setFinal(source.front().initialPoint()); _closing_seg->setInitial(source.back().finalPoint()); - _curves->transfer(_curves->begin(), source.begin(), source.end(), source); + _data->curves.transfer(_data->curves.begin(), source.begin(), source.end(), source); return; } // stitch in front - if (!_closed && first == _curves->begin()) { + if (!_closed && first == _data->curves.begin()) { // not necessary to stitch in front } else if (first->initialPoint() != source.front().initialPoint()) { if (_exception_on_stitch) { @@ -947,7 +1003,7 @@ void Path::do_update(Sequence::iterator first, Sequence::iterator last, Sequence } // stitch at the end - if ((!_closed && last == _curves->end() - 1) || last_beyond_closing_segment) { + if ((!_closed && last == _data->curves.end() - 1) || last_beyond_closing_segment) { // repurpose the closing segment as the stitch segment // do nothing } else if (source.back().finalPoint() != (last - 1)->finalPoint()) { @@ -962,8 +1018,8 @@ void Path::do_update(Sequence::iterator first, Sequence::iterator last, Sequence if (last_beyond_closing_segment) { --last; } - _curves->erase(first, last); - _curves->transfer(first, source.begin(), source.end(), source); + _data->curves.erase(first, last); + _data->curves.transfer(first, source.begin(), source.end(), source); // adjust closing segment if (size_open() == 0) { @@ -978,7 +1034,7 @@ void Path::do_update(Sequence::iterator first, Sequence::iterator last, Sequence void Path::do_append(Curve *c) { - if (&_curves->front() == _closing_seg) { + if (&_data->curves.front() == _closing_seg) { _closing_seg->setFinal(c->initialPoint()); } else { // if we can't freely move the closing segment, we check whether @@ -994,20 +1050,20 @@ void Path::do_append(Curve *c) return; } } - _curves->insert(_curves->end() - 1, c); + _data->curves.insert(_data->curves.end() - 1, c); _closing_seg->setInitial(c->finalPoint()); } void Path::checkContinuity() const { - Sequence::const_iterator i = _curves->begin(), j = _curves->begin(); + Sequence::const_iterator i = _data->curves.begin(), j = _data->curves.begin(); ++j; - for (; j != _curves->end(); ++i, ++j) { + for (; j != _data->curves.end(); ++i, ++j) { if (i->finalPoint() != j->initialPoint()) { THROW_CONTINUITYERROR(); } } - if (_curves->front().initialPoint() != _curves->back().finalPoint()) { + if (_data->curves.front().initialPoint() != _data->curves.back().finalPoint()) { THROW_CONTINUITYERROR(); } } @@ -1040,6 +1096,16 @@ Piecewise > paths_to_pw(PathVector const &paths) return ret; } +bool are_near(Path const &a, Path const &b, Coord precision) +{ + if (a.size() != b.size()) return false; + + for (unsigned i = 0; i < a.size(); ++i) { + if (!a[i].isNear(b[i], precision)) return false; + } + return true; +} + std::ostream &operator<<(std::ostream &out, Path const &path) { SVGPathWriter pw; diff --git a/src/2geom/path.h b/src/2geom/path.h index 3ca43e0e5..3552ec43e 100644 --- a/src/2geom/path.h +++ b/src/2geom/path.h @@ -55,6 +55,11 @@ namespace PathInternal { typedef boost::ptr_vector Sequence; +struct PathData { + Sequence curves; + OptRect fast_bounds; +}; + template class BaseIterator : public boost::random_access_iterator_helper @@ -221,6 +226,7 @@ public: } size_type pathSize() const { return _path_size; } + size_type curveCount() const; private: PathTime _from, _to; @@ -316,6 +322,7 @@ class Path : boost::equality_comparable< Path > { public: + typedef PathInternal::PathData PathData; typedef PathInternal::Sequence Sequence; typedef PathInternal::BaseIterator iterator; typedef PathInternal::BaseIterator const_iterator; @@ -342,31 +349,31 @@ public: /// Construct an empty path starting at the specified point. explicit Path(Point const &p = Point()) - : _curves(new Sequence()) + : _data(new PathData()) , _closing_seg(new ClosingSegment(p, p)) , _closed(false) , _exception_on_stitch(true) { - _curves->push_back(_closing_seg); + _data->curves.push_back(_closing_seg); } /// Construct a path containing a range of curves. template Path(Iter first, Iter last, bool closed = false, bool stitch = false) - : _curves(new Sequence()) + : _data(new PathData()) , _closed(closed) , _exception_on_stitch(!stitch) { for (Iter i = first; i != last; ++i) { - _curves->push_back(i->duplicate()); + _data->curves.push_back(i->duplicate()); } - if (!_curves->empty()) { - _closing_seg = new ClosingSegment(_curves->back().finalPoint(), - _curves->front().initialPoint()); + if (!_data->curves.empty()) { + _closing_seg = new ClosingSegment(_data->curves.back().finalPoint(), + _data->curves.front().initialPoint()); } else { _closing_seg = new ClosingSegment(); } - _curves->push_back(_closing_seg); + _data->curves.push_back(_closing_seg); } /// Create a path from a rectangle. @@ -386,7 +393,7 @@ public: * @todo Add noexcept specifiers for C++11 */ void swap(Path &other) throw() { using std::swap; - swap(other._curves, _curves); + swap(other._data, _data); swap(other._closing_seg, _closing_seg); swap(other._closed, _closed); swap(other._exception_on_stitch, _exception_on_stitch); @@ -396,26 +403,26 @@ public: friend inline void swap(Path &a, Path &b) throw() { a.swap(b); } /** @brief Access a curve by index */ - Curve const &operator[](size_type i) const { return (*_curves)[i]; } + Curve const &operator[](size_type i) const { return _data->curves[i]; } /** @brief Access a curve by index */ - Curve const &at(size_type i) const { return _curves->at(i); } + Curve const &at(size_type i) const { return _data->curves.at(i); } /** @brief Access the first curve in the path. * Since the curve always contains at least a degenerate closing segment, * it is always safe to use this method. */ - Curve const &front() const { return _curves->front(); } + Curve const &front() const { return _data->curves.front(); } /// Alias for front(). - Curve const &initialCurve() const { return _curves->front(); } + Curve const &initialCurve() const { return _data->curves.front(); } /** @brief Access the last curve in the path. */ Curve const &back() const { return back_default(); } Curve const &back_open() const { - if (empty()) return _curves->back(); - return (*_curves)[_curves->size() - 2]; + if (empty()) return _data->curves.back(); + return _data->curves[_data->curves.size() - 2]; } Curve const &back_closed() const { return _closing_seg->isDegenerate() - ? (*_curves)[_curves->size() - 2] - : (*_curves)[_curves->size() - 1]; + ? _data->curves[_data->curves.size() - 2] + : _data->curves[_data->curves.size() - 1]; } Curve const &back_default() const { return _includesClosingSegment() @@ -436,13 +443,13 @@ public: iterator end_closed() { return iterator(*this, size_closed()); } /// Size without the closing segment, even if the path is closed. - size_type size_open() const { return _curves->size() - 1; } + size_type size_open() const { return _data->curves.size() - 1; } /** @brief Size with the closing segment, if it makes a difference. * If the closing segment is degenerate, i.e. its initial and final points * are exactly equal, then it is not included in this size. */ size_type size_closed() const { - return _closing_seg->isDegenerate() ? _curves->size() - 1 : _curves->size(); + return _closing_seg->isDegenerate() ? _data->curves.size() - 1 : _data->curves.size(); } /// Natural size of the path. @@ -452,7 +459,7 @@ public: /// Natural size of the path. size_type size() const { return size_default(); } - size_type max_size() const { return _curves->max_size() - 1; } + size_type max_size() const { return _data->curves.max_size() - 1; } /** @brief Check whether path is empty. * The path is empty if it contains only the closing segment, which according @@ -460,7 +467,7 @@ public: * containers, two empty paths are not necessarily identical, because the * degenerate closing segment may be at a different point, affecting the operation * of methods such as appendNew(). */ - bool empty() const { return (_curves->size() == 1); } + bool empty() const { return (_data->curves.size() == 1); } /// Check whether the path is closed. bool closed() const { return _closed; } @@ -497,8 +504,8 @@ public: Path &operator*=(T const &tr) { BOOST_CONCEPT_ASSERT((TransformConcept)); _unshare(); - for (std::size_t i = 0; i < _curves->size(); ++i) { - (*_curves)[i] *= tr; + for (std::size_t i = 0; i < _data->curves.size(); ++i) { + _data->curves[i] *= tr; } return *this; } @@ -570,6 +577,8 @@ public: PathTime nearestTime(Point const &p, Coord *dist = NULL) const; std::vector nearestTimePerCurve(Point const &p) const; + std::vector nodes() const; + void appendPortionTo(Path &p, Coord f, Coord t) const; /** @brief Append a subset of this path to another path. @@ -662,13 +671,13 @@ public: void setInitial(Point const &p) { _unshare(); _closed = false; - _curves->front().setInitial(p); + _data->curves.front().setInitial(p); _closing_seg->setFinal(p); } void setFinal(Point const &p) { _unshare(); _closed = false; - (*_curves)[size_open() - 1].setFinal(p); + _data->curves[size_open() - 1].setFinal(p); _closing_seg->setInitial(p); } @@ -804,10 +813,10 @@ public: private: static Sequence::iterator seq_iter(iterator const &iter) { - return iter.path->_curves->begin() + iter.index; + return iter.path->_data->curves.begin() + iter.index; } static Sequence::const_iterator seq_iter(const_iterator const &iter) { - return iter.path->_curves->begin() + iter.index; + return iter.path->_data->curves.begin() + iter.index; } // whether the closing segment is part of the path @@ -815,10 +824,13 @@ private: return _closed && !_closing_seg->isDegenerate(); } void _unshare() { - if (!_curves.unique()) { - _curves.reset(new Sequence(*_curves)); - _closing_seg = static_cast(&_curves->back()); + // Called before every mutation. + // Ensure we have our own copy of curve data and reset cached values + if (!_data.unique()) { + _data.reset(new PathData(*_data)); + _closing_seg = static_cast(&_data->curves.back()); } + _data->fast_bounds = OptRect(); } PathTime _factorTime(Coord t) const; @@ -828,7 +840,7 @@ private: // n.b. takes ownership of curve object void do_append(Curve *curve); - boost::shared_ptr _curves; + boost::shared_ptr _data; ClosingSegment *_closing_seg; bool _closed; bool _exception_on_stitch; @@ -841,6 +853,8 @@ inline Coord nearest_time(Point const &p, Path const &c) { return pt.curve_index + pt.t; } +bool are_near(Path const &a, Path const &b, Coord precision = EPSILON); + std::ostream &operator<<(std::ostream &out, Path const &path); } // end namespace Geom diff --git a/src/2geom/pathvector.cpp b/src/2geom/pathvector.cpp index bff201c71..28ab26237 100644 --- a/src/2geom/pathvector.cpp +++ b/src/2geom/pathvector.cpp @@ -35,6 +35,7 @@ #include <2geom/path.h> #include <2geom/pathvector.h> #include <2geom/svg-path-writer.h> +#include <2geom/sweeper.h> namespace Geom { @@ -133,19 +134,96 @@ void PathVector::snapEnds(Coord precision) } } -std::vector PathVector::intersect(PathVector const &other, Coord precision) const -{ - typedef PathVectorTime PVPos; - std::vector result; - for (std::size_t i = 0; i < size(); ++i) { - for (std::size_t j = 0; j < other.size(); ++j) { - std::vector xs = (*this)[i].intersect(other[j], precision); - for (std::size_t k = 0; k < xs.size(); ++k) { - PVIntersection pvx(PVPos(i, xs[k].first), PVPos(j, xs[k].second), xs[k].point()); - result.push_back(pvx); +// sweepline optimization +// this is very similar to CurveIntersectionSweepSet in path.cpp +// should probably be merged +class PathIntersectionSweepSet { +public: + struct PathRecord { + boost::intrusive::list_member_hook<> _hook; + Path const *path; + std::size_t index; + unsigned which; + + PathRecord(Path const &p, std::size_t i, unsigned w) + : path(&p) + , index(i) + , which(w) + {} + }; + + typedef std::vector::iterator ItemIterator; + + PathIntersectionSweepSet(std::vector &result, + PathVector const &a, PathVector const &b, Coord precision) + : _result(result) + , _precision(precision) + { + _records.reserve(a.size() + b.size()); + for (std::size_t i = 0; i < a.size(); ++i) { + _records.push_back(PathRecord(a[i], i, 0)); + } + for (std::size_t i = 0; i < b.size(); ++i) { + _records.push_back(PathRecord(b[i], i, 1)); + } + } + + std::vector &items() { return _records; } + + Interval itemBounds(ItemIterator ii) { + OptRect r = ii->path->boundsFast(); + return (*r)[X]; + } + + void addActiveItem(ItemIterator ii) { + unsigned w = ii->which; + unsigned ow = (ii->which + 1) % 2; + + for (ActivePathList::iterator i = _active[ow].begin(); i != _active[ow].end(); ++i) { + if (!ii->path->boundsFast().intersects(i->path->boundsFast())) continue; + std::vector px = ii->path->intersect(*i->path, _precision); + for (std::size_t k = 0; k < px.size(); ++k) { + PathVectorTime tw(ii->index, px[k].first), tow(i->index, px[k].second); + _result.push_back(PVIntersection( + w == 0 ? tw : tow, + w == 0 ? tow : tw, + px[k].point())); } } + _active[w].push_back(*ii); + } + + void removeActiveItem(ItemIterator ii) { + ActivePathList &apl = _active[ii->which]; + apl.erase(apl.iterator_to(*ii)); } + +private: + typedef boost::intrusive::list + < PathRecord + , boost::intrusive::member_hook + < PathRecord + , boost::intrusive::list_member_hook<> + , &PathRecord::_hook + > + > ActivePathList; + + std::vector &_result; + std::vector _records; + ActivePathList _active[2]; + Coord _precision; +}; + +std::vector PathVector::intersect(PathVector const &other, Coord precision) const +{ + std::vector result; + + PathIntersectionSweepSet pisset(result, *this, other, precision); + Sweeper sweeper(pisset); + sweeper.process(); + + std::sort(result.begin(), result.end()); + return result; } @@ -153,6 +231,7 @@ int PathVector::winding(Point const &p) const { int wind = 0; for (const_iterator i = begin(); i != end(); ++i) { + if (!i->boundsFast().contains(p)) continue; wind += i->winding(p); } return wind; @@ -201,6 +280,18 @@ std::vector PathVector::allNearestTimes(Point const &p, Coord *d return retval; } +std::vector PathVector::nodes() const +{ + std::vector result; + for (size_type i = 0; i < size(); ++i) { + size_type path_size = (*this)[i].size_closed(); + for (size_type j = 0; j < path_size; ++j) { + result.push_back((*this)[i][j].initialPoint()); + } + } + return result; +} + PathVectorTime PathVector::_factorTime(Coord t) const { PathVectorTime ret; diff --git a/src/2geom/pathvector.h b/src/2geom/pathvector.h index 108f2aa05..0cbe5bf52 100644 --- a/src/2geom/pathvector.h +++ b/src/2geom/pathvector.h @@ -272,6 +272,8 @@ public: boost::optional nearestTime(Point const &p, Coord *dist = NULL) const; std::vector allNearestTimes(Point const &p, Coord *dist = NULL) const; + std::vector nodes() const; + private: PathVectorTime _factorTime(Coord t) const; diff --git a/src/2geom/piecewise.h b/src/2geom/piecewise.h index a5a65a9fe..3a12671e0 100644 --- a/src/2geom/piecewise.h +++ b/src/2geom/piecewise.h @@ -222,7 +222,7 @@ class Piecewise { inline void setDomain(Interval dom) { if(empty()) return; /* dom can not be empty - if(dom.isEmpty()) { + if(dom.empty()) { cuts.clear(); segs.clear(); return; }*/ diff --git a/src/2geom/rect.cpp b/src/2geom/rect.cpp index 383e72c8e..5a821e9f9 100644 --- a/src/2geom/rect.cpp +++ b/src/2geom/rect.cpp @@ -30,9 +30,56 @@ */ #include <2geom/rect.h> +#include <2geom/transforms.h> namespace Geom { +Point align_factors(Align g) { + Point p; + switch (g) { + case ALIGN_XMIN_YMIN: + p[X] = 0.0; + p[Y] = 0.0; + break; + case ALIGN_XMID_YMIN: + p[X] = 0.5; + p[Y] = 0.0; + break; + case ALIGN_XMAX_YMIN: + p[X] = 1.0; + p[Y] = 0.0; + break; + case ALIGN_XMIN_YMID: + p[X] = 0.0; + p[Y] = 0.5; + break; + case ALIGN_XMID_YMID: + p[X] = 0.5; + p[Y] = 0.5; + break; + case ALIGN_XMAX_YMID: + p[X] = 1.0; + p[Y] = 0.5; + break; + case ALIGN_XMIN_YMAX: + p[X] = 0.0; + p[Y] = 1.0; + break; + case ALIGN_XMID_YMAX: + p[X] = 0.5; + p[Y] = 1.0; + break; + case ALIGN_XMAX_YMAX: + p[X] = 1.0; + p[Y] = 1.0; + break; + default: + break; + } + return p; +} + + /** @brief Transform the rectangle by an affine. * The result of the transformation might not be axis-aligned. The return value * of this operation will be the smallest axis-aligned rectangle containing @@ -49,6 +96,37 @@ Rect &Rect::operator*=(Affine const &m) { return *this; } +Affine Rect::transformTo(Rect const &viewport, Aspect const &aspect) const +{ + // 1. translate viewbox to origin + Geom::Affine total = Translate(-min()); + + // 2. compute scale + Geom::Point vdims = viewport.dimensions(); + Geom::Point dims = dimensions(); + Geom::Scale scale(vdims[X] / dims[X], vdims[Y] / dims[Y]); + + if (aspect.align == ALIGN_NONE) { + // apply non-uniform scale + total *= scale * Translate(viewport.min()); + } else { + double uscale = 0; + if (aspect.expansion == EXPANSION_MEET) { + uscale = std::min(scale[X], scale[Y]); + } else { + uscale = std::max(scale[X], scale[Y]); + } + scale = Scale(uscale); + + // compute offset for align + Geom::Point offset = vdims - dims * scale; + offset *= Scale(align_factors(aspect.align)); + total *= scale * Translate(viewport.min() + offset); + } + + return total; +} + Coord distanceSq(Point const &p, Rect const &rect) { double dx = 0, dy = 0; diff --git a/src/2geom/rect.h b/src/2geom/rect.h index 51daf6b5a..d86741476 100644 --- a/src/2geom/rect.h +++ b/src/2geom/rect.h @@ -47,6 +47,43 @@ namespace Geom { +/** Values for the parameter of preserveAspectRatio. + * See: http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute */ +enum Align { + ALIGN_NONE, + ALIGN_XMIN_YMIN, + ALIGN_XMID_YMIN, + ALIGN_XMAX_YMIN, + ALIGN_XMIN_YMID, + ALIGN_XMID_YMID, + ALIGN_XMAX_YMID, + ALIGN_XMIN_YMAX, + ALIGN_XMID_YMAX, + ALIGN_XMAX_YMAX +}; + +/** Values for the parameter of preserveAspectRatio. + * See: http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute */ +enum Expansion { + EXPANSION_MEET, + EXPANSION_SLICE +}; + +/// Convert an align specification to coordinate fractions. +Point align_factors(Align align); + +/** @brief Structure that specifies placement of within a viewport. + * Use this to create transformations that preserve aspect. */ +struct Aspect { + Align align; + Expansion expansion; + bool deferred; ///< for SVG compatibility + + Aspect(Align a = ALIGN_NONE, Expansion ex = EXPANSION_MEET) + : align(a), expansion(ex), deferred(false) + {} +}; + /** * @brief Axis aligned, non-empty rectangle. * @ingroup Primitives @@ -113,6 +150,16 @@ public: } /// @} + /// @name SVG viewbox functionality. + /// @{ + /** @brief Transform contents to viewport. + * Computes an affine that transforms the contents of this rectangle + * to the specified viewport. The aspect parameter specifies how to + * to the transformation (whether the aspect ratio of content + * should be kept and where it should be placed in the viewport). */ + Affine transformTo(Rect const &viewport, Aspect const &aspect = Aspect()) const; + /// @} + /// @name Operators /// @{ Rect &operator*=(Affine const &m); @@ -145,8 +192,14 @@ public: OptRect(OptIntRect const &r) : Base() { if (r) *this = Rect(*r); } - // actually, the only reason we have this class, instead of typedefing - // to GenericOptRect, are the above constructors + + Affine transformTo(Rect const &viewport, Aspect const &aspect = Aspect()) { + Affine ret = Affine::identity(); + if (empty()) return ret; + ret = (*this)->transformTo(viewport, aspect); + return ret; + } + bool operator==(OptRect const &other) const { return Base::operator==(other); } diff --git a/src/2geom/sbasis-curve.h b/src/2geom/sbasis-curve.h index affe7edc0..cfc4ee9a8 100644 --- a/src/2geom/sbasis-curve.h +++ b/src/2geom/sbasis-curve.h @@ -37,6 +37,7 @@ #define LIB2GEOM_SEEN_SBASIS_CURVE_H #include <2geom/curve.h> +#include <2geom/exception.h> #include <2geom/nearest-time.h> #include <2geom/sbasis-geometric.h> #include <2geom/transforms.h> @@ -131,6 +132,10 @@ public: if (!other) return false; return inner == other->inner; } + virtual bool isNear(Curve const &/*c*/, Coord /*eps*/) const { + THROW_NOTIMPLEMENTED(); + return false; + } virtual int degreesOfFreedom() const { return inner[0].degreesOfFreedom() + inner[1].degreesOfFreedom(); } diff --git a/src/2geom/sbasis-math.cpp b/src/2geom/sbasis-math.cpp index 896eb18a7..e9ee917de 100644 --- a/src/2geom/sbasis-math.cpp +++ b/src/2geom/sbasis-math.cpp @@ -34,9 +34,8 @@ //TODO: define a truncated compose(sb,sb, order) and extend it to pw. //TODO: in all these functions, compute 'order' according to 'tol'. +#include <2geom/d2.h> #include <2geom/sbasis-math.h> - -#include <2geom/d2-sbasis.h> #include #include //#define ZERO 1e-3 diff --git a/src/2geom/svg-path-parser.cpp b/src/2geom/svg-path-parser.cpp index b6e6da869..93694156d 100644 --- a/src/2geom/svg-path-parser.cpp +++ b/src/2geom/svg-path-parser.cpp @@ -1424,7 +1424,7 @@ _match: Point point = _pop_point(); bool sweep = _pop_flag(); bool large_arc = _pop_flag(); - double angle = deg_to_rad(_pop()); + double angle = rad_from_deg(_pop()); double ry = _pop(); double rx = _pop(); @@ -1530,7 +1530,7 @@ _again: Point point = _pop_point(); bool sweep = _pop_flag(); bool large_arc = _pop_flag(); - double angle = deg_to_rad(_pop()); + double angle = rad_from_deg(_pop()); double ry = _pop(); double rx = _pop(); diff --git a/src/2geom/svg-path-writer.cpp b/src/2geom/svg-path-writer.cpp index 1c40ba64e..c484a172b 100644 --- a/src/2geom/svg-path-writer.cpp +++ b/src/2geom/svg-path-writer.cpp @@ -150,7 +150,7 @@ void SVGPathWriter::arcTo(double rx, double ry, double angle, _setCommand('A'); _current_pars.push_back(rx); _current_pars.push_back(ry); - _current_pars.push_back(rad_to_deg(angle)); + _current_pars.push_back(deg_from_rad(angle)); _current_pars.push_back(large_arc ? 1. : 0.); _current_pars.push_back(sweep ? 1. : 0.); _current_pars.push_back(p[X]); diff --git a/src/2geom/sweeper.h b/src/2geom/sweeper.h index 8c4e182a6..b3c96455f 100644 --- a/src/2geom/sweeper.h +++ b/src/2geom/sweeper.h @@ -41,32 +41,24 @@ namespace Geom { -/** @brief Sweep traits class for interval bounds. - * @relates Sweeper - * @ingroup Utilities */ -struct IntervalSweepTraits { - typedef Interval Bound; - typedef std::less Compare; - inline static Coord entry_value(Bound const &b) { return b.min(); } - inline static Coord exit_value(Bound const &b) { return b.max(); } -}; +// exposition only +template +class SweepVector { +public: + typedef typename std::vector::const_iterator ItemIterator; -/** @brief Sweep traits class for rectangle bounds. - * @tparam D Which axis to use for sweeping - * @ingroup Utilities */ -template -struct RectSweepTraits { - typedef Rect Bound; - typedef std::less Compare; - inline static Coord entry_value(Bound const &b) { return b[D].min(); } - inline static Coord exit_value(Bound const &b) { return b[D].max(); } -}; + SweepVector(std::vector const &v) + : _items(v) + {} -template -struct BoundsFast { - Rect operator()(T const &item) const { - return item.boundsFast(); - } + std::vector const &items() { return _items; } + Interval itemBounds(ItemIterator ii) { return Interval(); } + + void addActiveItem(ItemIterator ii) {} + void removeActiveItem(ItemIterator ii) {} + +private: + std::vector const &_items; }; /** @brief Generic sweepline algorithm. @@ -77,13 +69,19 @@ struct BoundsFast { * the line starts intersecting their bounds, and removed when it completely * passes over them. * - * To use this, create a derived class and reimplement the _enter() - * and/or _leave() virtual functions, insert all the objects, - * and finally call process(). Inside _enter() and _leave(), the items that have - * their bounds intersected by the sweepline are available in a list called - * _active_items. This is an intrusive linked list, so you should access it using - * iterators. Do not add or remove items from it. You can specify the bound type - * and how it should be accessed by defining a custom SweepTraits class. + * To use this, create a class that exposes the following methods: + * - Range items() - returns a forward iterable range of items that will be swept. + * - Interval itemBounds(iterator i) - given an iterator from the above range, + * compute the bounding interval of the referenced item in the direction of sweep. + * - void addActiveItem(iterator i) - add an item to the active list. + * - void removeActiveItem(iterator i) - remove an item from the active list. + * + * Create the object, then instantiate this template with the above class + * as the template parameter, pass it the constructed object of the class, + * and call the process() method. + * + * A good choice for the active list is a Boost intrusive list, which allows + * you to get an iterator from a value in constant time. * * Look in path.cpp for example usage. * @@ -92,38 +90,17 @@ struct BoundsFast { * how to interpret them and how to sort the events * @ingroup Utilities */ -template +template class Sweeper { public: - /// Type of the item's boundary - usually this will be an Interval or Rect. - typedef typename SweepTraits::Bound Bound; - - Sweeper() {} - - /** @brief Insert a single item for sweeping. - * @param bound Boundary of the item, as defined in sweep traits - * @param item The item itself */ - void insert(Bound const &bound, Item const &item) { - assert(!(typename SweepTraits::Compare()( - SweepTraits::exit_value(bound), - SweepTraits::entry_value(bound)))); - _items.push_back(Record(bound, item)); - } - - /** @brief Insert a range of items using the supplied bounds functor. - * The bounds are computed from items using the supplied bounds functor. - * @param first Start of range - * @param last End of range (one-past-the-end iterator) - * @param f Bounds functor */ - template - void insert(Iter first, Iter last, BoundFunc f = BoundFunc()) { - for (; first != last; ++first) { - Bound b = f(*first); - assert(!(typename SweepTraits::Compare()( - SweepTraits::exit_value(b), - SweepTraits::entry_value(b)))); - _items.push_back(Record(b, *first)); - } + typedef typename SweepSet::ItemIterator Iter; + + explicit Sweeper(SweepSet &set) + : _set(set) + { + std::size_t sz = std::distance(set.items().begin(), set.items().end()); + _entry_events.reserve(sz); + _exit_events.reserve(sz); } /** @brief Process entry and exit events. @@ -131,109 +108,70 @@ public: * functions _enter() and _leave() according to the order of the boundaries * of each item. */ void process() { - if (_items.empty()) return; + if (_set.items().empty()) return; + + Iter last = _set.items().end(); + for (Iter i = _set.items().begin(); i != last; ++i) { + Interval b = _set.itemBounds(i); + // guard against NANs + assert(b.min() == b.min() && b.max() == b.max()); + _entry_events.push_back(Event(b.max(), i)); + _exit_events.push_back(Event(b.min(), i)); + } - typename SweepTraits::Compare cmp; + boost::make_heap(_entry_events); + boost::make_heap(_exit_events); - // we store the events in heaps, which is slightly more efficient - // than sorting them, since a heap requires linear time to construct - for (RecordIter i = _items.begin(); i != _items.end(); ++i) { - _entry_events.push_back(i); - _exit_events.push_back(i); - } - boost::make_heap(_entry_events, _entry_heap_compare); - boost::make_heap(_exit_events, _exit_heap_compare); - boost::pop_heap(_entry_events, _entry_heap_compare); - boost::pop_heap(_exit_events, _exit_heap_compare); - - RecordIter next_entry = _entry_events.back(); - RecordIter next_exit = _exit_events.back(); - _entry_events.pop_back(); - _exit_events.pop_back(); - - while (next_entry != _items.end() || next_exit != _items.end()) { - assert(next_exit != _items.end()); - - if (next_entry == _items.end() || - cmp(SweepTraits::exit_value(next_exit->bound), - SweepTraits::entry_value(next_entry->bound))) - { + Event next_entry = _get_next(_entry_events); + Event next_exit = _get_next(_exit_events); + + while (next_entry || next_exit) { + assert(next_exit); + + if (!next_entry || next_exit > next_entry) { // exit event - remove record from active list - _leave(*next_exit); - _active_items.erase(_active_items.iterator_to(*next_exit)); - if (!_exit_events.empty()) { - boost::pop_heap(_exit_events, _exit_heap_compare); - next_exit = _exit_events.back(); - _exit_events.pop_back(); - } else { - next_exit = _items.end(); - // we should end the loop after this happens - } + _set.removeActiveItem(next_exit.item); + next_exit = _get_next(_exit_events); } else { // entry event - add record to active list - _enter(*next_entry); - _active_items.push_back(*next_entry); - if (!_entry_events.empty()) { - boost::pop_heap(_entry_events, _entry_heap_compare); - next_entry = _entry_events.back(); - _entry_events.pop_back(); - } else { - next_entry = _items.end(); - } + _set.addActiveItem(next_entry.item); + next_entry = _get_next(_entry_events); } } - - assert(_active_items.empty()); } -protected: - /// The item and its sweepline boundary. - struct Record { - boost::intrusive::list_member_hook<> _hook; - Bound bound; - Item item; - - Record(Bound const &b, Item const &i) - : bound(b), item(i) +private: + struct Event + : boost::totally_ordered + { + Coord coord; + Iter item; + + Event(Coord c, Iter const &i) + : coord(c), item(i) + {} + Event() + : coord(nan("")), item() {} + bool operator<(Event const &other) const { return coord < other.coord; } + bool operator==(Event const &other) const { return coord == other.coord; } + operator bool() const { return !IS_NAN(coord); } }; - typedef typename std::vector::iterator RecordIter; - - typedef boost::intrusive::list - < Record - , boost::intrusive::member_hook - < Record - , boost::intrusive::list_member_hook<> - , &Record::_hook - > - > RecordList; - - /** @brief Enter an item record. - * Override this to process an item as it is about to enter the active list. - * When called, the passed record will not be part of the active list. */ - virtual void _enter(Record const &) {} - /** @brief Leave an item record. - * Override this to process an item as it is about to leave the active list. - * When called, the passed record will be part of the active list. */ - virtual void _leave(Record const &) {} - - /// The list of all item records undergoing sweeping. - std::vector _items; - /// The list of active item records. - RecordList _active_items; -private: - inline static bool _entry_heap_compare(RecordIter a, RecordIter b) { - typename SweepTraits::Compare cmp; - return cmp(SweepTraits::entry_value(b->bound), SweepTraits::entry_value(a->bound)); - } - inline static bool _exit_heap_compare(RecordIter a, RecordIter b) { - typename SweepTraits::Compare cmp; - return cmp(SweepTraits::exit_value(b->bound), SweepTraits::exit_value(a->bound)); + static Event _get_next(std::vector &heap) { + if (heap.empty()) { + Event e; + return e; + } + boost::pop_heap(heap); + Event ret = heap.back(); + heap.pop_back(); + return ret; } - std::vector _entry_events; - std::vector _exit_events; + SweepSet &_set; + std::vector _entry_events; + std::vector _exit_events; }; } // namespace Geom diff --git a/src/2geom/utils.h b/src/2geom/utils.h index bc0ad74b8..3e0dd4717 100644 --- a/src/2geom/utils.h +++ b/src/2geom/utils.h @@ -71,6 +71,30 @@ struct NullIterator void operator=(T const &v) {} }; +/** @brief Get the next iterator in the container with wrap-around. + * If the iterator would become the end iterator after incrementing, + * return the begin iterator instead. */ +template +Iter cyclic_next(Iter i, Container &c) { + ++i; + if (i == c.end()) { + i = c.begin(); + } + return i; +} + +/** @brief Get the previous iterator in the container with wrap-around. + * If the passed iterator is the begin iterator, return the iterator + * just before the end iterator instead. */ +template +Iter cyclic_prior(Iter i, Container &c) { + if (i == c.begin()) { + i = c.end(); + } + --i; + return i; +} + } // end namespace Geom #endif // LIB2GEOM_SEEN_UTILS_H diff --git a/src/2geom/viewbox.cpp b/src/2geom/viewbox.cpp deleted file mode 100644 index 69bd0c487..000000000 --- a/src/2geom/viewbox.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/** - * \file - * \brief Convenience class for SVG viewBox handling - *//* - * Authors: - * Krzysztof Kosiński - * - * Copyright (C) 2013 Authors - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - */ - -#include <2geom/transforms.h> -#include <2geom/viewbox.h> - -namespace Geom { - -/** Convert an align specification to coordinate fractions. */ -Point align_factors(Align g) { - Point p; - switch (g) { - case ALIGN_XMIN_YMIN: - p[X] = 0.0; - p[Y] = 0.0; - break; - case ALIGN_XMID_YMIN: - p[X] = 0.5; - p[Y] = 0.0; - break; - case ALIGN_XMAX_YMIN: - p[X] = 1.0; - p[Y] = 0.0; - break; - case ALIGN_XMIN_YMID: - p[X] = 0.0; - p[Y] = 0.5; - break; - case ALIGN_XMID_YMID: - p[X] = 0.5; - p[Y] = 0.5; - break; - case ALIGN_XMAX_YMID: - p[X] = 1.0; - p[Y] = 0.5; - break; - case ALIGN_XMIN_YMAX: - p[X] = 0.0; - p[Y] = 1.0; - break; - case ALIGN_XMID_YMAX: - p[X] = 0.5; - p[Y] = 1.0; - break; - case ALIGN_XMAX_YMAX: - p[X] = 1.0; - p[Y] = 1.0; - break; - default: - break; - } - return p; -} - -/** Obtain transformation from the viewbox to the specified viewport. */ -Affine ViewBox::transformTo(Geom::Rect const &viewport) const -{ - if (!_box) { - return Geom::Affine::identity(); - } - - // 1. translate viewbox to origin - Geom::Affine total = Translate(-_box->min()); - - // 2. compute scale - Geom::Point vdims = viewport.dimensions(); - Geom::Point bdims = _box->dimensions(); - Geom::Scale scale(vdims[X] / bdims[X], vdims[Y] / bdims[Y]); - - if (_align == ALIGN_NONE) { - // apply non-uniform scale - // = Scale(_box->dimensions()).inverse() * Scale(viewport.dimensions()) - total *= scale * Translate(viewport.min()); - } else { - double uscale = 0; - if (_expansion == EXPANSION_MEET) { - uscale = std::min(scale[X], scale[Y]); - } else { - uscale = std::max(scale[X], scale[Y]); - } - scale = Scale(uscale); - - // compute offset for align - Geom::Point offset = bdims * scale - vdims; - offset *= Scale(align_factors(_align)); - total *= Translate(-offset); - } - - return total; -} - -} // namespace Geom - -/* - 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/2geom/viewbox.h b/src/2geom/viewbox.h deleted file mode 100644 index 81f59ee36..000000000 --- a/src/2geom/viewbox.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * \file - * \brief Convenience class for SVG viewBox handling - *//* - * Authors: - * Krzysztof Kosiński - * - * Copyright (C) 2013 Authors - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - */ - -#ifndef LIB2GEOM_SEEN_VIEWBOX_H -#define LIB2GEOM_SEEN_VIEWBOX_H - -#include <2geom/affine.h> -#include <2geom/rect.h> - -namespace Geom { - -/** Values for the parameter of preserveAspectRatio. - * See: http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute */ -enum Align { - ALIGN_NONE, - ALIGN_XMIN_YMIN, - ALIGN_XMID_YMIN, - ALIGN_XMAX_YMIN, - ALIGN_XMIN_YMID, - ALIGN_XMID_YMID, - ALIGN_XMAX_YMID, - ALIGN_XMIN_YMAX, - ALIGN_XMID_YMAX, - ALIGN_XMAX_YMAX -}; - -/** Values for the parameter of preserveAspectRatio. - * See: http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute */ -enum Expansion { - EXPANSION_MEET, - EXPANSION_SLICE -}; - -Point align_factors(Align align); - -class ViewBox { - OptRect _box; - Align _align; - Expansion _expansion; - -public: - explicit ViewBox(OptRect const &r = OptRect(), Align a = ALIGN_XMID_YMID, Expansion ex = EXPANSION_MEET) - : _box(r) - , _align(a) - , _expansion(ex) - {} - - void setBox(OptRect const &r) { _box = r; } - void setAlign(Align a) { _align = a; } - void setExpansion(Expansion ex) { _expansion = ex; } - OptRect const &box() const { return _box; } - Align align() const { return _align; } - Expansion expansion() const { return _expansion; } - - /** Obtain transformation from the viewbox to the specified viewport. */ - Affine transformTo(Geom::Rect const &viewport) const; -}; - -} // namespace Geom - -#endif // !LIB2GEOM_SEEN_VIEWBOX_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/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index 1794ccbab..14f36376f 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -172,9 +172,9 @@ CanvasAxonomGrid::CanvasAxonomGrid (SPNamedView * nv, Inkscape::XML::Node * in_r angle_deg[Z] = prefs->getDouble("/options/grids/axonom/angle_z", 30.0); angle_deg[Y] = 0; - angle_rad[X] = Geom::deg_to_rad(angle_deg[X]); + angle_rad[X] = Geom::rad_from_deg(angle_deg[X]); tan_angle[X] = tan(angle_rad[X]); - angle_rad[Z] = Geom::deg_to_rad(angle_deg[Z]); + angle_rad[Z] = Geom::rad_from_deg(angle_deg[Z]); tan_angle[Z] = tan(angle_rad[Z]); snapper = new CanvasAxonomGridSnapper(this, &namedview->snap_manager, 0); @@ -272,7 +272,7 @@ CanvasAxonomGrid::readRepr() angle_deg[X] = g_ascii_strtod(value, NULL); if (angle_deg[X] < 0.) angle_deg[X] = 0.; if (angle_deg[X] > 89.0) angle_deg[X] = 89.0; - angle_rad[X] = Geom::deg_to_rad(angle_deg[X]); + angle_rad[X] = Geom::rad_from_deg(angle_deg[X]); tan_angle[X] = tan(angle_rad[X]); } @@ -280,7 +280,7 @@ CanvasAxonomGrid::readRepr() angle_deg[Z] = g_ascii_strtod(value, NULL); if (angle_deg[Z] < 0.) angle_deg[Z] = 0.; if (angle_deg[Z] > 89.0) angle_deg[Z] = 89.0; - angle_rad[Z] = Geom::deg_to_rad(angle_deg[Z]); + angle_rad[Z] = Geom::rad_from_deg(angle_deg[Z]); tan_angle[Z] = tan(angle_rad[Z]); } diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index dec5b1f57..8591be7eb 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -200,7 +200,7 @@ void Filter::area_enlarge(Geom::IntRect &bbox, Inkscape::DrawingItem const *item Geom::Rect item_bbox; Geom::OptRect maybe_bbox = item->itemBounds(); - if (maybe_bbox.isEmpty()) { + if (maybe_bbox.empty()) { // Code below needs a bounding box return; } diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 9f2d030d4..7b4c0ac20 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -379,7 +379,7 @@ SPGradient *sp_gradient_reset_to_userspace(SPGradient *gr, SPItem *item) if (angle != 0.0) { - Geom::Line grl(center, Geom::deg_to_rad(angle)); + Geom::Line grl(center, Geom::rad_from_deg(angle)); Geom::LineSegment bbl1(bbox->corner(0), bbox->corner(1)); Geom::LineSegment bbl2(bbox->corner(1), bbox->corner(2)); Geom::LineSegment bbl3(bbox->corner(2), bbox->corner(3)); diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 874e23c4c..d7c0b69a4 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -199,7 +199,7 @@ KnotHolderEntityWidthBendPath::knot_set(Geom::Point const &p, Geom::Point const& if (cubic) { ray.setPoints(ptA, (*cubic)[1]); } - ray.setAngle(ray.angle() + Geom::deg_to_rad(90)); + ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); Geom::Point knot_pos = this->knot->pos * item->i2dt_affine().inverse(); Geom::Coord nearest_to_ray = ray.nearestTime(knot_pos); if(nearest_to_ray == 0){ @@ -225,7 +225,7 @@ KnotHolderEntityWidthBendPath::knot_get() const if (cubic) { ray.setPoints(ptA,(*cubic)[1]); } - ray.setAngle(ray.angle() + Geom::deg_to_rad(90)); + ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA; bp_helper_path.clear(); diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index fd9b853d5..87d8f05a9 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -17,7 +17,6 @@ #include "live_effects/lpe-copy_rotate.h" #include <2geom/path.h> #include <2geom/transforms.h> -#include <2geom/d2-sbasis.h> #include <2geom/angle.h> #include "knot-holder-entity.h" @@ -107,8 +106,8 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) dir = unit_vector(B - A); // I first suspected the minus sign to be a bug in 2geom but it is // likely due to SVG's choice of coordinate system orientation (max) - start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; - rot_pos = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle; + start_pos = origin + dir * Rotate(-rad_from_deg(starting_angle)) * dist_angle_handle; + rot_pos = origin + dir * Rotate(-rad_from_deg(rotation_angle+starting_angle)) * dist_angle_handle; if(copiesTo360 ){ rot_pos = origin; } @@ -129,9 +128,9 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p } Piecewise > output; - Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); + Affine pre = Translate(-origin) * Rotate(-rad_from_deg(starting_angle)); for (int i = 0; i < num_copies; ++i) { - Rotate rot(-deg_to_rad(rotation_angle * i)); + Rotate rot(-rad_from_deg(rotation_angle * i)); Affine t = pre * rot * Translate(origin); output.concat(pwd2_in * t); } @@ -146,7 +145,7 @@ LPECopyRotate::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector((Geom::Point)origin); - hp.appendNew(origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle); + hp.appendNew(origin + dir * Rotate(-rad_from_deg(rotation_angle+starting_angle)) * dist_angle_handle); Geom::PathVector pathv; pathv.push_back(hp); hp_vec.push_back(pathv); @@ -188,7 +187,7 @@ KnotHolderEntityStartingAngle::knot_set(Geom::Point const &p, Geom::Point const // I first suspected the minus sign to be a bug in 2geom but it is // likely due to SVG's choice of coordinate system orientation (max) - lpe->starting_angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, s - lpe->origin))); + lpe->starting_angle.param_set_value(deg_from_rad(-angle_between(lpe->dir, s - lpe->origin))); if (state & GDK_SHIFT_MASK) { lpe->dist_angle_handle = L2(lpe->B - lpe->A); } else { @@ -208,7 +207,7 @@ KnotHolderEntityRotationAngle::knot_set(Geom::Point const &p, Geom::Point const // I first suspected the minus sign to be a bug in 2geom but it is // likely due to SVG's choice of coordinate system orientation (max) - lpe->rotation_angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, s - lpe->origin)) - lpe->starting_angle); + lpe->rotation_angle.param_set_value(deg_from_rad(-angle_between(lpe->dir, s - lpe->origin)) - lpe->starting_angle); if (state & GDK_SHIFT_MASK) { lpe->dist_angle_handle = L2(lpe->B - lpe->A); } else { diff --git a/src/live_effects/lpe-dynastroke.cpp b/src/live_effects/lpe-dynastroke.cpp index c60db4fc4..aeecd5d5c 100644 --- a/src/live_effects/lpe-dynastroke.cpp +++ b/src/live_effects/lpe-dynastroke.cpp @@ -20,7 +20,6 @@ #include <2geom/bezier-to-sbasis.h> #include <2geom/sbasis-to-bezier.h> #include <2geom/d2.h> -#include <2geom/d2-sbasis.h> #include <2geom/sbasis-math.h> #include <2geom/piecewise.h> diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp index b1ad07d23..74c7efd90 100644 --- a/src/live_effects/lpe-interpolate.cpp +++ b/src/live_effects/lpe-interpolate.cpp @@ -16,7 +16,6 @@ #include <2geom/path.h> #include <2geom/sbasis-to-bezier.h> -#include <2geom/d2-sbasis.h> #include <2geom/piecewise.h> #include <2geom/sbasis-geometric.h> diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index bf84e645d..a033a6c4a 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -27,7 +27,6 @@ #include <2geom/sbasis-to-bezier.h> #include <2geom/sbasis.h> #include <2geom/d2.h> -#include <2geom/d2-sbasis.h> #include <2geom/path.h> #include <2geom/bezier-to-sbasis.h> #include <2geom/basic-intersection.h> diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index 706091be9..9397d848f 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -298,7 +298,7 @@ KnotHolderEntityWidthPatternAlongPath::knot_set(Geom::Point const &p, Geom::Poin if (cubic) { ray.setPoints(ptA, (*cubic)[1]); } - ray.setAngle(ray.angle() + Geom::deg_to_rad(90)); + ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); Geom::Point knot_pos = this->knot->pos * item->i2dt_affine().inverse(); Geom::Coord nearest_to_ray = ray.nearestTime(knot_pos); if(nearest_to_ray == 0){ @@ -327,7 +327,7 @@ KnotHolderEntityWidthPatternAlongPath::knot_get() const if (cubic) { ray.setPoints(ptA, (*cubic)[1]); } - ray.setAngle(ray.angle() + Geom::deg_to_rad(90)); + ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA; pap_helper_path.clear(); diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index a919756df..4b62c6c65 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -220,8 +220,8 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) } Geom::Ray ray1(point_at2, point_at3); Geom::Ray ray2(point_at3, point_at4); - double angle1 = Geom::rad_to_deg(ray1.angle()); - double angle2 = Geom::rad_to_deg(ray2.angle()); + double angle1 = Geom::deg_from_rad(ray1.angle()); + double angle2 = Geom::deg_from_rad(ray2.angle()); if((smooth_angles >= std::abs(angle2 - angle1)) && !are_near(point_at4,point_at3) && !are_near(point_at2,point_at3)) { double dist = Geom::distance(point_at2,point_at3); Geom::Angle angleFixed = ray2.angle(); diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index f2b756567..dd1a29689 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -46,7 +46,7 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : point_b(Geom::Point()), pathvector(), append_path(false), - previous_angle(Geom::deg_to_rad(0)), + previous_angle(Geom::rad_from_deg(0)), previous_start(Geom::Point()), previous_lenght(-1) { @@ -151,10 +151,10 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) } if(lock_lenght && !lock_angle && previous_lenght != -1) { Geom::Ray transformed((Geom::Point)start,(Geom::Point)end); - if(previous_start == start || previous_angle == Geom::deg_to_rad(0)) { + if(previous_start == start || previous_angle == Geom::rad_from_deg(0)) { previous_angle = transformed.angle(); } - } else if(lock_angle && !lock_lenght && previous_angle != Geom::deg_to_rad(0)) { + } else if(lock_angle && !lock_lenght && previous_angle != Geom::rad_from_deg(0)) { if(previous_start == start){ previous_lenght = Geom::distance((Geom::Point)start, (Geom::Point)end); } @@ -406,7 +406,7 @@ LPETransform2Pts::doEffect_pwd2 (Geom::Piecewise > const trans = (Geom::Point)end - helper.initialPoint(); } if(offset != 0){ - trans = Geom::Point::polar(transformed.angle() + Geom::deg_to_rad(-90),offset) + trans; + trans = Geom::Point::polar(transformed.angle() + Geom::rad_from_deg(-90),offset) + trans; } m *= Geom::Translate(trans); diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp index 399307502..117d57460 100644 --- a/src/live_effects/parameter/filletchamferpointarray.cpp +++ b/src/live_effects/parameter/filletchamferpointarray.cpp @@ -392,7 +392,7 @@ void FilletChamferPointArrayParam::updateCanvasIndicators() Geom::PathVector pathv = sp_svg_read_pathv(svgd); Geom::Affine aff = Geom::Affine(); aff *= Geom::Scale(helper_size); - aff *= Geom::Rotate(ray1.angle() - deg_to_rad(270)); + aff *= Geom::Rotate(ray1.angle() - rad_from_deg(270)); aff *= Geom::Translate(last_pwd2[i].valueAt(Xvalue)); pathv *= aff; hp.push_back(pathv[0]); diff --git a/src/selection.cpp b/src/selection.cpp index 020912381..6fc426be7 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -374,7 +374,7 @@ SPItem *Selection::_sizeistItem(bool sml, Selection::CompareSize compare) { for ( std::vector::const_iterator i=items.begin();i!=items.end(); ++i) { Geom::OptRect obox = SP_ITEM(*i)->desktopPreferredBounds(); - if (!obox || obox.isEmpty()) continue; + if (!obox || obox.empty()) continue; Geom::Rect bbox = *obox; gdouble size = compare == 2 ? bbox.area() : diff --git a/src/seltrans.cpp b/src/seltrans.cpp index f010a687d..b54525610 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -1195,7 +1195,7 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, Geom::P } // Update the status text - double degrees = mod360symm(Geom::rad_to_deg(radians)); + double degrees = mod360symm(Geom::deg_from_rad(radians)); _message_context.setF(Inkscape::IMMEDIATE_MESSAGE, // TRANSLATORS: don't modify the first ";" // (it will NOT be displayed as ";" - only the second one will be) @@ -1271,7 +1271,7 @@ gboolean Inkscape::SelTrans::rotateRequest(Geom::Point &pt, guint state) pt = _point * Geom::Translate(-_origin) * _relative_affine * Geom::Translate(_origin); // Update the status text - double degrees = mod360symm(Geom::rad_to_deg(radians)); + double degrees = mod360symm(Geom::deg_from_rad(radians)); _message_context.setF(Inkscape::IMMEDIATE_MESSAGE, // TRANSLATORS: don't modify the first ";" // (it will NOT be displayed as ";" - only the second one will be) diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index d1e101fd5..17a1a9ff1 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -501,7 +501,7 @@ char* SPGuide::description(bool const verbose) const descr = g_strdup_printf(_("horizontal, at %s"), position_string_y->str); } else { double const radians = this->angle(); - double const degrees = Geom::rad_to_deg(radians); + double const degrees = Geom::deg_from_rad(radians); int const degrees_int = (int) round(degrees); descr = g_strdup_printf(_("at %d degrees, through (%s,%s)"), degrees_int, position_string_x->str, position_string_y->str); diff --git a/src/svg/svg-affine.cpp b/src/svg/svg-affine.cpp index c853f9930..d9d79bba5 100644 --- a/src/svg/svg-affine.cpp +++ b/src/svg/svg-affine.cpp @@ -119,7 +119,7 @@ sp_svg_transform_read(gchar const *str, Geom::Affine *transform) if (n_args != 1 && n_args != 3) { return false; } - Geom::Rotate const rot(Geom::deg_to_rad(args[0])); + Geom::Rotate const rot(Geom::rad_from_deg(args[0])); if (n_args == 3) { a = ( Geom::Translate(-args[1], -args[2]) * rot diff --git a/src/svg/svg-path.cpp b/src/svg/svg-path.cpp index ba9e11452..7bb58fc9c 100644 --- a/src/svg/svg-path.cpp +++ b/src/svg/svg-path.cpp @@ -84,7 +84,7 @@ static void sp_svg_write_curve(Inkscape::SVG::PathString & str, Geom::Curve cons } else if(Geom::EllipticalArc const *elliptical_arc = dynamic_cast(c)) { str.arcTo( elliptical_arc->ray(Geom::X), elliptical_arc->ray(Geom::Y), - Geom::rad_to_deg(elliptical_arc->rotationAngle()), + Geom::deg_from_rad(elliptical_arc->rotationAngle()), elliptical_arc->largeArc(), elliptical_arc->sweep(), elliptical_arc->finalPoint() ); } else { diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index e0efcde36..556d77a28 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -98,7 +98,7 @@ void GuidelinePropertiesDialog::_onOK() } else if ( deg_angle == 0. || deg_angle == 180. || deg_angle == -180.) { normal = Geom::Point(0.,1.); } else { - double rad_angle = Geom::deg_to_rad( deg_angle ); + double rad_angle = Geom::rad_from_deg( deg_angle ); normal = Geom::rot90(Geom::Point::polar(rad_angle, 1.0)); } //To allow reposition from dialog @@ -326,7 +326,7 @@ void GuidelinePropertiesDialog::_setup() { } else if (_guide->isHorizontal()) { _oldangle = 0; } else { - _oldangle = Geom::rad_to_deg( std::atan2( - _guide->getNormal()[Geom::X], _guide->getNormal()[Geom::Y] ) ); + _oldangle = Geom::deg_from_rad( std::atan2( - _guide->getNormal()[Geom::X], _guide->getNormal()[Geom::Y] ) ); } { diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 813b064aa..3d194191a 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -747,9 +747,9 @@ void MeasureTool::toGuides() } } setGuide(start,0,""); - setGuide(start,Geom::deg_to_rad(90),_("Start")); + setGuide(start,Geom::rad_from_deg(90),_("Start")); setGuide(end,0,_("End")); - setGuide(end,Geom::deg_to_rad(90),""); + setGuide(end,Geom::rad_from_deg(90),""); showCanvasItems(true); doc->ensureUpToDate(); DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add guides from measure tool")); @@ -808,9 +808,9 @@ void MeasureTool::toMarkDimension() 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); + start = start + Geom::Point::polar(ray.angle() + Geom::rad_from_deg(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); + end = end+ Geom::Point::polar(ray.angle() + Geom::rad_from_deg(90), -dimension_offset); guint32 color = 0x000000ff; setLine(start, end, true, color); Glib::ustring unit_name = prefs->getString("/tools/measure/unit"); @@ -827,7 +827,7 @@ void MeasureTool::toMarkDimension() 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); + setLabelText(totallength_str, middle, fontsize, Geom::rad_from_deg(180) - ray.angle(), color); g_free(totallength_str); doc->ensureUpToDate(); DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add global measure line")); @@ -967,7 +967,7 @@ void MeasureTool::setLabelText(const char *value, Geom::Point pos, double fontsi 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()); + pos += Geom::Point::polar(angle+ Geom::rad_from_deg(90), -bbox->height()); } if(measure_repr) { /* Create */ @@ -1244,7 +1244,7 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, bool to_phantom, start_p, end_p, fontsize); { - setMeasureCanvasText(true, precision, Geom::rad_to_deg(angle), fontsize, unit_name, angleDisplayPt, 0x337f337f, TEXT_ANCHOR_CENTER, to_item, to_phantom, measure_repr); + setMeasureCanvasText(true, precision, Geom::deg_from_rad(angle), fontsize, unit_name, angleDisplayPt, 0x337f337f, TEXT_ANCHOR_CENTER, to_item, to_phantom, measure_repr); } { @@ -1277,9 +1277,9 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, bool to_phantom, cross_number= g_strdup_printf(_("Crossing %u"), idx + 1); } if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true) && idx == 0) { - setGuide(desktop->doc2dt(intersections[idx]), angle + Geom::deg_to_rad(90), ""); + setGuide(desktop->doc2dt(intersections[idx]), angle + Geom::rad_from_deg(90), ""); } else { - setGuide(desktop->doc2dt(intersections[idx]), angle + Geom::deg_to_rad(90), cross_number); + setGuide(desktop->doc2dt(intersections[idx]), angle + Geom::rad_from_deg(90), cross_number); } g_free(cross_number); } diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index cceaca7cb..4149403ea 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -495,7 +495,7 @@ bool NodeTool::root_handler(GdkEvent* event) { // We will show a pre-snap indication for when the user adds a node through double-clicking // Adding a node will only work when a path has been selected; if that's not the case then snapping is useless - if (not this->desktop->selection->isEmpty()) { + if (!this->desktop->selection->isEmpty()) { if (!(event->motion.state & GDK_SHIFT_MASK)) { m.setup(this->desktop); Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE); @@ -678,7 +678,7 @@ void NodeTool::update_tip(GdkEvent *event) { } } g_assert(positions.size() == 2); - const double angle = Geom::rad_to_deg(Geom::Line(positions[0], positions[1]).angle()); + const double angle = Geom::deg_from_rad(Geom::Line(positions[0], positions[1]).angle()); nodestring = g_strdup_printf("%u of %u nodes selected, angle: %.2f°.", sz, total, angle); } else { -- cgit v1.2.3 From fc76cf0a83906341a647625ca2e53cd7a15f0b76 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 8 Feb 2016 21:48:06 +0100 Subject: Changed no end lifetime temporary canvas items to canvas items in measure tool (bzr r14640) --- src/ui/tools/measure-tool.cpp | 48 +++++++++++++++++++++++++++---------------- src/ui/tools/measure-tool.h | 4 ++-- 2 files changed, 32 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 3d194191a..dedea8fc1 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -275,7 +275,7 @@ void setMeasureItem(Geom::PathVector pathv, bool is_curve, bool markers, guint32 * @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 ¢er, Geom::Point const &end, Geom::Point const &anchor, double angle, bool to_phantom, std::vector &measure_phantom_items , std::vector &measure_tmp_items , Inkscape::XML::Node *measure_repr = NULL) +void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom::Point const &end, Geom::Point const &anchor, double angle, bool to_phantom, std::vector &measure_phantom_items , std::vector &measure_tmp_items , 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. @@ -313,10 +313,12 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom SPCtrlCurve *curve = ControlManager::getManager().createControlCurve(desktop->getTempGroup(), p1, p2, p3, p4, CTLINE_SECONDARY); if(to_phantom){ curve->rgba = 0x8888887f; - measure_phantom_items.push_back(desktop->add_temporary_canvasitem(SP_CANVAS_ITEM(curve), 0, true)); + measure_phantom_items.push_back(SP_CANVAS_ITEM(curve)); } else { - measure_tmp_items.push_back(desktop->add_temporary_canvasitem(SP_CANVAS_ITEM(curve), 0, true)); + measure_tmp_items.push_back(SP_CANVAS_ITEM(curve)); } + sp_canvas_item_move_to_z(SP_CANVAS_ITEM(curve), 0); + sp_canvas_item_show(SP_CANVAS_ITEM(curve)); if(measure_repr) { Geom::PathVector pathv; Geom::Path path; @@ -331,7 +333,7 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom } } -} // namespace +} // namespace MeasureTool::MeasureTool() : ToolBase(cursor_measure_xpm, 4, 4) @@ -388,11 +390,11 @@ MeasureTool::~MeasureTool() 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]); + sp_canvas_item_destroy(measure_tmp_items[idx]); } measure_tmp_items.clear(); for (size_t idx = 0; idx < measure_phantom_items.size(); ++idx) { - desktop->remove_temporary_canvasitem(measure_phantom_items[idx]); + sp_canvas_item_destroy(measure_phantom_items[idx]); } measure_phantom_items.clear(); } @@ -510,7 +512,7 @@ void MeasureTool::knotUngrabbedHandler(SPKnot */*knot*/, unsigned int state) } - +//todo: we need this function? void MeasureTool::finish() { this->enableGrDrag(false); @@ -763,11 +765,11 @@ void MeasureTool::toPhantom() } SPDocument *doc = desktop->getDocument(); for (size_t idx = 0; idx < measure_phantom_items.size(); ++idx) { - desktop->remove_temporary_canvasitem(measure_phantom_items[idx]); + sp_canvas_item_destroy(measure_phantom_items[idx]); } measure_phantom_items.clear(); for (size_t idx = 0; idx < measure_tmp_items.size(); ++idx) { - desktop->remove_temporary_canvasitem(measure_tmp_items[idx]); + sp_canvas_item_destroy(measure_tmp_items[idx]); } measure_tmp_items.clear(); showCanvasItems(false, false, true); @@ -1024,7 +1026,7 @@ 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]); + sp_canvas_item_destroy(measure_tmp_items[idx]); } measure_tmp_items.clear(); } @@ -1052,10 +1054,13 @@ void MeasureTool::setMeasureCanvasText(bool is_angle, double precision, double a canvas_tooltip->anchor_position = text_anchor; if(to_phantom){ canvas_tooltip->rgba_background = 0x4444447f; - measure_phantom_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0, false)); + measure_phantom_items.push_back(SP_CANVAS_ITEM(canvas_tooltip)); + sp_canvas_item_show(SP_CANVAS_ITEM(canvas_tooltip)); } else { - measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0, false)); + measure_tmp_items.push_back(SP_CANVAS_ITEM(canvas_tooltip)); + sp_canvas_item_show(SP_CANVAS_ITEM(canvas_tooltip)); } + if(to_item) { setLabelText(measure_str, position, fontsize, 0, background, measure_repr); } @@ -1080,10 +1085,12 @@ void MeasureTool::setMeasureCanvasItem(Geom::Point position, bool to_item, bool SP_CTRL(canvasitem)->moveto(position); if(to_phantom){ - measure_phantom_items.push_back(desktop->add_temporary_canvasitem(canvasitem, 0)); + measure_phantom_items.push_back(canvasitem); } else { - measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvasitem, 0)); + measure_tmp_items.push_back(canvasitem); } + sp_canvas_item_show(canvasitem); + sp_canvas_item_move_to_z(canvasitem, 0); if(to_item) { setPoint(position, measure_repr); @@ -1102,10 +1109,12 @@ void MeasureTool::setMeasureCanvasControlLine(Geom::Point start, Geom::Point end ctrl_line_type); control_line->rgba = color; if(to_phantom){ - measure_phantom_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); + measure_phantom_items.push_back(SP_CANVAS_ITEM(control_line)); } else { - measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); + measure_tmp_items.push_back(SP_CANVAS_ITEM(control_line)); } + sp_canvas_item_move_to_z(SP_CANVAS_ITEM(control_line), 0); + sp_canvas_item_show(SP_CANVAS_ITEM(control_line)); if(to_item) { setLine(start, end, @@ -1123,11 +1132,14 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, bool to_phantom, } writeMeasurePoint(start_p, true); writeMeasurePoint(end_p, false); - //clear previous temporary canvas items, we'll draw new ones + //clear previous 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]); + sp_canvas_item_destroy(measure_tmp_items[idx]); } measure_tmp_items.clear(); + //TODO:Calculate the measure area for current lenght and origin + // and use canvas->requestRedraw. In the calculation need a gap for outside text + // maybe this remove the trash lines on measure use 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); diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index 716e2cee8..f36578d38 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -75,8 +75,8 @@ private: gint dimension_offset; Geom::Point start_p; Geom::Point end_p; - std::vector measure_tmp_items; - std::vector measure_phantom_items; + std::vector measure_tmp_items; + std::vector measure_phantom_items; sigc::connection _knot_start_moved_connection; sigc::connection _knot_start_ungrabbed_connection; sigc::connection _knot_start_click_connection; -- cgit v1.2.3 From c9514c8b2801a5bcef7d6fbcfe8eec5b2ff49bbc Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Tue, 9 Feb 2016 03:13:32 +0100 Subject: Allow python extensions to get the list of selected nodes format : --selected-nodes=id:subpath:position cf https://bugs.launchpad.net/inkscape/+bug/171640 for a debug test extension Fixed bugs: - https://launchpad.net/bugs/171640 (bzr r14641) --- src/extension/implementation/script.cpp | 56 +++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 4a929fa08..4cb0c9b73 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -41,6 +41,11 @@ #include "ui/view/view.h" #include "xml/node.h" #include "xml/attribute-record.h" +#include "ui/tools/node-tool.h" +#include "ui/tool/multi-path-manipulator.h" +#include "ui/tool/path-manipulator.h" +#include "ui/tool/control-point-selection.h" + #include "path-prefix.h" @@ -309,9 +314,9 @@ bool Script::load(Inkscape::Extension::Extension *module) const gchar *interpretstr = child_repr->attribute("interpreter"); if (interpretstr != NULL) { std::string interpString = resolveInterpreterExecutable(interpretstr); - command.insert(command.end(), interpString); + command.push_back(interpString); } - command.insert(command.end(), solve_reldir(child_repr)); + command.push_back(solve_reldir(child_repr)); } if (!strcmp(child_repr->name(), INKSCAPE_EXTENSION_NS "helper_extension")) { helper_extension = child_repr->firstChild()->content(); @@ -694,9 +699,52 @@ void Script::effect(Inkscape::Extension::Effect *module, Glib::ustring selected_id; selected_id += "--id="; selected_id += (*x)->getId(); - params.insert(params.begin(), selected_id); + params.push_front(selected_id); } + {//add selected nodes + Inkscape::UI::Tools::NodeTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + } + } + + if(tool){ + Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; + for (Inkscape::UI::ControlPointSelection::iterator i = cps->begin(); i != cps->end(); ++i) { + Inkscape::UI::Node *node = dynamic_cast(*i); + if (node) { + std::string id = node->nodeList().subpathList().pm().item()->getId(); + + int sp = 0; + bool found_sp = false; + for(Inkscape::UI::SubpathList::iterator i = node->nodeList().subpathList().begin(); i != node->nodeList().subpathList().end(); ++i,++sp){ + if(&**i == &(node->nodeList())){ + found_sp = true; + break; + } + } + int nl=0; + bool found_nl = false; + for (Inkscape::UI::NodeList::iterator j = node->nodeList().begin(); j != node->nodeList().end(); ++j, ++nl){ + if(&*j==node){ + found_nl = true; + break; + } + } + std::ostringstream ss; + ss<< "--selected-nodes=" << id << ":" << sp << ":" << nl; + Glib::ustring selected = ss.str(); + + if(found_nl && found_sp)params.push_front(selected); + else g_warning("Something went wrong while trying to pass selected nodes to extension. Please report a bug."); + } + } + } + }//end add selected nodes + file_listener fileout; int data_read = execute(command, params, dc->_filename, fileout); fileout.toFile(tempfilename_out); @@ -1013,6 +1061,8 @@ int Script::execute (const std::list &in_command, } } + //for(int i=0;i Date: Tue, 9 Feb 2016 03:16:06 +0100 Subject: Fix CMake build broken by r14639 Fixed bugs: - https://launchpad.net/bugs/1543298 (bzr r14642) --- src/2geom/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/2geom/CMakeLists.txt b/src/2geom/CMakeLists.txt index 33f8baee6..97b47b630 100644 --- a/src/2geom/CMakeLists.txt +++ b/src/2geom/CMakeLists.txt @@ -71,7 +71,6 @@ set(2geom_SRC crossing.h curve.h curves.h - d2-sbasis.h d2.h ellipse.h elliptical-arc.h -- cgit v1.2.3 From 225c64ac7604b0d64c93702c723d52b7d53539e1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 10 Feb 2016 12:02:21 +0100 Subject: Remove artifacts when remove canvas items, for example in measure tool (bzr r14645) --- src/display/sp-canvas.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index f33428295..22765cb9d 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -419,7 +419,7 @@ static void redraw_if_visible(SPCanvasItem *item) int y1 = (int)(item->y2); if (x0 !=0 || x1 !=0 || y0 !=0 || y1 !=0) { - item->canvas->requestRedraw((int)(item->x1), (int)(item->y1), (int)(item->x2 + 1), (int)(item->y2 + 1)); + item->canvas->requestRedraw((int)(item->x1 - 1), (int)(item->y1 -1), (int)(item->x2 + 1), (int)(item->y2 + 1)); } } } -- cgit v1.2.3 From b2eba12ae847ce5ba16e456fd156231cd200b644 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 11 Feb 2016 16:16:11 +0100 Subject: Fix a bug on explicit_base on meassure tool when using knots dialog to change position (bzr r14646) --- src/ui/tools/measure-tool.cpp | 22 +++++++++++++--------- src/ui/tools/measure-tool.h | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index dedea8fc1..a2a440ef4 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -335,6 +335,8 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom } // namespace +boost::optional explicit_base_tmp = boost::none; + MeasureTool::MeasureTool() : ToolBase(cursor_measure_xpm, 4, 4) , grabbed(NULL) @@ -369,7 +371,6 @@ MeasureTool::MeasureTool() 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_click_connection = this->knot_start->click_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotClickHandler)); this->_knot_start_ungrabbed_connection = this->knot_start->ungrabbed_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotUngrabbedHandler)); @@ -458,6 +459,7 @@ void MeasureTool::knotClickHandler(SPKnot *knot, guint state) SPDesktop *desktop = SP_ACTIVE_DESKTOP; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring const unit_name = prefs->getString("/tools/measure/unit"); + explicit_base = explicit_base_tmp; Inkscape::UI::Dialogs::KnotPropertiesDialog::showDialog(desktop, knot, unit_name); } } @@ -560,7 +562,8 @@ bool MeasureTool::root_handler(GdkEvent* event) this->knot_start->hide(); this->knot_end->hide(); Geom::Point const button_w(event->button.x, event->button.y); - explicitBase = boost::none; + explicit_base = boost::none; + explicit_base_tmp = boost::none; last_end = boost::none; start_p = desktop->w2d(button_w); @@ -585,7 +588,8 @@ bool MeasureTool::root_handler(GdkEvent* event) } case GDK_KEY_PRESS: { if ((event->key.keyval == GDK_KEY_Shift_L) || (event->key.keyval == GDK_KEY_Shift_R)) { - explicitBase = end_p; + explicit_base_tmp = explicit_base; + explicit_base = end_p; } break; } @@ -741,9 +745,9 @@ void MeasureTool::toGuides() return; } setGuide(start,ray.angle(), _("Measure")); - if(explicitBase) { - explicitBase = *explicitBase * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - ray.setPoints(start, *explicitBase); + if(explicit_base) { + explicit_base = *explicit_base * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + ray.setPoints(start, *explicit_base); if(ray.angle() != 0) { setGuide(start,ray.angle(), _("Base")); } @@ -1153,8 +1157,8 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, bool to_phantom, double angle = atan2(end_p - start_p); double baseAngle = 0; - if (explicitBase) { - baseAngle = atan2(explicitBase.get() - start_p); + if (explicit_base) { + baseAngle = atan2(explicit_base.get() - start_p); angle -= baseAngle; } @@ -1304,7 +1308,7 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, bool to_phantom, double length = std::abs((end_p - start_p).length()); Geom::Point anchorEnd = start_p; anchorEnd[Geom::X] += length; - if (explicitBase) { + if (explicit_base) { anchorEnd *= (Geom::Affine(Geom::Translate(-start_p)) * Geom::Affine(Geom::Rotate(baseAngle)) * Geom::Affine(Geom::Translate(start_p))); diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h index f36578d38..14fc9f81a 100644 --- a/src/ui/tools/measure-tool.h +++ b/src/ui/tools/measure-tool.h @@ -68,7 +68,7 @@ public: void knotUngrabbedHandler(SPKnot */*knot*/, unsigned int /*state*/); private: SPCanvasItem* grabbed; - boost::optional explicitBase; + boost::optional explicit_base; boost::optional last_end; SPKnot *knot_start; SPKnot *knot_end; -- cgit v1.2.3 From a3acbfd37562c86fa8eea07c223ab37d281e333c Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 11 Feb 2016 18:15:53 +0100 Subject: Fix default value of 'fr'. (bzr r14647) --- src/sp-radial-gradient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-radial-gradient.cpp b/src/sp-radial-gradient.cpp index 7175a8165..fa6355478 100644 --- a/src/sp-radial-gradient.cpp +++ b/src/sp-radial-gradient.cpp @@ -93,7 +93,7 @@ void SPRadialGradient::set(unsigned key, gchar const *value) { case SP_ATTR_FR: if (!this->fr.read(value)) { - this->fr.unset(SVGLength::PERCENT, 0.5, 0.5); + this->fr.unset(SVGLength::PERCENT, 0.0, 0.0); } this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; -- cgit v1.2.3 From 447b514a70131ba71e507c0ef4647b9101a57113 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Fri, 12 Feb 2016 09:52:13 -0500 Subject: if viewbox does not exist, create it from page size, only if page size exists. (Bug 1544016) Fixed bugs: - https://launchpad.net/bugs/1544016 (bzr r14648) --- src/file.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/file.cpp b/src/file.cpp index 7ae7d238a..9d390908e 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -142,7 +142,9 @@ SPDesktop *sp_file_new(const std::string &templ) } // Set viewBox if it doesn't exist - if (!doc->getRoot()->viewBox_set) { + if (!doc->getRoot()->viewBox_set + && (doc->getRoot()->width.unit != SVGLength::PERCENT) + && (doc->getRoot()->height.unit != SVGLength::PERCENT)) { DocumentUndo::setUndoSensitive(doc, false); doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); DocumentUndo::setUndoSensitive(doc, true); @@ -289,7 +291,9 @@ bool sp_file_open(const Glib::ustring &uri, if (doc) { // Set viewBox if it doesn't exist - if (!doc->getRoot()->viewBox_set) { + if (!doc->getRoot()->viewBox_set + && (doc->getRoot()->width.unit != SVGLength::PERCENT) + && (doc->getRoot()->height.unit != SVGLength::PERCENT)) { DocumentUndo::setUndoSensitive(doc, false); doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); DocumentUndo::setUndoSensitive(doc, true); -- cgit v1.2.3 From 710d4b83c310bd2fe9958aa22a9938b7ddb022a7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 13 Feb 2016 02:41:52 +0100 Subject: Improved eraser tool, now working on documents not pixels and with 0 width (bzr r14648.1.1) --- src/splivarot.cpp | 7 ++ src/splivarot.h | 1 + src/ui/tools/eraser-tool.cpp | 159 +++++++++++++++++++++-------------------- src/ui/tools/eraser-tool.h | 1 + src/widgets/eraser-toolbar.cpp | 6 +- 5 files changed, 92 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 9b2890bb8..461445ee0 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -105,6 +105,13 @@ sp_selected_path_cut(Inkscape::Selection *selection, SPDesktop *desktop) { sp_selected_path_boolop(selection, desktop, bool_op_cut, SP_VERB_SELECTION_CUT, _("Division")); } + +void +sp_selected_path_cut_skip_undo(Inkscape::Selection *selection, SPDesktop *desktop) +{ + sp_selected_path_boolop(selection, desktop, bool_op_cut, SP_VERB_NONE, _("Division")); +} + void sp_selected_path_slice(Inkscape::Selection *selection, SPDesktop *desktop) { diff --git a/src/splivarot.h b/src/splivarot.h index ba314399f..421c9c4b8 100644 --- a/src/splivarot.h +++ b/src/splivarot.h @@ -33,6 +33,7 @@ void sp_selected_path_diff (Inkscape::Selection *selection, SPDesktop *desktop); void sp_selected_path_diff_skip_undo (Inkscape::Selection *selection, SPDesktop *desktop); void sp_selected_path_symdiff (Inkscape::Selection *selection, SPDesktop *desktop); void sp_selected_path_cut (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_cut_skip_undo (Inkscape::Selection *selection, SPDesktop *desktop); void sp_selected_path_slice (Inkscape::Selection *selection, SPDesktop *desktop); // offset/inset of a curve diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp index 83ecf7a0a..51068a3ae 100644 --- a/src/ui/tools/eraser-tool.cpp +++ b/src/ui/tools/eraser-tool.cpp @@ -96,6 +96,7 @@ const std::string EraserTool::prefsPath = "/tools/eraser"; EraserTool::EraserTool() : DynamicBase(cursor_eraser_xpm, 4, 4) + , nowidth(false) { } @@ -145,6 +146,7 @@ static ProfileFloatElement f_profile[PROFILE_FLOAT_SIZE] = { sp_event_context_read(this, "cap_rounding"); this->is_drawing = false; + //TODO not sure why get 0.01 if slider width == 0, maybe a double/int problem Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/tools/eraser/selcue", 0) != 0) { @@ -339,7 +341,10 @@ void EraserTool::brush() { this->point1[this->npoints] = brush + del_left; this->point2[this->npoints] = brush - del_right; - + + if (this->nowidth) { + this->point1[this->npoints] = Geom::middle_point(this->point1[this->npoints],this->point2[this->npoints]); + } this->del = 0.5*(del_left + del_right); this->npoints++; @@ -489,33 +494,32 @@ bool EraserTool::root_handler(GdkEvent* event) { case GDK_KEY_PRESS: switch (get_group0_keyval (&event->key)) { - case GDK_KEY_Up: - case GDK_KEY_KP_Up: - if (!MOD__CTRL_ONLY(event)) { - this->angle += 5.0; - - if (this->angle > 90.0) { - this->angle = 90.0; - } - - sp_erc_update_toolbox (desktop, "eraser-angle", this->angle); - ret = TRUE; - } - break; - - case GDK_KEY_Down: - case GDK_KEY_KP_Down: - if (!MOD__CTRL_ONLY(event)) { - this->angle -= 5.0; - - if (this->angle < -90.0) { - this->angle = -90.0; - } - - sp_erc_update_toolbox (desktop, "eraser-angle", this->angle); - ret = TRUE; - } - break; +// case GDK_KEY_Up: +// case GDK_KEY_KP_Up: +// if (!MOD__CTRL_ONLY(event)) { +// this->angle += 5.0; + +// if (this->angle > 90.0) { +// this->angle = 90.0; +// } +// sp_erc_update_toolbox (desktop, "eraser-angle", this->angle); +// ret = TRUE; +// } +// break; + +// case GDK_KEY_Down: +// case GDK_KEY_KP_Down: +// if (!MOD__CTRL_ONLY(event)) { +// this->angle -= 5.0; + +// if (this->angle < -90.0) { +// this->angle = -90.0; +// } + +// sp_erc_update_toolbox (desktop, "eraser-angle", this->angle); +// ret = TRUE; +// } +// break; case GDK_KEY_Right: case GDK_KEY_KP_Right: @@ -640,20 +644,16 @@ void EraserTool::set_to_accumulated() { sp_desktop_apply_style_tool (desktop, repr, "/tools/eraser", false); this->repr = repr; - - SPItem *item=SP_ITEM(desktop->currentLayer()->appendChildRepr(this->repr)); - Inkscape::GC::release(this->repr); - - item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - item->updateRepr(); } - + SPItem *item=SP_ITEM(desktop->currentLayer()->appendChildRepr(this->repr)); + Inkscape::GC::release(this->repr); + item->updateRepr(); Geom::PathVector pathv = this->accumulated->get_pathvector() * desktop->dt2doc(); + pathv *= item->i2doc_affine().inverse(); gchar *str = sp_svg_write_path(pathv); g_assert( str != NULL ); this->repr->setAttribute("d", str); g_free(str); - if ( this->repr ) { bool wasSelection = false; Inkscape::Selection *selection = desktop->getSelection(); @@ -663,13 +663,12 @@ void EraserTool::set_to_accumulated() { Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); SPItem* acid = SP_ITEM(desktop->doc()->getObjectByRepr(this->repr)); - Geom::OptRect eraserBbox = acid->visualBounds(); - Geom::Rect bounds = (*eraserBbox) * desktop->doc2dt(); + Geom::OptRect eraserBbox = acid->desktopVisualBounds(); std::vector remainingItems; std::vector toWorkOn; if (selection->isEmpty()) { if ( eraserMode ) { - toWorkOn = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, bounds); + toWorkOn = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, *eraserBbox); } else { Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop); toWorkOn = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints()); @@ -684,30 +683,30 @@ void EraserTool::set_to_accumulated() { if ( eraserMode ) { for (std::vector::const_iterator i = toWorkOn.begin(); i != toWorkOn.end(); ++i){ SPItem *item = *i; - - if ( eraserMode ) { - Geom::OptRect bbox = item->visualBounds(); - - if (bbox && bbox->intersects(*eraserBbox)) { - Inkscape::XML::Node* dup = this->repr->duplicate(xml_doc); - this->repr->parent()->appendChild(dup); - Inkscape::GC::release(dup); // parent takes over - - selection->set(item); - selection->add(dup); + Geom::OptRect bbox = item->desktopVisualBounds(); + if (bbox && bbox->intersects(*eraserBbox)) { + Inkscape::XML::Node* dup = this->repr->duplicate(xml_doc); + this->repr->parent()->appendChild(dup); + Inkscape::GC::release(dup); // parent takes over + + selection->set(item); + selection->add(dup); + if (this->nowidth) { + sp_selected_path_cut_skip_undo(selection, desktop); + } else { sp_selected_path_diff_skip_undo(selection, desktop); - workDone = true; // TODO set this only if something was cut. - - if ( !selection->isEmpty() ) { - // If the item was not completely erased, track the new remainder. - std::vector nowSel(selection->itemList()); - for (std::vector::const_iterator i2 = nowSel.begin();i2!=nowSel.end();++i2) { - remainingItems.push_back(*i2); - } + } + workDone = true; // TODO set this only if something was cut. + + if ( !selection->isEmpty() ) { + // If the item was not completely erased, track the new remainder. + std::vector nowSel(selection->itemList()); + for (std::vector::const_iterator i2 = nowSel.begin();i2!=nowSel.end();++i2) { + remainingItems.push_back(*i2); } - } else { - remainingItems.push_back(item); } + } else { + remainingItems.push_back(item); } } } else { @@ -811,24 +810,25 @@ void EraserTool::accumulate() { g_assert( rev_cal2_lastseg ); this->accumulated->append(this->cal1, FALSE); - - add_cap(this->accumulated, - dc_cal1_lastseg->finalPoint() - dc_cal1_lastseg->unitTangentAt(1), - dc_cal1_lastseg->finalPoint(), - rev_cal2_firstseg->initialPoint(), - rev_cal2_firstseg->initialPoint() + rev_cal2_firstseg->unitTangentAt(0), - this->cap_rounding); - - this->accumulated->append(rev_cal2, TRUE); - - add_cap(this->accumulated, - rev_cal2_lastseg->finalPoint() - rev_cal2_lastseg->unitTangentAt(1), - rev_cal2_lastseg->finalPoint(), - dc_cal1_firstseg->initialPoint(), - dc_cal1_firstseg->initialPoint() + dc_cal1_firstseg->unitTangentAt(0), - this->cap_rounding); - - this->accumulated->closepath(); + if(!this->nowidth) { + add_cap(this->accumulated, + dc_cal1_lastseg->finalPoint() - dc_cal1_lastseg->unitTangentAt(1), + dc_cal1_lastseg->finalPoint(), + rev_cal2_firstseg->initialPoint(), + rev_cal2_firstseg->initialPoint() + rev_cal2_firstseg->unitTangentAt(0), + this->cap_rounding); + + this->accumulated->append(rev_cal2, TRUE); + + add_cap(this->accumulated, + rev_cal2_lastseg->finalPoint() - rev_cal2_lastseg->unitTangentAt(1), + rev_cal2_lastseg->finalPoint(), + dc_cal1_firstseg->initialPoint(), + dc_cal1_firstseg->initialPoint() + dc_cal1_firstseg->unitTangentAt(0), + this->cap_rounding); + + this->accumulated->closepath(); + } rev_cal2->unref(); @@ -844,6 +844,8 @@ static double square(double const x) void EraserTool::fit_and_split(bool release) { double const tolerance_sq = square( desktop->w2d().descrim() * TOLERANCE_ERASER ); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + this->nowidth = prefs->getDouble( "/tools/eraser/width", 1) == 0; #ifdef ERASER_VERBOSE g_print("[F&S:R=%c]", release?'T':'F'); @@ -940,7 +942,6 @@ void EraserTool::fit_and_split(bool release) { g_print("[%d]Yup\n", this->npoints); #endif if (!release) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0; g_assert(!this->currentcurve->is_empty()); diff --git a/src/ui/tools/eraser-tool.h b/src/ui/tools/eraser-tool.h index 110f57ba3..50ce6b6e3 100644 --- a/src/ui/tools/eraser-tool.h +++ b/src/ui/tools/eraser-tool.h @@ -58,6 +58,7 @@ private: void accumulate(); void fit_and_split(bool release); void draw_temporary_box(); + bool nowidth; }; } diff --git a/src/widgets/eraser-toolbar.cpp b/src/widgets/eraser-toolbar.cpp index 1f79b50f2..f18a805b2 100644 --- a/src/widgets/eraser-toolbar.cpp +++ b/src/widgets/eraser-toolbar.cpp @@ -122,14 +122,14 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb { /* Width */ - gchar const* labels[] = {_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")}; - gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; + gchar const* labels[] = {_("(no width)"),_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")}; + gdouble values[] = {0, 1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; EgeAdjustmentAction *eact = create_adjustment_action( "EraserWidthAction", _("Pen Width"), _("Width:"), _("The width of the eraser pen (relative to the visible canvas area)"), "/tools/eraser/width", 15, GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-eraser", - 1, 100, 1.0, 10.0, + 0, 100, 1.0, 10.0, labels, values, G_N_ELEMENTS(labels), sp_erc_width_value_changed, NULL /*unit tracker*/, 1, 0); ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); -- cgit v1.2.3 From 50addf8b79d80608e9a37999861f55a20cdf19ae Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Sun, 14 Feb 2016 18:35:49 +0100 Subject: Fix for bug 1478168 (CDR import crashes) Fixed bugs: - https://launchpad.net/bugs/1478168 (bzr r14650) --- src/extension/internal/cdr-input.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index f4789a08f..c8df804bc 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -22,6 +22,7 @@ #include #include +#include #include @@ -281,7 +282,12 @@ SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u } } - SPDocument * doc = SPDocument::createNewDocFromMem(tmpSVGOutput[page_num-1].cstr(), strlen(tmpSVGOutput[page_num-1].cstr()), TRUE); + // remove consecutive closepath commands (see bug 1492153) + Glib::RefPtr regex = Glib::Regex::create("(Z(?:[\n\s]+Z)+)(?=[^<]+\")"); + Glib::ustring outString1 = Glib::ustring(tmpSVGOutput[page_num-1].cstr()); + Glib::ustring outString2 = regex->replace(outString1, 0, "Z", Glib::REGEX_MATCH_NEWLINE_ANY); + + SPDocument * doc = SPDocument::createNewDocFromMem(outString2.c_str(), outString2.bytes(), TRUE); // Set viewBox if it doesn't exist if (doc && !doc->getRoot()->viewBox_set) { -- cgit v1.2.3 From 107052535c8abd107bb98ece0149f013687b7d10 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Sun, 14 Feb 2016 21:35:26 +0100 Subject: Fix improperly escaped character in previous commit (which actually fixes bug 1492153, sorry for the mix-up) Fixed bugs: - https://launchpad.net/bugs/1492153 (bzr r14651) --- src/extension/internal/cdr-input.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index c8df804bc..a4e26e224 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -283,7 +283,7 @@ SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u } // remove consecutive closepath commands (see bug 1492153) - Glib::RefPtr regex = Glib::Regex::create("(Z(?:[\n\s]+Z)+)(?=[^<]+\")"); + Glib::RefPtr regex = Glib::Regex::create("(Z(?:\\s+Z)+)(?=[^<]+\")"); Glib::ustring outString1 = Glib::ustring(tmpSVGOutput[page_num-1].cstr()); Glib::ustring outString2 = regex->replace(outString1, 0, "Z", Glib::REGEX_MATCH_NEWLINE_ANY); -- cgit v1.2.3 From 7f4a4369b9b0b97301690a32f1fd25f1161b41f3 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Mon, 15 Feb 2016 01:03:42 -0800 Subject: Sync 2Geom to e7245a01127647cd20b0d851a0a622d9ded38d23. Restores correct meaning of Line::versor(). (bzr r14652) --- src/2geom/circle.cpp | 8 ++++---- src/2geom/conicsec.cpp | 14 ++++++------- src/2geom/coord.cpp | 9 --------- src/2geom/ellipse.cpp | 2 +- src/2geom/generic-interval.h | 3 +-- src/2geom/generic-rect.h | 5 ++--- src/2geom/line.cpp | 38 +++++++++++++++++------------------ src/2geom/line.h | 41 ++++++++++++++++++++------------------ src/2geom/ray.h | 47 ++++++++++++++++++++++---------------------- src/2geom/sweeper.h | 12 +++++------ src/2geom/utils.h | 2 +- src/conn-avoid-ref.cpp | 4 ++-- 12 files changed, 89 insertions(+), 96 deletions(-) (limited to 'src') diff --git a/src/2geom/circle.cpp b/src/2geom/circle.cpp index 553981a72..934a8d3ab 100644 --- a/src/2geom/circle.cpp +++ b/src/2geom/circle.cpp @@ -144,7 +144,7 @@ bool Circle::contains(Circle const &other) const bool Circle::intersects(Line const &l) const { // http://mathworld.wolfram.com/Circle-LineIntersection.html - Coord dr = l.versor().length(); + Coord dr = l.vector().length(); Coord r = _radius; Coord D = cross(l.initialPoint(), l.finalPoint()); Coord delta = r*r * dr*dr - D*D; @@ -163,9 +163,9 @@ bool Circle::intersects(Circle const &other) const std::vector Circle::intersect(Line const &l) const { // http://mathworld.wolfram.com/Circle-LineIntersection.html - Coord dr = l.versor().length(); - Coord dx = l.versor().x(); - Coord dy = l.versor().y(); + Coord dr = l.vector().length(); + Coord dx = l.vector().x(); + Coord dy = l.vector().y(); Coord D = cross(l.initialPoint() - _center, l.finalPoint() - _center); Coord delta = _radius*_radius * dr*dr - D*D; diff --git a/src/2geom/conicsec.cpp b/src/2geom/conicsec.cpp index 089db71a4..2d396ba30 100644 --- a/src/2geom/conicsec.cpp +++ b/src/2geom/conicsec.cpp @@ -114,8 +114,8 @@ double RatQuad::lambda() const { RatQuad RatQuad::fromPointsTangents(Point P0, Point dP0, Point P, Point P2, Point dP2) { - Line Line0 = Line::from_origin_and_versor(P0, dP0); - Line Line2 = Line::from_origin_and_versor(P2, dP2); + Line Line0 = Line::from_origin_and_vector(P0, dP0); + Line Line2 = Line::from_origin_and_vector(P2, dP2); try { OptCrossing oc = intersection(Line0, Line2); if(!oc) // what to do? @@ -276,8 +276,8 @@ std::vector decompose_degenerate(xAx const & C1, xAx const & C2, xAx cons n1 = Point(b-d, 1); } - Line L0 = Line::from_origin_and_versor(B0, rot90(n0)); - Line L1 = Line::from_origin_and_versor(B0, rot90(n1)); + Line L0 = Line::from_origin_and_vector(B0, rot90(n0)); + Line L1 = Line::from_origin_and_vector(B0, rot90(n1)); std::vector rts = C1.roots(L0); for(unsigned i = 0; i < rts.size(); i++) { @@ -327,12 +327,12 @@ std::vector decompose_degenerate(xAx const & C1, xAx const & C2, xAx cons */ assert(L2sq(g) != 0); - Line Lx = Line::from_origin_and_versor(trial_pt, g); // a line along the gradient + Line Lx = Line::from_origin_and_vector(trial_pt, g); // a line along the gradient std::vector rts = xC0.roots(Lx); for(unsigned i = 0; i < rts.size(); i++) { Point P0 = Lx.pointAt(rts[i]); //std::cout << P0 << "\n"; - Line L = Line::from_origin_and_versor(P0, rot90(g)); + Line L = Line::from_origin_and_vector(P0, rot90(g)); std::vector cnrts; // It's very likely that at least one of the conics is degenerate, this will hopefully pick the more generate of the two. if(fabs(C1.hessian().det()) > fabs(C2.hessian().det())) @@ -515,7 +515,7 @@ xAx xAx::operator*(double const &b) const { if(L2sq(dA) <= 1e-10) { // perhaps a single point? return boost::optional (); } - LineSegment ls = intersection(Line::from_origin_and_versor(A, dA), bnd); + LineSegment ls = intersection(Line::from_origin_and_vector(A, dA), bnd); return RatQuad::fromPointsTangents(A, dA, ls.pointAt(0.5), ls[1], dA); } else if(crs.size() >= 2 && crs.size() < 4) { diff --git a/src/2geom/coord.cpp b/src/2geom/coord.cpp index 8b5e28586..8c7485883 100644 --- a/src/2geom/coord.cpp +++ b/src/2geom/coord.cpp @@ -111,12 +111,6 @@ namespace Geom { namespace { -inline int StrLength(const char* string) { - size_t length = strlen(string); - ASSERT(length == static_cast(static_cast(length))); - return static_cast(length); -} - template class Vector { public: @@ -1733,8 +1727,6 @@ enum FastDtoaMode { FAST_DTOA_PRECISION }; -static const int kFastDtoaMaximalLength = 17; - bool FastDtoa(double d, FastDtoaMode mode, int requested_digits, @@ -2350,7 +2342,6 @@ bool FastFixedDtoa(double v, return true; } -static const int kMaxExactDoubleIntegerDecimalDigits = 15; static const int kMaxUint64DecimalDigits = 19; static const int kMaxDecimalPower = 309; diff --git a/src/2geom/ellipse.cpp b/src/2geom/ellipse.cpp index afde428b1..f4704460f 100644 --- a/src/2geom/ellipse.cpp +++ b/src/2geom/ellipse.cpp @@ -417,7 +417,7 @@ std::vector Ellipse::intersect(Line const &line) const // generic case Coord a, b, c; line.coefficients(a, b, c); - Point lv = line.versor(); + Point lv = line.vector(); if (fabs(lv[X]) > fabs(lv[Y])) { // y = -a/b x - c/b diff --git a/src/2geom/generic-interval.h b/src/2geom/generic-interval.h index ce7945ab6..e7892e2dd 100644 --- a/src/2geom/generic-interval.h +++ b/src/2geom/generic-interval.h @@ -32,6 +32,7 @@ #define LIB2GEOM_SEEN_GENERIC_INTERVAL_H #include +#include #include #include #include <2geom/coord.h> @@ -338,14 +339,12 @@ inline GenericOptInterval operator&(GenericInterval const &a, GenericInter return GenericOptInterval(a) & GenericOptInterval(b); } -#ifdef _GLIBCXX_IOSTREAM template inline std::ostream &operator<< (std::ostream &os, Geom::GenericInterval const &I) { os << "Interval("< +#include #include #include <2geom/coord.h> @@ -513,13 +514,11 @@ inline bool GenericRect::contains(OptCRect const &r) const { return !r || contains(*r); } -#ifdef _GLIBCXX_IOSTREAM template inline std::ostream &operator<<(std::ostream &out, GenericRect const &r) { - out << "X: " << r[X] << " Y: " << r[Y]; + out << "Rect " << r[X] << " x " << r[Y]; return out; } -#endif } // end namespace Geom diff --git a/src/2geom/line.cpp b/src/2geom/line.cpp index ee2edeba7..a9cc0e251 100644 --- a/src/2geom/line.cpp +++ b/src/2geom/line.cpp @@ -103,7 +103,7 @@ void Line::setCoefficients (Coord a, Coord b, Coord c) void Line::coefficients(Coord &a, Coord &b, Coord &c) const { - Point v = versor().cw(); + Point v = vector().cw(); a = v[X]; b = v[Y]; c = cross(_initial, _final); @@ -139,7 +139,7 @@ std::vector Line::roots(Coord v, Dim2 d) const { Coord Line::root(Coord v, Dim2 d) const { assert(d == X || d == Y); - Point vs = versor(); + Point vs = vector(); if (vs[d] != 0) { return (v - _initial[d]) / vs[d]; } else { @@ -149,7 +149,7 @@ Coord Line::root(Coord v, Dim2 d) const boost::optional Line::clip(Rect const &r) const { - Point v = versor(); + Point v = vector(); // handle horizontal and vertical lines first, // since the root-based code below will break for them for (unsigned i = 0; i < 2; ++i) { @@ -221,7 +221,7 @@ boost::optional Line::clip(Rect const &r) const * @see timeAtProjection */ Coord Line::timeAt(Point const &p) const { - Point v = versor(); + Point v = vector(); // degenerate case if (v[X] == 0 && v[Y] == 0) { return 0; @@ -243,8 +243,8 @@ Coord Line::timeAt(Point const &p) const Affine Line::transformTo(Line const &other) const { Affine result = Translate(-_initial); - result *= Rotate(angle_between(versor(), other.versor())); - result *= Scale(other.versor().length() / versor().length()); + result *= Rotate(angle_between(vector(), other.vector())); + result *= Scale(other.vector().length() / vector().length()); result *= Translate(other._initial); return result; } @@ -253,8 +253,8 @@ std::vector Line::intersect(Line const &other) const { std::vector result; - Point v1 = versor(); - Point v2 = other.versor(); + Point v1 = vector(); + Point v2 = other.vector(); Coord cp = cross(v1, v2); if (cp == 0) return result; @@ -333,8 +333,8 @@ OptCrossing intersection_impl(Ray const& r1, Line const& l2, unsigned int i) using std::swap; OptCrossing crossing = - intersection_impl(r1.versor(), r1.origin(), - l2.versor(), l2.origin() ); + intersection_impl(r1.vector(), r1.origin(), + l2.vector(), l2.origin() ); if (crossing) { if (crossing->ta < 0) { @@ -363,7 +363,7 @@ OptCrossing intersection_impl( LineSegment const& ls1, OptCrossing crossing = intersection_impl(ls1.finalPoint() - ls1.initialPoint(), ls1.initialPoint(), - l2.versor(), + l2.vector(), l2.origin() ); if (crossing) { @@ -396,7 +396,7 @@ OptCrossing intersection_impl( LineSegment const& ls1, OptCrossing crossing = intersection_impl( direction, ls1.initialPoint(), - r2.versor(), + r2.vector(), r2.origin() ); if (crossing) { @@ -414,7 +414,7 @@ OptCrossing intersection_impl( LineSegment const& ls1, } if ( are_near(r2.origin(), ls1) ) { - bool eqvs = (dot(direction, r2.versor()) > 0); + bool eqvs = (dot(direction, r2.vector()) > 0); if ( are_near(ls1.initialPoint(), r2.origin()) && !eqvs) { crossing->ta = crossing->tb = 0; return crossing; @@ -445,8 +445,8 @@ OptCrossing intersection_impl( LineSegment const& ls1, OptCrossing intersection(Line const& l1, Line const& l2) { OptCrossing c = detail::intersection_impl( - l1.versor(), l1.origin(), - l2.versor(), l2.origin()); + l1.vector(), l1.origin(), + l2.vector(), l2.origin()); if (!c && distance(l1.origin(), l2) == 0) { THROW_INFINITESOLUTIONS(); @@ -457,8 +457,8 @@ OptCrossing intersection(Line const& l1, Line const& l2) OptCrossing intersection(Ray const& r1, Ray const& r2) { OptCrossing crossing = - detail::intersection_impl( r1.versor(), r1.origin(), - r2.versor(), r2.origin() ); + detail::intersection_impl( r1.vector(), r1.origin(), + r2.vector(), r2.origin() ); if (crossing) { @@ -477,7 +477,7 @@ OptCrossing intersection(Ray const& r1, Ray const& r2) if ( are_near(r1.origin(), r2) || are_near(r2.origin(), r1) ) { if ( are_near(r1.origin(), r2.origin()) - && !are_near(r1.versor(), r2.versor()) ) + && !are_near(r1.vector(), r2.vector()) ) { crossing->ta = crossing->tb = 0; return crossing; @@ -582,7 +582,7 @@ Line make_angle_bisector_line(Line const& l1, Line const& l2) } Point O = l1.pointAt(crossing->ta); Point A = l1.pointAt(crossing->ta + 1); - double angle = angle_between(l1.versor(), l2.versor()); + double angle = angle_between(l1.vector(), l2.vector()); Point B = (angle > 0) ? l2.pointAt(crossing->tb + 1) : l2.pointAt(crossing->tb - 1); diff --git a/src/2geom/line.h b/src/2geom/line.h index 8a66d4472..62b3652f1 100644 --- a/src/2geom/line.h +++ b/src/2geom/line.h @@ -98,7 +98,7 @@ public: /// Create a line by extending a ray. explicit Line(Ray const &r) : _initial(r.origin()) - , _final(r.origin() + r.versor()) + , _final(r.origin() + r.vector()) {} /// Create a line normal to a vector at a specified distance from origin. @@ -111,7 +111,7 @@ public: * Note that each line direction has two possible unit vectors. * @param o Point through which the line will pass * @param v Unit vector of the line's direction */ - static Line from_origin_and_versor(Point const &o, Point const &v) { + static Line from_origin_and_vector(Point const &o, Point const &v) { Line l(o, o + v); return l; } @@ -126,9 +126,12 @@ public: /// Get the line's origin point. Point origin() const { return _initial; } - /** @brief Get the line's direction vector. - * Note that the retrieved vector is not normalized to unit length. */ - Point versor() const { return _final - _initial; } + /** @brief Get the line's raw direction vector. + * The retrieved vector is normalized to unit length. */ + Point vector() const { return _final - _initial; } + /** @brief Get the line's normalized direction vector. + * The retrieved vector is normalized to unit length. */ + Point versor() const { return (_final - _initial).normalized(); } /// Angle the line makes with the X axis, in mathematical convention. Coord angle() const { Point d = _final - _initial; @@ -147,7 +150,7 @@ public: } /** @brief Set the speed of the line. * Origin remains unchanged. */ - void setVersor(Point const &v) { + void setVector(Point const &v) { _final = _initial + v; } @@ -239,7 +242,7 @@ public: * @return Time value corresponding to a point closest to @c p. */ Coord timeAtProjection(Point const& p) const { if ( isDegenerate() ) return 0; - Point v = versor(); + Point v = vector(); return dot(p - _initial, v) / dot(v, v); } @@ -284,22 +287,22 @@ public: boost::optional clip(Rect const &r) const; /** @brief Create a ray starting at the specified time value. - * The created ray will go in the direction of the line's versor (in the direction + * The created ray will go in the direction of the line's vector (in the direction * of increasing time values). * @param t Time value where the ray should start - * @return Ray starting at t and going in the direction of the versor */ + * @return Ray starting at t and going in the direction of the vector */ Ray ray(Coord t) { Ray result; result.setOrigin(pointAt(t)); - result.setVersor(versor()); + result.setVector(vector()); return result; } /** @brief Create a derivative of the line. * The new line will always be degenerate. Its origin will be equal to this - * line's versor. */ + * line's vector. */ Line derivative() const { - Point v = versor(); + Point v = vector(); Line result(v, v); return result; } @@ -314,7 +317,7 @@ public: * If Y grows upwards, then this is the left normal. If Y grows downwards, * then this is the right normal. */ Point normal() const { - return rot90(versor()).normalized(); + return rot90(vector()).normalized(); } // what does this do? @@ -326,7 +329,7 @@ public: /// Compute an affine matrix representing a reflection about the line. Affine reflection() const { - Point v = versor().normalized(); + Point v = versor(); Coord x2 = v[X]*v[X], y2 = v[Y]*v[Y], xy = v[X]*v[Y]; Affine m(x2-y2, 2.*xy, 2.*xy, y2-x2, @@ -344,7 +347,7 @@ public: * lower precision than e.g. a shear transform. * @param d Which coordinate of points on the line should be zero after the transformation */ Affine rotationToZero(Dim2 d) const { - Point v = versor(); + Point v = vector(); if (d == X) { std::swap(v[X], v[Y]); } else { @@ -421,7 +424,7 @@ bool are_near(Point const &p, Line const &line, double eps = EPSILON) inline bool are_parallel(Line const &l1, Line const &l2, double eps = EPSILON) { - return are_near(cross(l1.versor(), l2.versor()), 0, eps); + return are_near(cross(l1.vector(), l2.vector()), 0, eps); } /** @brief Test whether two lines are approximately the same. @@ -442,7 +445,7 @@ bool are_same(Line const &l1, Line const &l2, double eps = EPSILON) inline bool are_orthogonal(Line const &l1, Line const &l2, double eps = EPSILON) { - return are_near(dot(l1.versor(), l2.versor()), 0, eps); + return are_near(dot(l1.vector(), l2.vector()), 0, eps); } // evaluate the angle between l1 and l2 rotating l1 in cw direction @@ -451,7 +454,7 @@ bool are_orthogonal(Line const &l1, Line const &l2, double eps = EPSILON) inline double angle_between(Line const& l1, Line const& l2) { - double angle = angle_between(l1.versor(), l2.versor()); + double angle = angle_between(l1.vector(), l2.vector()); if (angle < 0) angle += M_PI; if (angle == M_PI) angle = 0; return angle; @@ -474,7 +477,7 @@ bool are_near(Point const &p, LineSegment const &seg, double eps = EPSILON) inline Line make_orthogonal_line(Point const &p, Line const &line) { - Point d = line.versor().cw(); + Point d = line.vector().cw(); Line l(p, p + d); return l; } diff --git a/src/2geom/ray.h b/src/2geom/ray.h index a336e3132..4e60fd814 100644 --- a/src/2geom/ray.h +++ b/src/2geom/ray.h @@ -53,61 +53,62 @@ namespace Geom class Ray { private: Point _origin; - Point _versor; + Point _vector; public: - Ray() : _origin(0,0), _versor(1,0) {} + Ray() : _origin(0,0), _vector(1,0) {} Ray(Point const& origin, Coord angle) : _origin(origin) { - sincos(angle, _versor[Y], _versor[X]); + sincos(angle, _vector[Y], _vector[X]); } Ray(Point const& A, Point const& B) { setPoints(A, B); } Point origin() const { return _origin; } - Point versor() const { return _versor; } + Point vector() const { return _vector; } + Point versor() const { return _vector.normalized(); } void setOrigin(Point const &o) { _origin = o; } - void setVersor(Point const& v) { _versor = v; } - Coord angle() const { return std::atan2(_versor[Y], _versor[X]); } - void setAngle(Coord a) { sincos(a, _versor[Y], _versor[X]); } + void setVector(Point const& v) { _vector = v; } + Coord angle() const { return std::atan2(_vector[Y], _vector[X]); } + void setAngle(Coord a) { sincos(a, _vector[Y], _vector[X]); } void setPoints(Point const &a, Point const &b) { _origin = a; - _versor = b - a; - if (are_near(_versor, Point(0,0)) ) - _versor = Point(0,0); + _vector = b - a; + if (are_near(_vector, Point(0,0)) ) + _vector = Point(0,0); else - _versor.normalize(); + _vector.normalize(); } bool isDegenerate() const { - return ( _versor[X] == 0 && _versor[Y] == 0 ); + return ( _vector[X] == 0 && _vector[Y] == 0 ); } Point pointAt(Coord t) const { - return _origin + _versor * t; + return _origin + _vector * t; } Coord valueAt(Coord t, Dim2 d) const { - return _origin[d] + _versor[d] * t; + return _origin[d] + _vector[d] * t; } std::vector roots(Coord v, Dim2 d) const { std::vector result; - if ( _versor[d] != 0 ) { - double t = (v - _origin[d]) / _versor[d]; + if ( _vector[d] != 0 ) { + double t = (v - _origin[d]) / _vector[d]; if (t >= 0) result.push_back(t); - } else if (_versor[(d+1)%2] == v) { + } else if (_vector[(d+1)%2] == v) { THROW_INFINITESOLUTIONS(); } return result; } Coord nearestTime(Point const& point) const { if ( isDegenerate() ) return 0; - double t = dot(point - _origin, _versor); + double t = dot(point - _origin, _vector); if (t < 0) t = 0; return t; } Ray reverse() const { Ray result; result.setOrigin(_origin); - result.setVersor(-_versor); + result.setVector(-_vector); return result; } Curve *portion(Coord f, Coord t) const { @@ -117,7 +118,7 @@ public: return LineSegment(pointAt(f), pointAt(t)); } Ray transformed(Affine const& m) const { - return Ray(_origin * m, (_origin + _versor) * m); + return Ray(_origin * m, (_origin + _vector) * m); } }; // end class Ray @@ -134,7 +135,7 @@ bool are_near(Point const& _point, Ray const& _ray, double eps = EPSILON) { inline bool are_same(Ray const& r1, Ray const& r2, double eps = EPSILON) { - return are_near(r1.versor(), r2.versor(), eps) + return are_near(r1.vector(), r2.vector(), eps) && are_near(r1.origin(), r2.origin(), eps); } @@ -142,7 +143,7 @@ bool are_same(Ray const& r1, Ray const& r2, double eps = EPSILON) { // the returned value is an angle in the interval [0, 2PI[ inline double angle_between(Ray const& r1, Ray const& r2, bool cw = true) { - double angle = angle_between(r1.versor(), r2.versor()); + double angle = angle_between(r1.vector(), r2.vector()); if (angle < 0) angle += 2*M_PI; if (!cw) angle = 2*M_PI - angle; return angle; @@ -170,7 +171,7 @@ Ray make_angle_bisector_ray(Ray const& r1, Ray const& r2, bool cw = true) THROW_RANGEERROR("passed rays do not have the same origin"); } - Ray bisector(r1.origin(), r1.origin() + r1.versor() * Rotate(angle_between(r1, r2) / 2.0)); + Ray bisector(r1.origin(), r1.origin() + r1.vector() * Rotate(angle_between(r1, r2) / 2.0)); return (cw ? bisector : bisector.reverse()); } diff --git a/src/2geom/sweeper.h b/src/2geom/sweeper.h index b3c96455f..469108465 100644 --- a/src/2geom/sweeper.h +++ b/src/2geom/sweeper.h @@ -52,10 +52,10 @@ public: {} std::vector const &items() { return _items; } - Interval itemBounds(ItemIterator ii) { return Interval(); } + Interval itemBounds(ItemIterator /*ii*/) { return Interval(); } - void addActiveItem(ItemIterator ii) {} - void removeActiveItem(ItemIterator ii) {} + void addActiveItem(ItemIterator /*ii*/) {} + void removeActiveItem(ItemIterator /*ii*/) {} private: std::vector const &_items; @@ -104,9 +104,9 @@ public: } /** @brief Process entry and exit events. - * This will iterate over all inserted items, calling the virtual protected - * functions _enter() and _leave() according to the order of the boundaries - * of each item. */ + * This will iterate over all inserted items, calling the methods + * addActiveItem and removeActiveItem on the SweepSet passed at construction + * according to the order of the boundaries of each item. */ void process() { if (_set.items().empty()) return; diff --git a/src/2geom/utils.h b/src/2geom/utils.h index 3e0dd4717..01579d81b 100644 --- a/src/2geom/utils.h +++ b/src/2geom/utils.h @@ -68,7 +68,7 @@ struct NullIterator NullIterator() {} template - void operator=(T const &v) {} + void operator=(T const &) {} }; /** @brief Get the next iterator in the container with wrap-around. diff --git a/src/conn-avoid-ref.cpp b/src/conn-avoid-ref.cpp index d43d000a7..9190fe633 100644 --- a/src/conn-avoid-ref.cpp +++ b/src/conn-avoid-ref.cpp @@ -296,14 +296,14 @@ static Avoid::Polygon avoid_item_poly(SPItem const *item) Geom::Line hull_edge(hull[-1], hull[0]); Geom::Line prev_parallel_hull_edge; prev_parallel_hull_edge.setOrigin(hull_edge.origin()+hull_edge.versor().ccw()*spacing); - prev_parallel_hull_edge.setVersor(hull_edge.versor()); + prev_parallel_hull_edge.setVector(hull_edge.versor()); int hull_size = hull.size(); for (int i = 0; i < hull_size; ++i) { hull_edge.setPoints(hull[i], hull[i+1]); Geom::Line parallel_hull_edge; parallel_hull_edge.setOrigin(hull_edge.origin()+hull_edge.versor().ccw()*spacing); - parallel_hull_edge.setVersor(hull_edge.versor()); + parallel_hull_edge.setVector(hull_edge.versor()); // determine the intersection point try { -- cgit v1.2.3 From 3baced40739b8b12bc5d258f05a209681e900cd6 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 15 Feb 2016 10:52:41 +0100 Subject: Temporary: Add different fallback strategies for 'line-join' LPE with 'arcs' line join. (bzr r14653) --- src/helper/geom-pathstroke.cpp | 356 ++++++++++++++++++++++++++++++++++++-- src/helper/geom-pathstroke.h | 3 + src/live_effects/lpe-jointype.cpp | 3 + 3 files changed, 349 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/helper/geom-pathstroke.cpp b/src/helper/geom-pathstroke.cpp index c73a9e9e7..52871ae2a 100644 --- a/src/helper/geom-pathstroke.cpp +++ b/src/helper/geom-pathstroke.cpp @@ -15,6 +15,7 @@ #include <2geom/sbasis-to-bezier.h> // cubicbezierpath_from_sbasis #include <2geom/path-intersection.h> #include <2geom/circle.h> +#include #include "helper/geom-pathstroke.h" @@ -55,6 +56,53 @@ static Circle touching_circle( D2 const &curve, double t, double tol=0.0 return Geom::Circle(center, fabs(radius)); } + +// Area of triangle given three corner points +static double area( Geom::Point a, Geom::Point b, Geom::Point c ) { + + using Geom::X; + using Geom::Y; + return( 0.5 * fabs( ( a[X]*(b[Y]-c[Y]) + b[X]*(c[Y]-a[Y]) + c[X]*(a[Y]-b[Y]) ) ) ); +} + +// Alternative touching circle routine directly using Beziers. Works only at end points. +static Circle touching_circle( CubicBezier const &curve, bool start ) { + + double k = 0; + Geom::Point p; + Geom::Point normal; + if ( start ) { + double distance = Geom::distance( curve[1], curve[0] ); + k = 4.0/3.0 * area( curve[0], curve[1], curve[2] ) / + (distance * distance * distance); + if( Geom::cross(curve[0]-curve[1], curve[1]-curve[2]) < 0 ) { + k = -k; + } + p = curve[0]; + normal = Geom::Point(curve[1] - curve[0]).cw(); + normal.normalize(); + // std::cout << "Start k: " << k << " d: " << distance << " normal: " << normal << std::endl; + } else { + double distance = Geom::distance( curve[3], curve[2] ); + k = 4.0/3.0 * area( curve[1], curve[2], curve[3] ) / + (distance * distance * distance); + if( Geom::cross(curve[1]-curve[2], curve[2]-curve[3]) < 0 ) { + k = -k; + } + p = curve[3]; + normal = Geom::Point(curve[3] - curve[2]).cw(); + normal.normalize(); + // std::cout << "End k: " << k << " d: " << distance << " normal: " << normal << std::endl; + } + if( k == 0 ) { + return Geom::Circle( Geom::Point(0,std::numeric_limits::infinity()), + std::numeric_limits::infinity()); + } else { + double radius = 1/k; + Geom::Point center = p + normal * radius; + return Geom::Circle( center, fabs(radius) ); + } +} } namespace { @@ -77,7 +125,7 @@ struct join_data { // line parameters double miter; - double width; + double width; // half stroke width }; // Join functions must append the outgoing path @@ -124,13 +172,16 @@ void miter_join_internal(join_data jd, bool clip) res.appendNew(p); } } else if (clip) { + // std::cout << " Clipping ------------ " << std::endl; // miter needs clipping, find two points Point bisector_versor = Line(point_on_path, p).versor(); Point point_limit = point_on_path + miter * 2.0 * width * bisector_versor; - + // std::cout << " bisector_versor: " << bisector_versor << std::endl; + // std::cout << " point_limit: " << point_limit << std::endl; Point p1 = intersection_point(incoming.finalPoint(), tang1, point_limit, bisector_versor.cw()); Point p2 = intersection_point(outgoing.initialPoint(), tang2, point_limit, bisector_versor.cw()); - + // std::cout << " p1: " << p1 << std::endl; + // std::cout << " p2: " << p2 << std::endl; if (inc_ls) { res.setFinal(p1); } else { @@ -176,8 +227,132 @@ Geom::Point pick_solution(std::vector points, Geom::Poi return sol; } -void extrapolate_join(join_data jd) +// Arcs line join. If two circles don't intersect, expand inner circle. +Geom::Point expand_circle( Geom::Circle &inner_circle, Geom::Circle const &outer_circle, Geom::Point const &start_pt, Geom::Point const &start_tangent ) { + // std::cout << "expand_circle:" << std::endl; + // std::cout << " outer_circle: radius: " << outer_circle.radius() << " center: " << outer_circle.center() << std::endl; + // std::cout << " start: point: " << start_pt << " tangent: " << start_tangent << std::endl; + + if( !(outer_circle.contains(start_pt) ) ) { + // std::cout << " WARNING: Outer circle does not contain starting point!" << std::endl; + return Geom::Point(0,0); + } + + Geom::Line secant1(start_pt, start_pt + start_tangent); + std::vector chord1_pts = outer_circle.intersect(secant1); + // std::cout << " chord1: " << chord1_pts[0].point() << ", " << chord1_pts[1].point() << std::endl; + Geom::LineSegment chord1(chord1_pts[0].point(), chord1_pts[1].point()); + + Geom::Line bisector = make_bisector_line( chord1 ); + std::vector chord2_pts = outer_circle.intersect(bisector); + // std::cout << " chord2: " << chord2_pts[0].point() << ", " << chord2_pts[1].point() << std::endl; + Geom::LineSegment chord2(chord2_pts[0].point(), chord2_pts[1].point()); + + // Find D, point on chord2 and on circle closest to start point + Geom::Coord d0 = Geom::distance(chord2_pts[0].point(),start_pt); + Geom::Coord d1 = Geom::distance(chord2_pts[1].point(),start_pt); + // std::cout << " d0: " << d0 << " d1: " << d1 << std::endl; + Geom::Point d = (d0 < d1) ? chord2_pts[0].point() : chord2_pts[1].point(); + Geom::Line da(d,start_pt); + + // Chord through start point and point D + std::vector chord3_pts = outer_circle.intersect(da); + // std::cout << " chord3: " << chord3_pts[0].point() << ", " << chord3_pts[1].point() << std::endl; + + // Find farthest point on chord3 and on circle (could be more robust) + Geom::Coord d2 = Geom::distance(chord3_pts[0].point(),d); + Geom::Coord d3 = Geom::distance(chord3_pts[1].point(),d); + // std::cout << " d2: " << d2 << " d3: " << d3 << std::endl; + + // Find point P, the intersection of outer circle and new inner circle + Geom::Point p = (d2 > d3) ? chord3_pts[0].point() : chord3_pts[1].point(); + + // Find center of new circle: it is at the intersection of the bisector + // of the chord defined by the start point and point P and a line through + // the start point and parallel to the first bisector. + Geom::LineSegment chord4(start_pt,p); + Geom::Line bisector2 = make_bisector_line( chord4 ); + Geom::Line diameter = make_parallel_line( start_pt, bisector ); + std::vector center_new = bisector2.intersect( diameter ); + // std::cout << " center_new: " << center_new[0].point() << std::endl; + Geom::Coord r_new = Geom::distance( center_new[0].point(), start_pt ); + // std::cout << " r_new: " << r_new << std::endl; + + inner_circle.setCenter( center_new[0].point() ); + inner_circle.setRadius( r_new ); + return p; +} + +// Arcs line join. If two circles don't intersect, adjust both circles so they just touch. +// Increase (decrease) the radius of circle 1 and decrease (increase) of circle 2 by the same amount keeping the given points and tangents fixed. +Geom::Point adjust_circles( Geom::Circle &circle1, Geom::Circle &circle2, Geom::Point const &point1, Geom::Point const &point2, Geom::Point const &tan1, Geom::Point const &tan2 ) { + + Geom::Point n1 = (circle1.center() - point1).normalized(); // Always points towards center + Geom::Point n2 = (circle2.center() - point2).normalized(); + Geom::Point sum_n = n1 + n2; + + double r1 = circle1.radius(); + double r2 = circle2.radius(); + double delta_r = r2 - r1; + Geom::Point c1 = circle1.center(); + Geom::Point c2 = circle2.center(); + Geom::Point delta_c = c2 - c1; + + // std::cout << "adjust_circles:" << std::endl; + // std::cout << " norm: " << n1 << "; " << n2 << std::endl; + // std::cout << " sum_n: " << sum_n << std::endl; + // std::cout << " delta_r: " << delta_r << std::endl; + // std::cout << " delta_c: " << delta_c << std::endl; + + // Quadratic equation + double A = 4 - sum_n.length() * sum_n.length(); + double B = 4.0 * delta_r - 2.0 * Geom::dot( delta_c, sum_n ); + double C = delta_r * delta_r - delta_c.length() * delta_c.length(); + + double s1 = 0; + double s2 = 0; + + if( fabs(A) < 0.01 ) { + // std::cout << " A near zero! $$$$$$$$$$$$$$$$$$" << std::endl; + if( B != 0 ) { + s1 = -C/B; + s2 = -s1; + } + } else { + s1 = (-B + sqrt(B*B - 4*A*C))/(2*A); + s2 = (-B - sqrt(B*B - 4*A*C))/(2*A); + } + + double dr = (fabs(s1)<=fabs(s2)?s1:s2); + + // std::cout << " A: " << A << std::endl; + // std::cout << " B: " << B << std::endl; + // std::cout << " C: " << C << std::endl; + // std::cout << " s1: " << s1 << " s2: " << s2 << " dr: " << dr << std::endl; + + circle1 = Geom::Circle( c1 - dr*n1, r1-dr ); + circle2 = Geom::Circle( c2 + dr*n2, r2+dr ); + + // std::cout << " C1: " << circle1 << std::endl; + // std::cout << " C2: " << circle2 << std::endl; + // std::cout << " d': " << Geom::Point( circle1.center() - circle2.center() ).length() << std::endl; + + Geom::Line bisector( circle1.center(), circle2.center() ); + std::vector points = circle1.intersect( bisector ); + Geom::Point p0 = points[0].point(); + Geom::Point p1 = points[1].point(); + // std::cout << " points: " << p0 << "; " << p1 << std::endl; + if( abs( Geom::distance( p0, circle2.center() ) - circle2.radius() ) < + abs( Geom::distance( p1, circle2.center() ) - circle2.radius() ) ) { + return p0; + } else { + return p1; + } +} + +void extrapolate_join_internal(join_data jd, int alternative) { + // std::cout << "\nextrapolate_join: entrance: alternative: " << alternative << std::endl; using namespace Geom; Geom::Path &res = jd.res; @@ -187,10 +362,40 @@ void extrapolate_join(join_data jd) Geom::Point endPt = outgoing.initialPoint(); Geom::Point tang1 = jd.in_tang; Geom::Point tang2 = jd.out_tang; + // width is half stroke-width double width = jd.width, miter = jd.miter; - Geom::Circle circle1 = Geom::touching_circle(Geom::reverse(incoming.toSBasis()), 0.); - Geom::Circle circle2 = Geom::touching_circle(outgoing.toSBasis(), 0); + // std::cout << " startPt: " << startPt << " endPt: " << endPt << std::endl; + // std::cout << " tang1: " << tang1 << " tang2: " << tang2 << std::endl; + // std::cout << " dot product: " << Geom::dot( tang1, tang2 ) << std::endl; + // std::cout << " width: " << width << std::endl; + + // CIRCLE CALCULATION TESTING + Geom::Circle circle1 = touching_circle(Geom::reverse(incoming.toSBasis()), 0.); + Geom::Circle circle2 = touching_circle(outgoing.toSBasis(), 0); + // std::cout << " circle1: " << circle1 << std::endl; + // std::cout << " circle2: " << circle2 << std::endl; + if( Geom::CubicBezier const * in_bezier = dynamic_cast(&incoming) ) { + Geom::Circle circle_test1 = touching_circle(*in_bezier, false); + if( !Geom::are_near( circle1, circle_test1, 0.01 ) ) { + // std::cout << " Circle 1 error!!!!!!!!!!!!!!!!!" << std::endl; + // std::cout << " " << circle_test1 << std::endl; + } + } + if( Geom::CubicBezier const * out_bezier = dynamic_cast(&outgoing) ) { + Geom::Circle circle_test2 = touching_circle(*out_bezier, true); + if( !Geom::are_near( circle2, circle_test2, 0.01 ) ) { + // std::cout << " Circle 2 error!!!!!!!!!!!!!!!!!" << std::endl; + // std::cout << " " << circle_test2 << std::endl; + } + } + // END TESTING + + Geom::Point center1 = circle1.center(); + Geom::Point center2 = circle2.center(); + double side1 = tang1[Geom::X]*(startPt[Geom::Y]-center1[Geom::Y]) - tang1[Geom::Y]*(startPt[Geom::X]-center1[Geom::X]); + double side2 = tang2[Geom::X]*( endPt[Geom::Y]-center2[Geom::Y]) - tang2[Geom::Y]*( endPt[Geom::X]-center2[Geom::X]); + // std::cout << " side1: " << side1 << " side2: " << side2 << std::endl; bool inc_ls = !circle1.center().isFinite(); bool out_ls = !circle2.center().isFinite(); @@ -199,20 +404,120 @@ void extrapolate_join(join_data jd) Geom::EllipticalArc *arc1 = NULL; Geom::EllipticalArc *arc2 = NULL; + Geom::LineSegment *seg1 = NULL; + Geom::LineSegment *seg2 = NULL; Geom::Point sol; Geom::Point p1; Geom::Point p2; if (!inc_ls && !out_ls) { + // std::cout << " two circles" << std::endl; + + // See if tangent is backwards (radius < width/2 and circle is inside stroke). + Geom::Point node_on_path = startPt + Geom::rot90(tang1)*width; + // std::cout << " node_on_path: " << node_on_path << " -------------- " << std::endl; + bool b1 = false; + bool b2 = false; + if (circle1.radius() < width && distance( circle1.center(), node_on_path ) < width) { + b1 = true; + } + if (circle2.radius() < width && distance( circle2.center(), node_on_path ) < width) { + b2 = true; + } + // std::cout << " b1: " << (b1?"true":"false") + // << " b2: " << (b2?"true":"false") << std::endl; + // Two circles points = circle1.intersect(circle2); + + if (points.size() != 2) { + // std::cout << " Circles do not intersect, do backup" << std::endl; + switch (alternative) { + case 1: + { + // Fallback to round if one path has radius smaller than half line width. + if(b1 || b2) { + // std::cout << "At one least path has radius smaller than half line width." << std::endl; + return( round_join(jd) ); + } + + Point p; + if( circle2.contains( startPt ) && !circle1.contains( endPt ) ) { + // std::cout << "Expand circle1" << std::endl; + p = expand_circle( circle1, circle2, startPt, tang1 ); + points.push_back( ShapeIntersection( 0, 0, p) ); + points.push_back( ShapeIntersection( 0, 0, p) ); + } else if( circle1.contains( endPt ) && !circle2.contains( startPt ) ) { + // std::cout << "Expand circle2" << std::endl; + p = expand_circle( circle2, circle1, endPt, tang2 ); + points.push_back( ShapeIntersection( 0, 0, p) ); + points.push_back( ShapeIntersection( 0, 0, p) ); + } else { + // std::cout << "Either both points inside or both outside" << std::endl; + return( miter_clip_join(jd) ); + } + break; + + } + case 2: + { + // Fallback to round if one path has radius smaller than half line width. + if(b1 || b2) { + // std::cout << "At one least path has radius smaller than half line width." << std::endl; + return( round_join(jd) ); + } + + if( ( circle2.contains( startPt ) && !circle1.contains( endPt ) ) || + ( circle1.contains( endPt ) && !circle2.contains( startPt ) ) ) { + + Geom::Point apex = adjust_circles( circle1, circle2, startPt, endPt, tang1, tang2 ); + points.push_back( ShapeIntersection( 0, 0, apex) ); + points.push_back( ShapeIntersection( 0, 0, apex) ); + } else { + // std::cout << "Either both points inside or both outside" << std::endl; + return( miter_clip_join(jd) ); + } + + break; + } + case 3: + if( side1 > 0 ) { + Geom::Line secant(startPt, startPt + tang1); + points = circle2.intersect(secant); + circle1.setRadius(std::numeric_limits::infinity()); + circle1.setCenter(Geom::Point(0,std::numeric_limits::infinity())); + } else { + Geom::Line secant(endPt, endPt + tang2); + points = circle1.intersect(secant); + circle2.setRadius(std::numeric_limits::infinity()); + circle2.setCenter(Geom::Point(0,std::numeric_limits::infinity())); + } + break; + + + case 0: + default: + // Do nothing + break; + } + } + if (points.size() == 2) { sol = pick_solution(points, tang2, endPt); - arc1 = circle1.arc(startPt, 0.5*(startPt+sol), sol); - arc2 = circle2.arc(sol, 0.5*(sol+endPt), endPt); + if( circle1.radius() != std::numeric_limits::infinity() ) { + arc1 = circle1.arc(startPt, 0.5*(startPt+sol), sol); + } else { + seg1 = new Geom::LineSegment(startPt, sol); + } + if( circle2.radius() != std::numeric_limits::infinity() ) { + arc2 = circle2.arc(sol, 0.5*(sol+endPt), endPt); + } else { + seg2 = new Geom::LineSegment(sol, endPt); + } } } else if (inc_ls && !out_ls) { // Line and circle + // std::cout << " line circle" << std::endl; points = circle2.intersect(Line(incoming.initialPoint(), incoming.finalPoint())); if (points.size() == 2) { sol = pick_solution(points, tang2, endPt); @@ -220,16 +525,18 @@ void extrapolate_join(join_data jd) } } else if (!inc_ls && out_ls) { // Circle and line + // std::cout << " circle line" << std::endl; points = circle1.intersect(Line(outgoing.initialPoint(), outgoing.finalPoint())); if (points.size() == 2) { sol = pick_solution(points, tang2, endPt); arc1 = circle1.arc(startPt, 0.5*(sol+startPt), sol); } } - - if (points.size() != 2) + if (points.size() != 2) { + // std::cout << " no solutions" << std::endl; // no solutions available, fall back to miter - return miter_clip_join(jd); + return miter_join(jd); + } // We have a solution, thus sol is defined. p1 = sol; @@ -250,12 +557,13 @@ void extrapolate_join(join_data jd) Geom::Line limit_line; double miter_limit = 2.0 * width * miter; bool clipped = false; - + if (are_parallel(bisector_chord, ortho)) { // No intersection (can happen if curvatures are equal but opposite) if (Geom::distance(point_on_path, sol) > miter_limit) { clipped = true; - Geom::Point limit_point = point_on_path + miter_limit * bisector.versor(); + Geom::Point temp = bisector.versor(); + Geom::Point limit_point = point_on_path + miter_limit * temp; limit_line = make_parallel_line( limit_point, ortho ); } } else { @@ -311,6 +619,8 @@ void extrapolate_join(join_data jd) // Add initial if (arc1) { res.append(*arc1); + } else if (seg1 ) { + res.append(*seg1); } else { // Straight line segment: move last point res.setFinal(p1); @@ -324,6 +634,9 @@ void extrapolate_join(join_data jd) if (arc2) { res.append(*arc2); res.append(outgoing); + } else if (seg2 ) { + res.append(*seg2); + res.append(outgoing); } else { // Straight line segment: res.appendNew(outgoing.finalPoint()); @@ -334,8 +647,16 @@ void extrapolate_join(join_data jd) delete arc1; delete arc2; + delete seg1; + delete seg2; } +void extrapolate_join( join_data jd) { extrapolate_join_internal(jd, 0); } +void extrapolate_join_alt1(join_data jd) { extrapolate_join_internal(jd, 1); } +void extrapolate_join_alt2(join_data jd) { extrapolate_join_internal(jd, 2); } +void extrapolate_join_alt3(join_data jd) { extrapolate_join_internal(jd, 3); } + + void join_inside(join_data jd) { Geom::Path &res = jd.res; @@ -716,6 +1037,15 @@ void outline_join(Geom::Path &res, Geom::Path const& temp, Geom::Point in_tang, case Inkscape::JOIN_EXTRAPOLATE: jf = &extrapolate_join; break; + case Inkscape::JOIN_EXTRAPOLATE1: + jf = &extrapolate_join_alt1; + break; + case Inkscape::JOIN_EXTRAPOLATE2: + jf = &extrapolate_join_alt2; + break; + case Inkscape::JOIN_EXTRAPOLATE3: + jf = &extrapolate_join_alt3; + break; case Inkscape::JOIN_MITER_CLIP: jf = &miter_clip_join; break; diff --git a/src/helper/geom-pathstroke.h b/src/helper/geom-pathstroke.h index 6697273cf..6a753a6fd 100644 --- a/src/helper/geom-pathstroke.h +++ b/src/helper/geom-pathstroke.h @@ -21,6 +21,9 @@ enum LineJoinType { JOIN_MITER, JOIN_MITER_CLIP, JOIN_EXTRAPOLATE, + JOIN_EXTRAPOLATE1, + JOIN_EXTRAPOLATE2, + JOIN_EXTRAPOLATE3, }; enum LineCapType { diff --git a/src/live_effects/lpe-jointype.cpp b/src/live_effects/lpe-jointype.cpp index 28f99eb94..2eef315dd 100644 --- a/src/live_effects/lpe-jointype.cpp +++ b/src/live_effects/lpe-jointype.cpp @@ -33,6 +33,9 @@ static const Util::EnumData JoinTypeData[] = { {JOIN_MITER, N_("Miter"), "miter"}, {JOIN_MITER_CLIP, N_("Miter Clip"), "miter-clip"}, {JOIN_EXTRAPOLATE, N_("Extrapolated arc"), "extrp_arc"}, + {JOIN_EXTRAPOLATE1, N_("Extrapolated arc Alt1"), "extrp_arc1"}, + {JOIN_EXTRAPOLATE2, N_("Extrapolated arc Alt2"), "extrp_arc2"}, + {JOIN_EXTRAPOLATE3, N_("Extrapolated arc Alt3"), "extrp_arc3"}, }; static const Util::EnumData CapTypeData[] = { -- cgit v1.2.3 From f200503cc154d84f3e4aa87400c1c045bfa80937 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Tue, 16 Feb 2016 02:42:58 +0100 Subject: Performance improvements when working in large files At each mouse move, a list of all elements in the document was computed (to get the correct cursor, in text mode for instance). This list is now cached. (bzr r14655) --- src/document.cpp | 39 ++++++++++++++++++++++++--------------- src/document.h | 8 ++++++-- 2 files changed, 30 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index d4bd29386..621cb071e 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -108,7 +108,8 @@ SPDocument::SPDocument() : oldSignalsConnected(false), current_persp3d(NULL), current_persp3d_impl(NULL), - _parent_document(NULL) + _parent_document(NULL), + _node_cache_valid(false) { // Penalise libavoid for choosing paths with needless extra segments. // This results in much better looking orthogonal connector paths. @@ -130,6 +131,7 @@ SPDocument::SPDocument() : // XXX only for testing! priv->undoStackObservers.add(p->console_output_undo_observer); + _node_cache = std::deque(); } SPDocument::~SPDocument() { @@ -986,6 +988,7 @@ void SPDocument::_emitModified() { static guint const flags = SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG; root->emitModified(0); priv->modified_signal.emit(flags); + _node_cache_valid=false; } void SPDocument::bindObjectToId(gchar const *id, SPObject *object) { @@ -1334,7 +1337,7 @@ Turn the SVG DOM into a flat list of nodes that can be searched from top-down. The list can be persisted, which improves "find at multiple points" speed. Returns true if upto is reached. */ -static bool build_flat_item_list(std::deque *nodes, unsigned int dkey, SPGroup *group, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL) +bool SPDocument::build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups, bool take_insensitive, SPItem *upto) { bool found_upto = false; for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) { @@ -1348,14 +1351,14 @@ static bool build_flat_item_list(std::deque *nodes, unsigned int dkey, } if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { - found_upto = build_flat_item_list(nodes, dkey, SP_GROUP(o), into_groups, take_insensitive, upto); + found_upto = build_flat_item_list(dkey, SP_GROUP(o), into_groups, take_insensitive, upto); if (found_upto) break; } else { SPItem *child = SP_ITEM(o); if (take_insensitive || child->isVisibleAndUnlocked(dkey)) { - nodes->push_front(child); + _node_cache.push_front(child); } } } @@ -1378,8 +1381,8 @@ static SPItem *find_item_at_point(std::deque *nodes, unsigned int dkey, SPItem *seen = NULL; SPItem *child; - for (unsigned long i = 0; i < nodes->size(); ++i) { - child = nodes->at(i); + for (std::deque::const_iterator i = nodes->begin(); i != nodes->end(); ++i) { + child = *i; Inkscape::DrawingItem *arenaitem = child->get_arenaitem(dkey); if (arenaitem && arenaitem->pick(p, delta, 1) != NULL) { @@ -1451,7 +1454,7 @@ std::vector SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom: return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps, false, into_groups); } -std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vector points, bool all_layers, size_t limit) const +std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vector points, bool all_layers, size_t limit) { std::vector items; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -1463,8 +1466,11 @@ std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vecto prefs->setDouble("/options/cursortolerance/value", 0.25); // Cache a flattened SVG DOM to speed up selection. - std::deque nodes; - build_flat_item_list(&nodes, key, SP_GROUP(this->root), true, false, NULL); + if(!_node_cache_valid){ + _node_cache.clear(); + build_flat_item_list(key, SP_GROUP(this->root), true, false, NULL); + _node_cache_valid=true; + } SPObject *current_layer = SP_ACTIVE_DESKTOP->currentLayer(); SPDesktop *desktop = SP_ACTIVE_DESKTOP; Inkscape::LayerModel *layer_model = NULL; @@ -1473,7 +1479,7 @@ std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vecto } size_t item_counter = 0; for(int i = points.size()-1;i>=0; i--) { - SPItem *item = find_item_at_point(&nodes, key, points[i]); + SPItem *item = find_item_at_point(&_node_cache, key, points[i]); if (item && items.end()==find(items.begin(),items.end(), item)) if(all_layers || (layer_model && layer_model->layerForObject(item) == current_layer)){ items.push_back(item); @@ -1493,15 +1499,18 @@ std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vecto } SPItem *SPDocument::getItemAtPoint( unsigned const key, Geom::Point const &p, - bool const into_groups, SPItem *upto) const + bool const into_groups, SPItem *upto) { g_return_val_if_fail(this->priv != NULL, NULL); // Build a flattened SVG DOM for find_item_at_point. - std::deque nodes; - build_flat_item_list(&nodes, key, SP_GROUP(this->root), into_groups, false, upto); - - return find_item_at_point(&nodes, key, p); + if(!_node_cache_valid){ + _node_cache.clear(); + build_flat_item_list(key, SP_GROUP(this->root), into_groups, false, upto); + if(!upto) + _node_cache_valid = true; + } + return find_item_at_point(&_node_cache, key, p); } SPItem *SPDocument::getGroupAtPoint(unsigned int key, Geom::Point const &p) const diff --git a/src/document.h b/src/document.h index b4a8a8e8e..b57cf205d 100644 --- a/src/document.h +++ b/src/document.h @@ -28,6 +28,7 @@ #include #include #include +#include namespace Avoid { class Router; @@ -262,8 +263,8 @@ public: const std::set getResourceList(char const *key) const; std::vector getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool into_groups = false) const; std::vector getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool into_groups = false) const; - SPItem *getItemAtPoint(unsigned int key, Geom::Point const &p, bool into_groups, SPItem *upto = NULL) const; - std::vector getItemsAtPoints(unsigned const key, std::vector points, bool all_layers = true, size_t limit = 0) const; + SPItem *getItemAtPoint(unsigned int key, Geom::Point const &p, bool into_groups, SPItem *upto = NULL) ; + std::vector getItemsAtPoints(unsigned const key, std::vector points, bool all_layers = true, size_t limit = 0) ; SPItem *getGroupAtPoint(unsigned int key, Geom::Point const &p) const; void changeUriAndHrefs(char const *uri); @@ -277,6 +278,9 @@ private: void do_change_uri(char const *const filename, bool const rebase); void setupViewport(SPItemCtx *ctx); void importDefsNode(SPDocument *source, Inkscape::XML::Node *defs, Inkscape::XML::Node *target_defs); + bool build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL); + std::deque _node_cache; + bool _node_cache_valid; }; /* -- cgit v1.2.3 From 109ec952f041590ee5f42ac6e7d6bd5c212c9441 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Thu, 18 Feb 2016 00:38:22 +0100 Subject: Fixes some regressions from rev14655 Fixed bugs: - https://launchpad.net/bugs/1546531 (bzr r14658) --- src/document.cpp | 48 ++++++++++++++++++++++++++---------------------- src/document.h | 10 +++++----- 2 files changed, 31 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 621cb071e..ae03b1ba1 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1335,34 +1335,24 @@ SPItem *SPDocument::getItemFromListAtPointBottom(unsigned int dkey, SPGroup *gro /** Turn the SVG DOM into a flat list of nodes that can be searched from top-down. The list can be persisted, which improves "find at multiple points" speed. -Returns true if upto is reached. */ -bool SPDocument::build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups, bool take_insensitive, SPItem *upto) +void SPDocument::build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups) const { - bool found_upto = false; for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) { if (!SP_IS_ITEM(o)) { continue; } - if (upto && SP_ITEM(o) == upto) { - found_upto = true; - break; - } - if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { - found_upto = build_flat_item_list(dkey, SP_GROUP(o), into_groups, take_insensitive, upto); - if (found_upto) - break; + build_flat_item_list(dkey, SP_GROUP(o), into_groups); } else { SPItem *child = SP_ITEM(o); - if (take_insensitive || child->isVisibleAndUnlocked(dkey)) { + if (child->isVisibleAndUnlocked(dkey)) { _node_cache.push_front(child); } } } - return found_upto; } /** @@ -1374,15 +1364,21 @@ upwards in z-order and returns what it has found so far (i.e. the found item is guaranteed to be lower than upto). Requires a list of nodes built by build_flat_item_list. */ -static SPItem *find_item_at_point(std::deque *nodes, unsigned int dkey, Geom::Point const &p) +static SPItem *find_item_at_point(std::deque *nodes, unsigned int dkey, Geom::Point const &p, SPItem* upto=NULL) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0); SPItem *seen = NULL; SPItem *child; + bool seen_upto = (!upto); for (std::deque::const_iterator i = nodes->begin(); i != nodes->end(); ++i) { child = *i; + if (!seen_upto){ + if(child == upto) + seen_upto = true; + continue; + } Inkscape::DrawingItem *arenaitem = child->get_arenaitem(dkey); if (arenaitem && arenaitem->pick(p, delta, 1) != NULL) { @@ -1454,7 +1450,7 @@ std::vector SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom: return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps, false, into_groups); } -std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vector points, bool all_layers, size_t limit) +std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vector points, bool all_layers, size_t limit) const { std::vector items; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -1468,7 +1464,7 @@ std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vecto // Cache a flattened SVG DOM to speed up selection. if(!_node_cache_valid){ _node_cache.clear(); - build_flat_item_list(key, SP_GROUP(this->root), true, false, NULL); + build_flat_item_list(key, SP_GROUP(this->root), true); _node_cache_valid=true; } SPObject *current_layer = SP_ACTIVE_DESKTOP->currentLayer(); @@ -1499,18 +1495,26 @@ std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vecto } SPItem *SPDocument::getItemAtPoint( unsigned const key, Geom::Point const &p, - bool const into_groups, SPItem *upto) + bool const into_groups, SPItem *upto) const { g_return_val_if_fail(this->priv != NULL, NULL); // Build a flattened SVG DOM for find_item_at_point. - if(!_node_cache_valid){ + std::deque bak(_node_cache); + if(!into_groups){ _node_cache.clear(); - build_flat_item_list(key, SP_GROUP(this->root), into_groups, false, upto); - if(!upto) - _node_cache_valid = true; + build_flat_item_list(key, SP_GROUP(this->root), into_groups); } - return find_item_at_point(&_node_cache, key, p); + if(!_node_cache_valid && into_groups){ + _node_cache.clear(); + build_flat_item_list(key, SP_GROUP(this->root), true); + _node_cache_valid=true; + } + + SPItem *res = find_item_at_point(&_node_cache, key, p, upto); + if(!into_groups) + _node_cache = bak; + return res; } SPItem *SPDocument::getGroupAtPoint(unsigned int key, Geom::Point const &p) const diff --git a/src/document.h b/src/document.h index b57cf205d..825049cd5 100644 --- a/src/document.h +++ b/src/document.h @@ -263,8 +263,8 @@ public: const std::set getResourceList(char const *key) const; std::vector getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool into_groups = false) const; std::vector getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool into_groups = false) const; - SPItem *getItemAtPoint(unsigned int key, Geom::Point const &p, bool into_groups, SPItem *upto = NULL) ; - std::vector getItemsAtPoints(unsigned const key, std::vector points, bool all_layers = true, size_t limit = 0) ; + SPItem *getItemAtPoint(unsigned int key, Geom::Point const &p, bool into_groups, SPItem *upto = NULL) const; + std::vector getItemsAtPoints(unsigned const key, std::vector points, bool all_layers = true, size_t limit = 0) const ; SPItem *getGroupAtPoint(unsigned int key, Geom::Point const &p) const; void changeUriAndHrefs(char const *uri); @@ -278,9 +278,9 @@ private: void do_change_uri(char const *const filename, bool const rebase); void setupViewport(SPItemCtx *ctx); void importDefsNode(SPDocument *source, Inkscape::XML::Node *defs, Inkscape::XML::Node *target_defs); - bool build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL); - std::deque _node_cache; - bool _node_cache_valid; + void build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups) const; + mutable std::deque _node_cache; + mutable bool _node_cache_valid; }; /* -- cgit v1.2.3 From 0a8ee75592d561f5f1db5807c69902368b7baab8 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Thu, 18 Feb 2016 08:12:07 -0500 Subject: fix logic error in sbasis_to_cubic_bezier. (Bug 1545632) Fixed bugs: - https://launchpad.net/bugs/1545632 (bzr r14659) --- src/2geom/sbasis-to-bezier.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/2geom/sbasis-to-bezier.cpp b/src/2geom/sbasis-to-bezier.cpp index d9a90aace..8a18cfd4a 100644 --- a/src/2geom/sbasis-to-bezier.cpp +++ b/src/2geom/sbasis-to-bezier.cpp @@ -205,11 +205,11 @@ void sbasis_to_cubic_bezier (std::vector & bz, D2 const& sb) xprime[i] = sb[X][0][1] - sb[X][0][0]; yprime[i] = sb[Y][0][1] - sb[Y][0][0]; } - if (sb[X].size() > 0) { + if (sb[X].size() > 1) { xprime[0] += sb[X][1][0]; xprime[1] -= sb[X][1][1]; } - if (sb[Y].size() > 0) { + if (sb[Y].size() > 1) { yprime[0] += sb[Y][1][0]; yprime[1] -= sb[Y][1][1]; } -- cgit v1.2.3 From 086755c3ab56bd98232253c760d4e81ccd8701fb Mon Sep 17 00:00:00 2001 From: mathog <> Date: Thu, 18 Feb 2016 13:42:37 -0800 Subject: provide end user debugging for EMF and WMF issues (bzr r14660) --- src/extension/internal/emf-inout.cpp | 32 ++++++++++++++++++++++++++------ src/extension/internal/wmf-inout.cpp | 32 ++++++++++++++++++++++++++------ 2 files changed, 52 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp index 68b38f5ee..13520c40b 100644 --- a/src/extension/internal/emf-inout.cpp +++ b/src/extension/internal/emf-inout.cpp @@ -1617,6 +1617,17 @@ int Emf::myEnhMetaFileProc(char *contents, unsigned int length, PEMF_CALLBACK_DA uint32_t tbkMode = U_TRANSPARENT; // holds proposed change to bkMode, if text is involved saving these to the DC must wait until the text is written U_COLORREF tbkColor = U_RGB(255, 255, 255); // holds proposed change to bkColor + // code for end user debugging + int eDbgRecord=0; + int eDbgComment=0; + int eDbgFinal=0; + char const* eDbgString = getenv( "INKSCAPE_DBG_EMF" ); + if ( eDbgString != NULL ) { + if(strstr(eDbgString,"RECORD")){ eDbgRecord = 1; } + if(strstr(eDbgString,"COMMENT")){ eDbgComment = 1; } + if(strstr(eDbgString,"FINAL")){ eDbgFinal = 1; } + } + /* initialize the tsp for text reassembly */ tsp.string = NULL; tsp.ori = 0.0; /* degrees */ @@ -1659,8 +1670,11 @@ int Emf::myEnhMetaFileProc(char *contents, unsigned int length, PEMF_CALLBACK_DA lpEMFR = (PU_ENHMETARECORD)(contents + off); -// Uncomment the following to track down toxic records -// std::cout << "record type: " << iType << " name " << U_emr_names(iType) << " length: " << nSize << " offset: " << off <\n"; break; } //end of switch -// When testing, uncomment the following to place a comment for each processed EMR record in the SVG -// d->outsvg += dbg_str.str().c_str(); +// At run time define environment variable INKSCAPE_DBG_EMF to include string COMMENT. +// Users may employ this to to place a comment for each processed EMR record in the SVG + if(eDbgComment){ + d->outsvg += dbg_str.str().c_str(); + } d->outsvg += tmp_outsvg.str().c_str(); d->path += tmp_path.str().c_str(); } //end of while -// When testing, uncomment the following to show the final SVG derived from the EMF -// std::cout << d->outsvg << std::endl; +// At run time define environment variable INKSCAPE_DBG_EMF to include string FINAL +// Users may employ this to to show the final SVG derived from the EMF + if(eDbgFinal){ + std::cout << d->outsvg << std::endl; + } (void) emr_properties(U_EMR_INVALID); // force the release of the lookup table memory, returned value is irrelevant return(file_status); diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp index d17180d91..b8b0c73de 100644 --- a/src/extension/internal/wmf-inout.cpp +++ b/src/extension/internal/wmf-inout.cpp @@ -1528,6 +1528,17 @@ int Wmf::myMetaFileProc(const char *contents, unsigned int length, PWMF_CALLBACK uint16_t tbkMode = U_TRANSPARENT; // holds proposed change to bkMode, if text is involved saving these to the DC must wait until the text is written U_COLORREF tbkColor = U_RGB(255, 255, 255); // holds proposed change to bkColor + // code for end user debugging + int wDbgRecord=0; + int wDbgComment=0; + int wDbgFinal=0; + char const* wDbgString = getenv( "INKSCAPE_DBG_WMF" ); + if ( wDbgString != NULL ) { + if(strstr(wDbgString,"RECORD")){ wDbgRecord = 1; } + if(strstr(wDbgString,"COMMENT")){ wDbgComment = 1; } + if(strstr(wDbgString,"FINAL")){ wDbgFinal = 1; } + } + /* initialize the tsp for text reassembly */ tsp.string = NULL; tsp.ori = 0.0; /* degrees */ @@ -1692,8 +1703,11 @@ int Wmf::myMetaFileProc(const char *contents, unsigned int length, PWMF_CALLBACK file_status = 0; break; } -// Uncomment the following to track down toxic records -// std::cout << "record type: " << (int) iType << " name " << U_wmr_names(iType) << " length: " << nSize << " offset: " << off <\n"; break; } //end of switch -// When testing, uncomment the following to place a comment for each processed WMR record in the SVG -// d->outsvg += dbg_str.str().c_str(); +// At run time define environment variable INKSCAPE_DBG_WMF to include string COMMENT. +// Users may employ this to to place a comment for each processed WMR record in the SVG + if(wDbgComment){ + d->outsvg += dbg_str.str().c_str(); + } d->path += tmp_path.str().c_str(); if(!nSize){ // There was some problem with the processing of this record, it is not safe to continue file_status = 0; @@ -3043,8 +3060,11 @@ std::cout << "BEFORE DRAW" } } //end of while on OK -// When testing, uncomment the following to show the final SVG derived from the WMF -// std::cout << d->outsvg << std::endl; +// At run time define environment variable INKSCAPE_DBG_WMF to include string FINAL +// Users may employ this to to show the final SVG derived from the WMF + if(wDbgFinal){ + std::cout << d->outsvg << std::endl; + } (void) U_wmr_properties(U_WMR_INVALID); // force the release of the lookup table memory, returned value is irrelevant return(file_status); -- cgit v1.2.3 From 1ad64f2c1c3734d3d5f2ff2ecc52eb3acf9d3475 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 20 Feb 2016 08:19:01 +0100 Subject: Clarify meaning of line spacing. (bzr r14661) --- src/ui/dialog/text-edit.cpp | 4 ++-- src/widgets/text-toolbar.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 05cf3a388..c01da8864 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -127,8 +127,8 @@ TextEdit::TextEdit() gtk_combo_box_text_append_text((GtkComboBoxText *) spacing_combo, spacings[i]); } - gtk_widget_set_tooltip_text (px, _("Spacing between lines (percent of font size)")); - gtk_widget_set_tooltip_text (spacing_combo, _("Spacing between lines (percent of font size)")); + gtk_widget_set_tooltip_text (px, _("Spacing between baselines (percent of font size)")); + gtk_widget_set_tooltip_text (spacing_combo, _("Spacing between baselines (percent of font size)")); layout_hbox.pack_start(*Gtk::manage(Glib::wrap(spacing_combo)), false, false); layout_frame.set_padding(4,4,4,4); layout_frame.add(layout_hbox); diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index c6cc7dc45..5ca92b4c0 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -1592,7 +1592,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje "TextLineHeightAction", /* name */ _("Line Height"), /* label */ _("Line:"), /* short label */ - _("Spacing between lines (times font size)"), /* tooltip */ + _("Spacing between baselines (times font size)"), /* tooltip */ "/tools/text/lineheight", /* preferences path */ 0.0, /* default */ GTK_WIDGET(desktop->canvas), /* focusTarget */ -- cgit v1.2.3 From 212bb7b04ce7443e2070fb71e738abdffe738bd8 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 20 Feb 2016 13:06:07 +0100 Subject: Font size in status bar should use unit from text units preference. Patch from Tobias Ellinghaus. (bzr r14662) --- src/sp-text.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-text.cpp b/src/sp-text.cpp index c7dfdd694..afbe0b147 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -367,8 +367,11 @@ gchar* SPText::description() const { char *n = xml_quote_strdup( style->font_family.value ); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); Inkscape::Util::Quantity q = Inkscape::Util::Quantity(style->font_size.computed, "px"); - GString *xs = g_string_new(q.string(SP_ACTIVE_DESKTOP->getNamedView()->display_units).c_str()); + q.quantity *= this->i2doc_affine().descrim(); + GString *xs = g_string_new(q.string(sp_style_get_css_unit_string(unit)).c_str()); char const *trunc = ""; Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) this); -- cgit v1.2.3 From dfc7239e9f4a91bb6c32b80544d92012d92b410d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 21 Feb 2016 16:44:25 -0500 Subject: Apply from patch from houz (Fixes color profile name mangling) Fixed bugs: - https://launchpad.net/bugs/1457105 (bzr r14663) --- src/ui/dialog/document-properties.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 7cd48e62e..c2c5c5005 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -448,13 +448,13 @@ void DocumentProperties::populate_available_profiles(){ */ static void sanitizeName( Glib::ustring& str ) { - if (str.size() > 1) { + if (str.size() > 0) { char val = str.at(0); if (((val < 'A') || (val > 'Z')) && ((val < 'a') || (val > 'z')) && (val != '_') && (val != ':')) { - str.replace(0, 1, "-"); + str.insert(0, "_"); } for (Glib::ustring::size_type i = 1; i < str.size(); i++) { char val = str.at(i); -- cgit v1.2.3 From e16f1a053c67a8c42172f5186f247f11c3b6e777 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Mon, 22 Feb 2016 20:49:03 +0100 Subject: static code analysis (bzr r14664) --- src/desktop-style.cpp | 2 +- src/display/sp-canvas.cpp | 4 ++-- src/ui/tools/mesh-tool.cpp | 6 +++--- src/ui/tools/select-tool.cpp | 10 ++++++---- src/vanishing-point.cpp | 15 +++++++-------- src/vanishing-point.h | 1 + 6 files changed, 20 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 67c0687b7..a81cbdd1f 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -1267,7 +1267,7 @@ objects_query_writing_modes (const std::vector &objects, SPStyle *style int texts = 0; - for (std::vector::const_iterator i = objects.begin(); i != objects.end(); i++) { + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { SPObject *obj = *i; if (!isTextualItem(obj)) { diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 22765cb9d..ef47613e4 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -607,7 +607,7 @@ void sp_canvas_item_raise(SPCanvasItem *item, int positions) g_assert (l != parent->items.end()); for (int i=0; i<=positions && l != parent->items.end(); ++i) - l++; + ++l; parent->items.remove(item); parent->items.insert(l, item); @@ -656,7 +656,7 @@ void sp_canvas_item_lower(SPCanvasItem *item, int positions) g_assert (l != parent->items.end()); for (int i=0; iitems.begin(); ++i) - l--; + ++l; parent->items.remove(item); parent->items.insert(l, item); diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index 7db4e09d8..47927667c 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -458,7 +458,7 @@ bool MeshTool::root_handler(GdkEvent* event) { SPCtrlCurve *line = NULL; if (! drag->lines.empty()) { - for (std::vector::const_iterator l = drag->lines.begin(); l != drag->lines.end() && (!over_line); l++) { + for (std::vector::const_iterator l = drag->lines.begin(); l != drag->lines.end() && (!over_line); ++l) { line = (SPCtrlCurve*) (*l); over_line |= sp_mesh_context_is_over_line (this, (SPItem*) line, Geom::Point(event->motion.x, event->motion.y)); } @@ -594,7 +594,7 @@ bool MeshTool::root_handler(GdkEvent* event) { bool over_line = false; if (!drag->lines.empty()) { - for (std::vector::const_iterator l = drag->lines.begin(); l != drag->lines.end() ; l++) { + for (std::vector::const_iterator l = drag->lines.begin(); l != drag->lines.end() ; ++l) { over_line |= sp_mesh_context_is_over_line (this, (SPItem*)(*l), Geom::Point(event->motion.x, event->motion.y)); } } @@ -625,7 +625,7 @@ bool MeshTool::root_handler(GdkEvent* event) { SPCtrlLine *line = NULL; if (!drag->lines.empty()) { - for (std::vector::const_iterator l = drag->lines.begin(); l != drag->lines.end() && (!over_line); l++) { + for (std::vector::const_iterator l = drag->lines.begin(); l != drag->lines.end() && (!over_line); ++l) { line = (SPCtrlLine*)(*l); over_line = sp_mesh_context_is_over_line (this, (SPItem*) line, Geom::Point(event->motion.x, event->motion.y)); diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp index 2b85216d2..905e38f2b 100644 --- a/src/ui/tools/select-tool.cpp +++ b/src/ui/tools/select-tool.cpp @@ -405,13 +405,15 @@ void SelectTool::sp_select_context_cycle_through_items(Inkscape::Selection *sele // Find next item and activate it std::vector::iterator next = this->cycling_cur_item; if (scroll_event->direction == GDK_SCROLL_UP) { - next++; - if (next == this->cycling_items.end() && this->cycling_wrap) + ++next; + if (next == this->cycling_items.end() && this->cycling_wrap) { next = this->cycling_items.begin(); + } } else { - if(next == this->cycling_items.begin()) + if(next == this->cycling_items.begin()) { next = this->cycling_items.end(); - next--; + } + --next; } if (next!=this->cycling_items.end()) { diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp index 9ce60fce7..32ccbad93 100644 --- a/src/vanishing-point.cpp +++ b/src/vanishing-point.cpp @@ -269,15 +269,14 @@ VanishingPoint::selectedBoxes(Inkscape::Selection *sel) { return sel_boxes; } -VPDragger::VPDragger(VPDrag *parent, Geom::Point p, VanishingPoint &vp) +VPDragger::VPDragger(VPDrag *parent, Geom::Point p, VanishingPoint &vp) : + parent(parent), + knot(NULL), + point(p), + point_original(p), + dragging_started(false), + vps() { - this->parent = parent; - - this->point = p; - this->point_original = p; - - this->dragging_started = false; - if (vp.is_finite()) { // create the knot this->knot = new SPKnot(SP_ACTIVE_DESKTOP, NULL); diff --git a/src/vanishing-point.h b/src/vanishing-point.h index 28da8e7fa..ae2a88d6e 100644 --- a/src/vanishing-point.h +++ b/src/vanishing-point.h @@ -46,6 +46,7 @@ public: inline VanishingPoint &operator=(VanishingPoint const &rhs) { _persp = rhs._persp; _axis = rhs._axis; + my_counter = rhs.my_counter; return *this; } inline bool operator==(VanishingPoint const &rhs) const { -- cgit v1.2.3 From 4aca329e373b27be4f8171e9f6cf2c8e04d591bc Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Mon, 22 Feb 2016 21:16:54 +0100 Subject: static code analysis (bzr r14665) --- src/io/inkjar.cpp | 17 +++++++++++------ src/object-snapper.cpp | 1 - src/sp-mask.cpp | 8 ++++---- 3 files changed, 15 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/io/inkjar.cpp b/src/io/inkjar.cpp index fb1fedf55..345455c4a 100644 --- a/src/io/inkjar.cpp +++ b/src/io/inkjar.cpp @@ -103,14 +103,19 @@ bool JarFile::init_inflation() bool JarFile::open() { + if (_file != NULL) { + fclose(_file); + } if ((_file = fopen(_filename, "r")) == NULL) { - fprintf(stderr, "open failed.\n"); - return false; + fprintf(stderr, "open failed.\n"); + return false; + } + if (!init_inflation()) { + return false; + } + else { + return true; } - if (!init_inflation()) - return false; - - return true; } bool JarFile::close() diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 5b7874c61..3e559ee7a 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -641,7 +641,6 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(IntermSnapResults &isr, bool strict_snapping = _snapmanager->snapprefs.getStrictSnapping(); // Find all intersections of the constrained path with the snap target candidates - std::vector intersections; for (std::vector::const_iterator k = _paths_to_snap_to->begin(); k != _paths_to_snap_to->end(); ++k) { if (k->path_vector && _allowSourceToSnapToTarget(p.getSourceType(), (*k).target_type, strict_snapping)) { // Do the intersection math diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp index 7b9ab11c3..3537c7bac 100644 --- a/src/sp-mask.cpp +++ b/src/sp-mask.cpp @@ -139,12 +139,12 @@ void SPMask::update(SPCtx* ctx, unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; std::vector children = this->childList(false); - for (std::vector::const_iterator child = children.begin();child != children.end();child++) { + for (std::vector::const_iterator child = children.begin();child != children.end();++child) { sp_object_ref(*child); } - for (std::vector::const_iterator child = children.begin();child != children.end();child++) { + for (std::vector::const_iterator child = children.begin();child != children.end();++child) { if (flags || ((*child)->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { (*child)->updateDisplay(ctx, flags); } @@ -173,11 +173,11 @@ void SPMask::modified(unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; std::vector children = this->childList(false); - for (std::vector::const_iterator child = children.begin();child != children.end();child++) { + for (std::vector::const_iterator child = children.begin();child != children.end();++child) { sp_object_ref(*child); } - for (std::vector::const_iterator child = children.begin();child != children.end();child++) { + for (std::vector::const_iterator child = children.begin();child != children.end();++child) { if (flags || ((*child)->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { (*child)->emitModified(flags); } -- cgit v1.2.3 From 15506bfca06d27831d1b4c6e69db4df914f6def2 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 23 Feb 2016 08:23:59 +0100 Subject: Fix small code buglet; found by Kris with cppcheck. (bzr r14666) --- src/sp-marker.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-marker.cpp b/src/sp-marker.cpp index 88dfbe04e..3505e2fe8 100644 --- a/src/sp-marker.cpp +++ b/src/sp-marker.cpp @@ -394,7 +394,8 @@ sp_marker_show_instance ( SPMarker *marker, Inkscape::DrawingItem *parent, if (marker->orient_mode == MARKER_ORIENT_AUTO) { m = base; } else if (marker->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { - m = Geom::Rotate::from_degrees( 180.0 ) * base; + // m = Geom::Rotate::from_degrees( 180.0 ) * base; + // Rotating is done at rendering time if necessary m = base; } else { /* fixme: Orient units (Lauris) */ -- cgit v1.2.3 From a380bbcafa8d6ef58fa4149db9987d6a69b4b6f0 Mon Sep 17 00:00:00 2001 From: Bryce Harrington Date: Thu, 25 Feb 2016 10:48:51 -0800 Subject: inkview: Drop use of obsolete getopt This lets us drop getopt as a cmake requirement. Patch from rindolf, thanks! http://www.shlomifish.org/Files/files/code/inkscape-cmake-get-rid-of-getopt-check-2.diff (bzr r14668) --- src/inkview.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/inkview.cpp b/src/inkview.cpp index aab4b4a20..c0c6f0b2c 100644 --- a/src/inkview.cpp +++ b/src/inkview.cpp @@ -30,10 +30,6 @@ # include "config.h" #endif -#ifdef HAVE_GETOPT_H -#include -#endif - #include #include #include @@ -179,17 +175,22 @@ main (int argc, const char **argv) num_parsed_options = 0; // the list of arguments is in the net line - while ((option = getopt(argc, (char* const* )argv, "t:")) != -1) - { - switch(option) { - case 't': // for timer - // fprintf(stderr, "set timer arg %s\n", optarg ); - ss.timer = atoi(optarg); - num_parsed_options += 2; // 2 because of flag + option + for (int i = 1; i < argc; i++) { + if ((argv[i][0] == '-')) { + if (!strcmp(argv[i], "--")) { break; - case '?': - default: - usage(); + } + else if ((!strcmp(argv[i], "-t"))) { + if (i + 1 >= argc) { + usage(); + } + ss.timer = atoi(argv[i+1]); + num_parsed_options = i+1; + i++; + } + else { + usage(); + } } } -- cgit v1.2.3 From 1968410abdc6b7ad7631d62fa1677badac8caeab Mon Sep 17 00:00:00 2001 From: "Eduard Braun (eduard-braun2)" <> Date: Sat, 27 Feb 2016 12:53:28 +0100 Subject: UI. Fix for bug #1351597 (Inkscape + Cairo >= 1.12 very slow on Windows, unless rulers are hidden). Fixed bugs: - https://launchpad.net/bugs/1351597 (bzr r14670) --- src/widgets/ruler.cpp | 328 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 198 insertions(+), 130 deletions(-) (limited to 'src') diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index ab486eeeb..b722ecea7 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -41,8 +41,9 @@ #define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB -#define DEFAULT_RULER_FONT_SCALE PANGO_SCALE_X_SMALL -#define MINIMUM_INCR 5 +#define DEFAULT_RULER_FONT_SCALE PANGO_SCALE_X_SMALL +#define MINIMUM_INCR 5 +#define IMMEDIATE_REDRAW_THRESHOLD 20 using Inkscape::Util::unit_table; @@ -71,11 +72,11 @@ typedef struct GdkWindow *input_window; cairo_surface_t *backing_store; + gboolean backing_store_valid; + GdkRectangle last_pos_rect; + guint pos_redraw_idle_id; PangoLayout *layout; gdouble font_scale; - - gint xsrc; - gint ysrc; GList *track_widgets; } SPRulerPrivate; @@ -132,18 +133,22 @@ static void sp_ruler_style_updated (GtkWidget *widget); static void sp_ruler_size_request (GtkWidget *widget, GtkRequisition *requisition); static void sp_ruler_style_set (GtkWidget *widget, - GtkStyle *prev_style); + GtkStyle *prev_style); #endif static gboolean sp_ruler_motion_notify (GtkWidget *widget, GdkEventMotion *event); static gboolean sp_ruler_draw (GtkWidget *widget, - cairo_t *cr); + cairo_t *cr); #if !GTK_CHECK_VERSION(3,0,0) static gboolean sp_ruler_expose (GtkWidget *widget, GdkEventExpose *event); #endif static void sp_ruler_draw_ticks (SPRuler *ruler); +static GdkRectangle sp_ruler_get_pos_rect (SPRuler *ruler, + gdouble position); +static gboolean sp_ruler_idle_queue_pos_redraw(gpointer data); +static void sp_ruler_queue_pos_redraw (SPRuler *ruler); static void sp_ruler_draw_pos (SPRuler *ruler, cairo_t *cr); static void sp_ruler_make_pixmap (SPRuler *ruler); @@ -260,14 +265,23 @@ sp_ruler_init (SPRuler *ruler) gtk_widget_set_has_window (GTK_WIDGET (ruler), FALSE); - priv->orientation = GTK_ORIENTATION_HORIZONTAL; - priv->unit = unit_table.getUnit("px"); - priv->lower = 0; - priv->upper = 0; - priv->position = 0; - priv->max_size = 0; - priv->backing_store = NULL; - priv->font_scale = DEFAULT_RULER_FONT_SCALE; + priv->orientation = GTK_ORIENTATION_HORIZONTAL; + priv->unit = unit_table.getUnit("px"); + priv->lower = 0; + priv->upper = 0; + priv->position = 0; + priv->max_size = 0; + + priv->backing_store = NULL; + priv->backing_store_valid = FALSE; + + priv->last_pos_rect.x = 0; + priv->last_pos_rect.y = 0; + priv->last_pos_rect.width = 0; + priv->last_pos_rect.height = 0; + priv->pos_redraw_idle_id = 0; + + priv->font_scale = DEFAULT_RULER_FONT_SCALE; #if GTK_CHECK_VERSION(3,0,0) #if GTK_CHECK_VERSION(3,8,0) @@ -299,6 +313,12 @@ sp_ruler_dispose (GObject *object) while (priv->track_widgets) sp_ruler_remove_track_widget (ruler, GTK_WIDGET(priv->track_widgets->data)); + if (priv->pos_redraw_idle_id) + { + g_source_remove (priv->pos_redraw_idle_id); + priv->pos_redraw_idle_id = 0; + } + G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -343,6 +363,7 @@ sp_ruler_set_range (SPRuler *ruler, } g_object_thaw_notify (G_OBJECT (ruler)); + priv->backing_store_valid = FALSE; gtk_widget_queue_draw (GTK_WIDGET (ruler)); } @@ -513,7 +534,9 @@ sp_ruler_unrealize(GtkWidget *widget) cairo_surface_destroy (priv->backing_store); priv->backing_store = NULL; } - + + priv->backing_store_valid = FALSE; + if (priv->layout) { g_object_unref (priv->layout); @@ -689,7 +712,6 @@ sp_ruler_expose (GtkWidget *widget, cairo_clip (cr); gtk_widget_get_allocation (widget, &allocation); - cairo_translate (cr, allocation.x, allocation.y); gboolean result = sp_ruler_draw (widget, cr); @@ -733,6 +755,8 @@ sp_ruler_make_pixmap (SPRuler *ruler) CAIRO_CONTENT_COLOR, allocation.width, allocation.height); + + priv->backing_store_valid = FALSE; } static void @@ -743,118 +767,22 @@ sp_ruler_draw_pos (SPRuler *ruler, #if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *context = gtk_widget_get_style_context (widget); - GtkBorder border; GdkRGBA color; #else GtkStyle *style = gtk_widget_get_style (widget); GtkStateType state = gtk_widget_get_state (widget); - gint xthickness; - gint ythickness; #endif SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); - GtkAllocation allocation; - gint x, y; - gint width, height; - gint bs_width, bs_height; + GdkRectangle pos_rect; if (! gtk_widget_is_drawable (widget)) return; - gtk_widget_get_allocation(widget, &allocation); - -#if GTK_CHECK_VERSION(3,0,0) - gtk_style_context_get_border (context, static_cast(0), &border); -#else - xthickness = style->xthickness; - ythickness = style->ythickness; -#endif - - if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) - { - width = allocation.width; -#if GTK_CHECK_VERSION(3,0,0) - height = allocation.height - (border.top + border.bottom); -#else - height = allocation.height - ythickness * 2; -#endif - - bs_width = height / 2 + 2; - bs_width |= 1; /* make sure it's odd */ - bs_height = bs_width / 2 + 1; - } - else - { -#if GTK_CHECK_VERSION(3,0,0) - width = allocation.width - (border.left + border.right); -#else - width = allocation.width - xthickness * 2; -#endif - height = allocation.height; - - bs_height = width / 2 + 2; - bs_height |= 1; /* make sure it's odd */ - bs_width = bs_height / 2 + 1; - } + pos_rect = sp_ruler_get_pos_rect (ruler, sp_ruler_get_position (ruler)); - if ((bs_width > 0) && (bs_height > 0)) + if ((pos_rect.width > 0) && (pos_rect.height > 0)) { - gdouble lower; - gdouble upper; - gdouble position; - gdouble increment; - - if (! cr) - { - cr = gdk_cairo_create (gtk_widget_get_window (widget)); - cairo_translate (cr, allocation.x, allocation.y); - cairo_rectangle (cr, allocation.x, allocation.y, allocation.width, allocation.height); - cairo_clip (cr); - - cairo_translate (cr, allocation.x, allocation.y); - - /* If a backing store exists, restore the ruler */ - if (priv->backing_store) - { - cairo_set_source_surface (cr, priv->backing_store, 0, 0); - cairo_rectangle (cr, priv->xsrc, priv->ysrc, bs_width, bs_height); - cairo_fill (cr); - } - } - else - { - cairo_reference (cr); - } - - position = sp_ruler_get_position (ruler); - - sp_ruler_get_range (ruler, &lower, &upper, NULL); - - if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) - { - increment = (gdouble) width / (upper - lower); - -#if GTK_CHECK_VERSION(3,0,0) - x = ROUND ((position - lower) * increment) + (border.left - bs_width) / 2 - 1; - y = (height + bs_height) / 2 + border.top; -#else - x = ROUND ((position - lower) * increment) + (xthickness - bs_width) / 2 - 1; - y = (height + bs_height) / 2 + ythickness; -#endif - } - else - { - increment = (gdouble) height / (upper - lower); - -#if GTK_CHECK_VERSION(3,0,0) - x = (width + bs_width) / 2 + border.left; - y = ROUND ((position - lower) * increment) + (border.top - bs_height) / 2 - 1; -#else - x = (width + bs_width) / 2 + xthickness; - y = ROUND ((position - lower) * increment) + (ythickness - bs_height) / 2 - 1; -#endif - } - #if GTK_CHECK_VERSION(3,0,0) gtk_style_context_get_color (context, gtk_widget_get_state_flags (widget), &color); @@ -863,26 +791,28 @@ sp_ruler_draw_pos (SPRuler *ruler, gdk_cairo_set_source_color (cr, &style->fg[state]); #endif - cairo_move_to (cr, x, y); + cairo_move_to (cr, pos_rect.x, pos_rect.y); if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { - cairo_line_to (cr, x + bs_width / 2.0, y + bs_height); - cairo_line_to (cr, x + bs_width, y); + cairo_line_to (cr, pos_rect.x + pos_rect.width / 2.0, + pos_rect.y + pos_rect.height); + cairo_line_to (cr, pos_rect.x + pos_rect.width, + pos_rect.y); } else { - cairo_line_to (cr, x + bs_width, y + bs_height / 2.0); - cairo_line_to (cr, x, y + bs_height); + cairo_line_to (cr, pos_rect.x + pos_rect.width, + + pos_rect.y + pos_rect.height / 2.0); + cairo_line_to (cr, pos_rect.x, + pos_rect.y + pos_rect.height); } cairo_fill (cr); - - cairo_destroy (cr); - - priv->xsrc = x; - priv->ysrc = y; } + + priv->last_pos_rect = pos_rect; } /** @@ -1096,6 +1026,7 @@ sp_ruler_set_unit (SPRuler *ruler, priv->unit = unit; g_object_notify(G_OBJECT(ruler), "unit"); + priv->backing_store_valid = FALSE; gtk_widget_queue_draw (GTK_WIDGET (ruler)); } } @@ -1131,10 +1062,39 @@ sp_ruler_set_position (SPRuler *ruler, if (priv->position != position) { - priv->position = position; - g_object_notify (G_OBJECT (ruler), "position"); - - sp_ruler_draw_pos (ruler, NULL); + GdkRectangle rect; + gint xdiff, ydiff; + + priv->position = position; + g_object_notify (G_OBJECT (ruler), "position"); + + rect = sp_ruler_get_pos_rect (ruler, priv->position); + + xdiff = rect.x - priv->last_pos_rect.x; + ydiff = rect.y - priv->last_pos_rect.y; + + /* + * If the position has changed far enough, queue a redraw immediately. + * Otherwise, we only queue a redraw in a low priority idle handler, to + * allow for other things (like updating the canvas) to run. + * + * TODO: This might not be necessary any more in GTK3 with the frame + * clock. Investigate this more after the port to GTK3. + */ + if (priv->last_pos_rect.width != 0 && + priv->last_pos_rect.height != 0 && + (ABS (xdiff) > IMMEDIATE_REDRAW_THRESHOLD || + ABS (ydiff) > IMMEDIATE_REDRAW_THRESHOLD)) + { + sp_ruler_queue_pos_redraw (ruler); + } + else if (! priv->pos_redraw_idle_id) + { + priv->pos_redraw_idle_id = + g_idle_add_full (G_PRIORITY_LOW, + sp_ruler_idle_queue_pos_redraw, + ruler, NULL); + } } } @@ -1454,10 +1414,118 @@ sp_ruler_draw_ticks (SPRuler *ruler) cairo_fill (cr); + priv->backing_store_valid = TRUE; + out: cairo_destroy (cr); } +static GdkRectangle +sp_ruler_get_pos_rect (SPRuler *ruler, + gdouble position) +{ + GtkWidget *widget = GTK_WIDGET (ruler); + GtkStyle *style = gtk_widget_get_style (widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation allocation; + gint width, height; + gint xthickness; + gint ythickness; + gdouble upper, lower; + gdouble increment; + GdkRectangle rect = { 0, }; + + if (! gtk_widget_is_drawable (widget)) + return rect; + + gtk_widget_get_allocation (widget, &allocation); + + xthickness = style->xthickness; + ythickness = style->ythickness; + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + width = allocation.width; + height = allocation.height - ythickness * 2; + + rect.width = height / 2 + 2; + rect.width |= 1; /* make sure it's odd */ + rect.height = rect.width / 2 + 1; + } + else + { + width = allocation.width - xthickness * 2; + height = allocation.height; + + rect.height = width / 2 + 2; + rect.height |= 1; /* make sure it's odd */ + rect.width = rect.height / 2 + 1; + } + + sp_ruler_get_range (ruler, &lower, &upper, NULL); + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + increment = (gdouble) width / (upper - lower); + + rect.x = ROUND ((position - lower) * increment) + (xthickness - rect.width) / 2 - 1; + rect.y = (height + rect.height) / 2 + ythickness; + } + else + { + increment = (gdouble) height / (upper - lower); + + rect.x = (width + rect.width) / 2 + xthickness; + rect.y = ROUND ((position - lower) * increment) + (ythickness - rect.height) / 2 - 1; + } + + rect.x += allocation.x; + rect.y += allocation.y; + + return rect; +} + +static gboolean +sp_ruler_idle_queue_pos_redraw (gpointer data) +{ + SPRuler *ruler = (SPRuler *)data; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + + sp_ruler_queue_pos_redraw (ruler); + + gboolean ret = g_source_remove(priv->pos_redraw_idle_id); + priv->pos_redraw_idle_id = 0; + + return ret; +} + +static void +sp_ruler_queue_pos_redraw (SPRuler *ruler) +{ + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + const GdkRectangle rect = sp_ruler_get_pos_rect (ruler, priv->position); + + gtk_widget_queue_draw_area (GTK_WIDGET(ruler), + rect.x, + rect.y, + rect.width, + rect.height); + + if (priv->last_pos_rect.width != 0 || priv->last_pos_rect.height != 0) + { + gtk_widget_queue_draw_area (GTK_WIDGET(ruler), + priv->last_pos_rect.x, + priv->last_pos_rect.y, + priv->last_pos_rect.width, + priv->last_pos_rect.height); + + priv->last_pos_rect.x = 0; + priv->last_pos_rect.y = 0; + priv->last_pos_rect.width = 0; + priv->last_pos_rect.height = 0; + } +} + static PangoLayout* sp_ruler_create_layout (GtkWidget *widget, const gchar *text) -- cgit v1.2.3 From ee541fdb5f3096cf4805563eca091173a70ddf9e Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 27 Feb 2016 15:59:01 +0100 Subject: Fix miter-limit behavior to match SVG spec. (bzr r14671) --- src/helper/geom-pathstroke.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/helper/geom-pathstroke.cpp b/src/helper/geom-pathstroke.cpp index 52871ae2a..3ef4b15da 100644 --- a/src/helper/geom-pathstroke.cpp +++ b/src/helper/geom-pathstroke.cpp @@ -163,7 +163,9 @@ void miter_join_internal(join_data jd, bool clip) if (p.isFinite()) { // check size of miter Point point_on_path = incoming.finalPoint() + rot90(tang1)*width; - satisfied = distance(p, point_on_path) <= miter * 2.0 * width; + // SVG defines miter length as distance between inner intersection and outer intersection, + // which is twice the distance from p to point_on_path but width is half stroke width. + satisfied = distance(p, point_on_path) <= miter * width; if (satisfied) { // miter OK, check to see if we can do a relocation if (inc_ls) { @@ -175,7 +177,7 @@ void miter_join_internal(join_data jd, bool clip) // std::cout << " Clipping ------------ " << std::endl; // miter needs clipping, find two points Point bisector_versor = Line(point_on_path, p).versor(); - Point point_limit = point_on_path + miter * 2.0 * width * bisector_versor; + Point point_limit = point_on_path + miter * width * bisector_versor; // std::cout << " bisector_versor: " << bisector_versor << std::endl; // std::cout << " point_limit: " << point_limit << std::endl; Point p1 = intersection_point(incoming.finalPoint(), tang1, point_limit, bisector_versor.cw()); -- cgit v1.2.3 From e5af44c875cb512a58ec520328e974a09819d965 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Mon, 29 Feb 2016 09:06:33 +0100 Subject: Inkview. Code consistency fixes. (bzr r14674) --- src/inkview.cpp | 328 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 162 insertions(+), 166 deletions(-) (limited to 'src') diff --git a/src/inkview.cpp b/src/inkview.cpp index c0c6f0b2c..3fcd9ed8a 100644 --- a/src/inkview.cpp +++ b/src/inkview.cpp @@ -102,66 +102,67 @@ static GtkWidget *ctrlwin = NULL; int sp_main_gui (int, char const**) { return 0; } int sp_main_console (int, char const**) { return 0; } -static int -sp_svgview_main_delete (GtkWidget */*widget*/, GdkEvent */*event*/, struct SPSlideShow */*ss*/) +static int sp_svgview_main_delete (GtkWidget */*widget*/, + GdkEvent */*event*/, + struct SPSlideShow */*ss*/) { gtk_main_quit (); return FALSE; } -static int -sp_svgview_main_key_press (GtkWidget */*widget*/, GdkEventKey *event, struct SPSlideShow *ss) +static int sp_svgview_main_key_press (GtkWidget */*widget*/, + GdkEventKey *event, + struct SPSlideShow *ss) { switch (event->keyval) { - case GDK_KEY_Up: - case GDK_KEY_Home: - sp_svgview_goto_first(ss); - break; - case GDK_KEY_Down: - case GDK_KEY_End: - sp_svgview_goto_last(ss); - break; - case GDK_KEY_F11: - if (ss->fullscreen) { - gtk_window_unfullscreen (GTK_WINDOW(ss->window)); - ss->fullscreen = false; - } else { - gtk_window_fullscreen (GTK_WINDOW(ss->window)); - ss->fullscreen = true; - } - break; - case GDK_KEY_Return: - sp_svgview_control_show (ss); - break; - case GDK_KEY_KP_Page_Down: - case GDK_KEY_Page_Down: - case GDK_KEY_Right: - case GDK_KEY_space: - sp_svgview_show_next (ss); - break; - case GDK_KEY_KP_Page_Up: - case GDK_KEY_Page_Up: - case GDK_KEY_Left: - case GDK_KEY_BackSpace: - sp_svgview_show_prev (ss); - break; - case GDK_KEY_Escape: - case GDK_KEY_q: - case GDK_KEY_Q: - gtk_main_quit(); - break; - default: - break; + case GDK_KEY_Up: + case GDK_KEY_Home: + sp_svgview_goto_first(ss); + break; + case GDK_KEY_Down: + case GDK_KEY_End: + sp_svgview_goto_last(ss); + break; + case GDK_KEY_F11: + if (ss->fullscreen) { + gtk_window_unfullscreen (GTK_WINDOW(ss->window)); + ss->fullscreen = false; + } else { + gtk_window_fullscreen (GTK_WINDOW(ss->window)); + ss->fullscreen = true; + } + break; + case GDK_KEY_Return: + sp_svgview_control_show (ss); + break; + case GDK_KEY_KP_Page_Down: + case GDK_KEY_Page_Down: + case GDK_KEY_Right: + case GDK_KEY_space: + sp_svgview_show_next (ss); + break; + case GDK_KEY_KP_Page_Up: + case GDK_KEY_Page_Up: + case GDK_KEY_Left: + case GDK_KEY_BackSpace: + sp_svgview_show_prev (ss); + break; + case GDK_KEY_Escape: + case GDK_KEY_q: + case GDK_KEY_Q: + gtk_main_quit(); + break; + default: + break; } gtk_window_set_title(GTK_WINDOW(ss->window), ss->doc->getName()); return TRUE; } -int -main (int argc, const char **argv) +int main (int argc, const char **argv) { if (argc == 1) { - usage(); + usage(); } // Prevents errors like "Unable to wrap GdkPixbuf..." (in nr-filter-image.cpp for example) @@ -171,8 +172,7 @@ main (int argc, const char **argv) struct SPSlideShow ss; - int option, - num_parsed_options = 0; + int num_parsed_options = 0; // the list of arguments is in the net line for (int i = 1; i < argc; i++) { @@ -233,82 +233,84 @@ main (int argc, const char **argv) // starting at where the commandline options stopped parsing because // we want all the files to be in the list for (i = num_parsed_options + 1 ; i < argc; i++) { - struct stat st; - if (stat (argv[i], &st) - || !S_ISREG (st.st_mode) - || (st.st_size < 64)) { - fprintf(stderr, "could not open file %s\n", argv[i]); - } else { - -#ifdef WITH_INKJAR - if (is_jar(argv[i])) { - Inkjar::JarFileReader jar_file_reader(argv[i]); - for (;;) { - GByteArray *gba = jar_file_reader.get_next_file(); - if (gba == NULL) { - char *c_ptr; - gchar *last_filename = jar_file_reader.get_last_filename(); - if (last_filename == NULL) - break; - if ((c_ptr = std::strrchr(last_filename, '/')) != NULL) { - if (*(++c_ptr) == '\0') { - g_free(last_filename); - continue; - } - } - } else if (gba->len > 0) { - //::write(1, gba->data, gba->len); - /* Append to list */ - if (ss.length >= ss.size) { - /* Expand */ - ss.size <<= 1; - ss.slides = g_renew (char *, ss.slides, ss.size); - } - - ss.doc = SPDocument::createNewDocFromMem ((const gchar *)gba->data, - gba->len, - TRUE); - gchar *last_filename = jar_file_reader.get_last_filename(); - if (ss.doc) { - ss.slides[ss.length++] = strdup (last_filename); - (ss.doc)->setUri (last_filename); - } - g_byte_array_free(gba, TRUE); - g_free(last_filename); - } else - break; - } - } else { -#endif /* WITH_INKJAR */ - /* Append to list */ - if (ss.length >= ss.size) { - /* Expand */ - ss.size <<= 1; - ss.slides = g_renew (char *, ss.slides, ss.size); - - } + struct stat st; + if (stat (argv[i], &st) + || !S_ISREG (st.st_mode) + || (st.st_size < 64)) { + fprintf(stderr, "could not open file %s\n", argv[i]); + } else { + + #ifdef WITH_INKJAR + if (is_jar(argv[i])) { + Inkjar::JarFileReader jar_file_reader(argv[i]); + for (;;) { + GByteArray *gba = jar_file_reader.get_next_file(); + if (gba == NULL) { + char *c_ptr; + gchar *last_filename = jar_file_reader.get_last_filename(); + if (last_filename == NULL) + break; + if ((c_ptr = std::strrchr(last_filename, '/')) != NULL) { + if (*(++c_ptr) == '\0') { + g_free(last_filename); + continue; + } + } + } else if (gba->len > 0) { + //::write(1, gba->data, gba->len); + /* Append to list */ + if (ss.length >= ss.size) { + /* Expand */ + ss.size <<= 1; + ss.slides = g_renew (char *, ss.slides, ss.size); + } + + ss.doc = SPDocument::createNewDocFromMem ((const gchar *)gba->data, + gba->len, + TRUE); + gchar *last_filename = jar_file_reader.get_last_filename(); + if (ss.doc) { + ss.slides[ss.length++] = strdup (last_filename); + (ss.doc)->setUri (last_filename); + } + g_byte_array_free(gba, TRUE); + g_free(last_filename); + } else { + break; + } + } + } else { + #endif /* WITH_INKJAR */ + /* Append to list */ + if (ss.length >= ss.size) { + /* Expand */ + ss.size <<= 1; + ss.slides = g_renew (char *, ss.slides, ss.size); + } - ss.slides[ss.length++] = strdup (argv[i]); + ss.slides[ss.length++] = strdup (argv[i]); + if (!ss.doc) { + ss.doc = SPDocument::createNewDoc (ss.slides[ss.current], TRUE, false); if (!ss.doc) { - ss.doc = SPDocument::createNewDoc (ss.slides[ss.current], TRUE, false); - if (!ss.doc) - ++ss.current; - } -#ifdef WITH_INKJAR - } -#endif - } + ++ss.current; + } + } + #ifdef WITH_INKJAR + } + #endif + } } - if(!ss.doc) + if(!ss.doc) { return 1; /* none of the slides loadable */ - + } + w = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title( GTK_WINDOW(w), ss.doc->getName() ); gtk_window_set_default_size (GTK_WINDOW (w), - MIN ((int)(ss.doc)->getWidth().value("px"), (int)gdk_screen_width() - 64), - MIN ((int)(ss.doc)->getHeight().value("px"), (int)gdk_screen_height() - 64)); + MIN ((int)(ss.doc)->getWidth().value("px"), (int)gdk_screen_width() - 64), + MIN ((int)(ss.doc)->getHeight().value("px"), (int)gdk_screen_height() - 64)); ss.window = w; g_signal_connect (G_OBJECT (w), "delete_event", (GCallback) sp_svgview_main_delete, &ss); @@ -328,8 +330,9 @@ main (int argc, const char **argv) return 0; } -static int -sp_svgview_ctrlwin_delete (GtkWidget */*widget*/, GdkEvent */*event*/, void */*data*/) +static int sp_svgview_ctrlwin_delete (GtkWidget */*widget*/, + GdkEvent */*event*/, + void */*data*/) { ctrlwin = NULL; return FALSE; @@ -338,97 +341,92 @@ sp_svgview_ctrlwin_delete (GtkWidget */*widget*/, GdkEvent */*event*/, void */*d static GtkWidget* sp_svgview_control_show(struct SPSlideShow *ss) { if (!ctrlwin) { - ctrlwin = gtk_window_new(GTK_WINDOW_TOPLEVEL); + ctrlwin = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_resizable(GTK_WINDOW(ctrlwin), FALSE); gtk_window_set_transient_for(GTK_WINDOW(ctrlwin), GTK_WINDOW(ss->window)); g_signal_connect(G_OBJECT (ctrlwin), "key_press_event", (GCallback) sp_svgview_main_key_press, ss); g_signal_connect(G_OBJECT (ctrlwin), "delete_event", (GCallback) sp_svgview_ctrlwin_delete, NULL); #if GTK_CHECK_VERSION(3,0,0) - GtkWidget *t = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); + GtkWidget *t = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); #else - GtkWidget *t = gtk_hbutton_box_new(); + GtkWidget *t = gtk_hbutton_box_new(); #endif - gtk_container_add(GTK_CONTAINER(ctrlwin), t); + gtk_container_add(GTK_CONTAINER(ctrlwin), t); #if GTK_CHECK_VERSION(3,10,0) GtkWidget *b = gtk_button_new_from_icon_name(INKSCAPE_ICON("go-first"), GTK_ICON_SIZE_BUTTON); #else - GtkWidget *b = gtk_button_new(); + GtkWidget *b = gtk_button_new(); GtkWidget *img = gtk_image_new_from_icon_name(INKSCAPE_ICON("go-first"), GTK_ICON_SIZE_BUTTON); gtk_button_set_image(GTK_BUTTON(b), img); #endif - gtk_container_add(GTK_CONTAINER(t), b); + gtk_container_add(GTK_CONTAINER(t), b); - g_signal_connect(G_OBJECT(b), "clicked", (GCallback) sp_svgview_goto_first_cb, ss); + g_signal_connect(G_OBJECT(b), "clicked", (GCallback) sp_svgview_goto_first_cb, ss); #if GTK_CHECK_VERSION(3,10,0) b = gtk_button_new_from_icon_name(INKSCAPE_ICON("go-previous"), GTK_ICON_SIZE_BUTTON); #else - b = gtk_button_new(); + b = gtk_button_new(); img = gtk_image_new_from_icon_name(INKSCAPE_ICON("go-previous"), GTK_ICON_SIZE_BUTTON); gtk_button_set_image(GTK_BUTTON(b), img); #endif - gtk_container_add(GTK_CONTAINER(t), b); + gtk_container_add(GTK_CONTAINER(t), b); - g_signal_connect(G_OBJECT(b), "clicked", (GCallback) sp_svgview_show_prev_cb, ss); + g_signal_connect(G_OBJECT(b), "clicked", (GCallback) sp_svgview_show_prev_cb, ss); #if GTK_CHECK_VERSION(3,10,0) b = gtk_button_new_from_icon_name(INKSCAPE_ICON("go-next"), GTK_ICON_SIZE_BUTTON); #else - b = gtk_button_new(); + b = gtk_button_new(); img = gtk_image_new_from_icon_name(INKSCAPE_ICON("go-next"), GTK_ICON_SIZE_BUTTON); gtk_button_set_image(GTK_BUTTON(b), img); #endif - gtk_container_add(GTK_CONTAINER(t), b); + gtk_container_add(GTK_CONTAINER(t), b); - g_signal_connect(G_OBJECT(b), "clicked", (GCallback) sp_svgview_show_next_cb, ss); + g_signal_connect(G_OBJECT(b), "clicked", (GCallback) sp_svgview_show_next_cb, ss); #if GTK_CHECK_VERSION(3,10,0) b = gtk_button_new_from_icon_name(INKSCAPE_ICON("go-last"), GTK_ICON_SIZE_BUTTON); #else - b = gtk_button_new(); + b = gtk_button_new(); img = gtk_image_new_from_icon_name(INKSCAPE_ICON("go-last"), GTK_ICON_SIZE_BUTTON); gtk_button_set_image(GTK_BUTTON(b), img); #endif - gtk_container_add(GTK_CONTAINER(t), b); - g_signal_connect(G_OBJECT(b), "clicked", (GCallback) sp_svgview_goto_last_cb, ss); - gtk_widget_show_all(ctrlwin); + gtk_container_add(GTK_CONTAINER(t), b); + g_signal_connect(G_OBJECT(b), "clicked", (GCallback) sp_svgview_goto_last_cb, ss); + gtk_widget_show_all(ctrlwin); } else { - gtk_window_present(GTK_WINDOW(ctrlwin)); + gtk_window_present(GTK_WINDOW(ctrlwin)); } return NULL; } -static int -sp_svgview_show_next_cb (GtkWidget */*widget*/, void *data) +static int sp_svgview_show_next_cb (GtkWidget */*widget*/, void *data) { sp_svgview_show_next(static_cast(data)); return FALSE; } -static int -sp_svgview_show_prev_cb (GtkWidget */*widget*/, void *data) +static int sp_svgview_show_prev_cb (GtkWidget */*widget*/, void *data) { sp_svgview_show_prev(static_cast(data)); return FALSE; } -static int -sp_svgview_goto_first_cb (GtkWidget */*widget*/, void *data) +static int sp_svgview_goto_first_cb (GtkWidget */*widget*/, void *data) { sp_svgview_goto_first(static_cast(data)); return FALSE; } -static int -sp_svgview_goto_last_cb (GtkWidget */*widget*/, void *data) +static int sp_svgview_goto_last_cb (GtkWidget */*widget*/, void *data) { sp_svgview_goto_last(static_cast(data)); return FALSE; } -static void -sp_svgview_waiting_cursor(struct SPSlideShow *ss) +static void sp_svgview_waiting_cursor(struct SPSlideShow *ss) { GdkCursor *waiting = gdk_cursor_new(GDK_WATCH); gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(ss->window)), waiting); @@ -446,12 +444,12 @@ sp_svgview_waiting_cursor(struct SPSlideShow *ss) gdk_cursor_unref(waiting); #endif } - while(gtk_events_pending()) + while(gtk_events_pending()) { gtk_main_iteration(); + } } -static void -sp_svgview_normal_cursor(struct SPSlideShow *ss) +static void sp_svgview_normal_cursor(struct SPSlideShow *ss) { gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(ss->window)), NULL); if (ctrlwin) { @@ -459,8 +457,9 @@ sp_svgview_normal_cursor(struct SPSlideShow *ss) } } -static void -sp_svgview_set_document(struct SPSlideShow *ss, SPDocument *doc, int current) +static void sp_svgview_set_document(struct SPSlideShow *ss, + SPDocument *doc, + int current) { if (doc && doc != ss->doc) { doc->ensureUpToDate(); @@ -470,8 +469,7 @@ sp_svgview_set_document(struct SPSlideShow *ss, SPDocument *doc, int current) } } -static void -sp_svgview_show_next (struct SPSlideShow *ss) +static void sp_svgview_show_next (struct SPSlideShow *ss) { sp_svgview_waiting_cursor(ss); @@ -486,8 +484,7 @@ sp_svgview_show_next (struct SPSlideShow *ss) sp_svgview_normal_cursor(ss); } -static void -sp_svgview_show_prev (struct SPSlideShow *ss) +static void sp_svgview_show_prev (struct SPSlideShow *ss) { sp_svgview_waiting_cursor(ss); @@ -502,16 +499,16 @@ sp_svgview_show_prev (struct SPSlideShow *ss) sp_svgview_normal_cursor(ss); } -static void -sp_svgview_goto_first (struct SPSlideShow *ss) +static void sp_svgview_goto_first (struct SPSlideShow *ss) { sp_svgview_waiting_cursor(ss); SPDocument *doc = NULL; int current = 0; while ( !doc && (current < ss->length - 1)) { - if (current == ss->current) + if (current == ss->current) { break; + } doc = SPDocument::createNewDoc (ss->slides[current++], TRUE, false); } @@ -520,16 +517,16 @@ sp_svgview_goto_first (struct SPSlideShow *ss) sp_svgview_normal_cursor(ss); } -static void -sp_svgview_goto_last (struct SPSlideShow *ss) +static void sp_svgview_goto_last (struct SPSlideShow *ss) { sp_svgview_waiting_cursor(ss); SPDocument *doc = NULL; int current = ss->length - 1; while (!doc && (current >= 0)) { - if (current == ss->current) + if (current == ss->current) { break; + } doc = SPDocument::createNewDoc (ss->slides[current--], TRUE, false); } @@ -539,8 +536,7 @@ sp_svgview_goto_last (struct SPSlideShow *ss) } #ifdef WITH_INKJAR -static bool -is_jar(char const *filename) +static bool is_jar(char const *filename) { /* fixme: Check MIME type or something. /usr/share/misc/file/magic suggests that checking for initial string "PK\003\004" in content should suffice. */ @@ -557,12 +553,12 @@ is_jar(char const *filename) static void usage() { fprintf(stderr, - "Usage: inkview [OPTIONS...] [FILES ...]\n" - "\twhere FILES are SVG (.svg or .svgz)" + "Usage: inkview [OPTIONS...] [FILES ...]\n" + "\twhere FILES are SVG (.svg or .svgz)" #ifdef WITH_INKJAR - " or archives of SVGs (.sxw, .jar)" + " or archives of SVGs (.sxw, .jar)" #endif - "\n"); + "\n"); exit(1); } -- cgit v1.2.3 From 42a5da69a0042b89907e58a613ce6b4a4c157ea8 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Mon, 29 Feb 2016 10:54:01 +0100 Subject: Code-design. Fixing variable initialization warnings and replacing tabs with spaces. (bzr r14675) --- src/widgets/ruler.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index b722ecea7..3a5e76277 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -1114,7 +1114,7 @@ sp_ruler_get_position (SPRuler *ruler) static gboolean sp_ruler_motion_notify (GtkWidget *widget, - GdkEventMotion *event) + GdkEventMotion *event) { SPRuler *ruler = SP_RULER(widget); @@ -1307,7 +1307,7 @@ sp_ruler_draw_ticks (SPRuler *ruler) if (ideal_length > ++length) length = ideal_length; - if (lower < upper) + if (lower < upper) { start = floor (lower / subd_incr) * subd_incr; end = ceil (upper / subd_incr) * subd_incr; @@ -1373,16 +1373,16 @@ sp_ruler_draw_ticks (SPRuler *ruler) pango_layout_get_extents (layout, &logical_rect, NULL); #if GTK_CHECK_VERSION(3,0,0) - cairo_move_to (cr, + cairo_move_to (cr, pos + 2, border.top + PANGO_PIXELS (logical_rect.y - digit_offset)); #else - cairo_move_to (cr, + cairo_move_to (cr, pos + 2, ythickness + PANGO_PIXELS (logical_rect.y - digit_offset)); #endif - pango_cairo_show_layout(cr, layout); + pango_cairo_show_layout(cr, layout); } else { @@ -1395,15 +1395,15 @@ sp_ruler_draw_ticks (SPRuler *ruler) pango_layout_get_extents (layout, NULL, &logical_rect); #if GTK_CHECK_VERSION(3,0,0) - cairo_move_to (cr, + cairo_move_to (cr, border.left + 1, pos + digit_height * j + 2 + PANGO_PIXELS (logical_rect.y - digit_offset)); #else - cairo_move_to (cr, + cairo_move_to (cr, xthickness + 1, pos + digit_height * j + 2 + PANGO_PIXELS (logical_rect.y - digit_offset)); #endif - pango_cairo_show_layout (cr, layout); + pango_cairo_show_layout (cr, layout); } } } @@ -1433,7 +1433,7 @@ sp_ruler_get_pos_rect (SPRuler *ruler, gint ythickness; gdouble upper, lower; gdouble increment; - GdkRectangle rect = { 0, }; + GdkRectangle rect = { 0, 0, 0, 0 }; if (! gtk_widget_is_drawable (widget)) return rect; -- cgit v1.2.3 From df60915bd9b41940cd58b5d0016e7746cf85cb95 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Mon, 29 Feb 2016 18:37:19 +0100 Subject: type in commit r14664 (bzr r14676) --- src/display/sp-canvas.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index ef47613e4..d17271752 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -656,7 +656,7 @@ void sp_canvas_item_lower(SPCanvasItem *item, int positions) g_assert (l != parent->items.end()); for (int i=0; iitems.begin(); ++i) - ++l; + --l; parent->items.remove(item); parent->items.insert(l, item); -- cgit v1.2.3 From 5234acfed2a47dc2445475ec7a9e245f0f8dc729 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 1 Mar 2016 02:39:05 +0100 Subject: Improve fill rule and add mass option (bzr r14648.1.2) --- src/ui/tools/eraser-tool.cpp | 62 +++++++++++++++++++++++++------------ src/widgets/eraser-toolbar.cpp | 69 +++++++++++++++++++++++++++++++++++++++--- src/widgets/toolbox.cpp | 3 ++ 3 files changed, 111 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp index 51068a3ae..698415480 100644 --- a/src/ui/tools/eraser-tool.cpp +++ b/src/ui/tools/eraser-tool.cpp @@ -64,8 +64,11 @@ #include "livarot/Shape.h" #include "document-undo.h" #include "verbs.h" +#include "style.h" +#include "style-enums.h" #include <2geom/math-utils.h> #include <2geom/pathvector.h> +#include "path-chemistry.h" #include "display/curve.h" #include "ui/tools/eraser-tool.h" @@ -376,7 +379,8 @@ void EraserTool::cancel() { bool EraserTool::root_handler(GdkEvent* event) { gint ret = FALSE; - + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0; switch (event->type) { case GDK_BUTTON_PRESS: if (event->button.button == 1 && !this->space_panning) { @@ -396,10 +400,10 @@ bool EraserTool::root_handler(GdkEvent* event) { if (this->repr) { this->repr = NULL; } - - Inkscape::Rubberband::get(desktop)->start(desktop, button_dt); - Inkscape::Rubberband::get(desktop)->setMode(RUBBERBAND_MODE_TOUCHPATH); - + if ( ! eraserMode ) { + Inkscape::Rubberband::get(desktop)->start(desktop, button_dt); + Inkscape::Rubberband::get(desktop)->setMode(RUBBERBAND_MODE_TOUCHPATH); + } /* initialize first point */ this->npoints = 0; @@ -444,8 +448,9 @@ bool EraserTool::root_handler(GdkEvent* event) { ret = TRUE; } - - Inkscape::Rubberband::get(desktop)->move(motion_dt); + if ( !eraserMode ) { + Inkscape::Rubberband::get(desktop)->move(motion_dt); + } } break; @@ -485,7 +490,7 @@ bool EraserTool::root_handler(GdkEvent* event) { ret = TRUE; } - if (Inkscape::Rubberband::get(desktop)->is_started()) { + if (!eraserMode && Inkscape::Rubberband::get(desktop)->is_started()) { Inkscape::Rubberband::get(desktop)->stop(); } @@ -572,8 +577,9 @@ bool EraserTool::root_handler(GdkEvent* event) { break; case GDK_KEY_Escape: - Inkscape::Rubberband::get(desktop)->stop(); - + if ( !eraserMode ) { + Inkscape::Rubberband::get(desktop)->stop(); + } if (this->is_drawing) { // if drawing, cancel, otherwise pass it up for deselecting this->cancel(); @@ -645,7 +651,7 @@ void EraserTool::set_to_accumulated() { this->repr = repr; } - SPItem *item=SP_ITEM(desktop->currentLayer()->appendChildRepr(this->repr)); + SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(this->repr)); Inkscape::GC::release(this->repr); item->updateRepr(); Geom::PathVector pathv = this->accumulated->get_pathvector() * desktop->dt2doc(); @@ -654,11 +660,11 @@ void EraserTool::set_to_accumulated() { g_assert( str != NULL ); this->repr->setAttribute("d", str); g_free(str); + if ( this->repr ) { bool wasSelection = false; Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0; Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); @@ -675,32 +681,50 @@ void EraserTool::set_to_accumulated() { } toWorkOn.erase(std::remove(toWorkOn.begin(), toWorkOn.end(), acid), toWorkOn.end()); } else { - toWorkOn= selection->itemList(); + toWorkOn = selection->itemList(); wasSelection = true; } if ( !toWorkOn.empty() ) { if ( eraserMode ) { for (std::vector::const_iterator i = toWorkOn.begin(); i != toWorkOn.end(); ++i){ - SPItem *item = *i; + SPItem *item = *i; + SPUse *use = dynamic_cast(item); + if (SP_IS_GROUP(item) || use ) { + continue; + } Geom::OptRect bbox = item->desktopVisualBounds(); if (bbox && bbox->intersects(*eraserBbox)) { Inkscape::XML::Node* dup = this->repr->duplicate(xml_doc); this->repr->parent()->appendChild(dup); Inkscape::GC::release(dup); // parent takes over - - selection->set(item); - selection->add(dup); + selection->set(dup); + sp_selected_path_union(selection, desktop); + selection->add(item); + if(item->style->fill_rule.value == SP_WIND_RULE_EVENODD){ + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "fill-rule", "evenodd"); + sp_desktop_set_style(desktop, css); + sp_repr_css_attr_unref(css); + css = 0; + } if (this->nowidth) { sp_selected_path_cut_skip_undo(selection, desktop); } else { sp_selected_path_diff_skip_undo(selection, desktop); } workDone = true; // TODO set this only if something was cut. - + bool break_apart = prefs->getBool("/tools/eraser/break_apart", false); + if(!break_apart){ + sp_selected_path_combine(desktop); + } else { + if(!this->nowidth){ + sp_selected_path_break_apart(desktop); + } + } if ( !selection->isEmpty() ) { // If the item was not completely erased, track the new remainder. - std::vector nowSel(selection->itemList()); + std::vector nowSel(selection->itemList()); for (std::vector::const_iterator i2 = nowSel.begin();i2!=nowSel.end();++i2) { remainingItems.push_back(*i2); } diff --git a/src/widgets/eraser-toolbar.cpp b/src/widgets/eraser-toolbar.cpp index f18a805b2..1fc520185 100644 --- a/src/widgets/eraser-toolbar.cpp +++ b/src/widgets/eraser-toolbar.cpp @@ -57,6 +57,13 @@ static void sp_erc_width_value_changed( GtkAdjustment *adj, GObject *tbl ) update_presets_list(tbl); } +static void sp_erc_mass_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/eraser/mass", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) { SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); @@ -65,7 +72,15 @@ static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setBool( "/tools/eraser/mode", eraserMode ); } - + GtkAction *split = GTK_ACTION( g_object_get_data(tbl, "split") ); + GtkAction *mass = GTK_ACTION( g_object_get_data(tbl, "mass") ); + if(eraserMode == TRUE){ + gtk_action_set_visible( split, TRUE ); + gtk_action_set_visible( mass, TRUE ); + } else { + gtk_action_set_visible( split, FALSE ); + gtk_action_set_visible( mass, FALSE ); + } // only take action if run by the attr_changed listener if (!g_object_get_data( tbl, "freeze" )) { // in turn, prevent listener from responding @@ -82,11 +97,20 @@ static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) } } +static void sp_toogle_break_apart( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/eraser/break_apart", active); +} + void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { + Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gint eraserMode = FALSE; { GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); - GtkTreeIter iter; gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, @@ -113,9 +137,8 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb ege_select_one_action_set_icon_column( act, 2 ); ege_select_one_action_set_tooltip_column( act, 1 ); - /// @todo Convert to boolean? Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0; + eraserMode = prefs->getBool("/tools/eraser/mode") ? TRUE : FALSE; ege_select_one_action_set_active( act, eraserMode ); g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_erasertb_mode_changed), holder ); } @@ -136,6 +159,44 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); } + { + /* Mass */ + gchar const* labels[] = {_("(no inertia)"), _("(slight smoothing, default)"), _("(noticeable lagging)"), 0, 0, _("(maximum inertia)")}; + gdouble values[] = {0.0, 2, 10, 20, 50, 100}; + EgeAdjustmentAction* eact = create_adjustment_action( "EraserMassAction", + _("Eraser Mass"), _("Mass:"), + _("Increase to make the eraser drag behind, as if slowed by inertia"), + "/tools/eraser/mass", 10.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 100, 1, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_erc_mass_value_changed, NULL /*unit tracker*/, 1, 0); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + g_object_set_data( holder, "mass", eact ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + /* Overlap */ + { + InkToggleAction* act = ink_toggle_action_new( "EraserBreakAppart", + _("Break appart cutted items"), + _("Break appart cutted itemss"), + INKSCAPE_ICON("distribute-randomize"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/eraser/break_apart", false) ); + g_object_set_data( holder, "split", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toogle_break_apart), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + GtkAction *split = GTK_ACTION( g_object_get_data(holder, "split") ); + GtkAction *mass = GTK_ACTION( g_object_get_data(holder, "mass") ); + if(eraserMode == TRUE){ + gtk_action_set_visible( split, TRUE ); + gtk_action_set_visible( mass, TRUE ); + } else { + gtk_action_set_visible( split, FALSE ); + gtk_action_set_visible( mass, FALSE ); + } } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 6787ef6cc..72537f727 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -497,6 +497,9 @@ static gchar const * ui_descr = " " " " " " + " " + " " + " " " " " " -- cgit v1.2.3 From fb08e5217a32dbfaf097cb26d67d9d7e0f5b718e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 1 Mar 2016 12:03:12 +0100 Subject: Fix a bug with 0 width shapes (bzr r14648.1.4) --- src/ui/tools/eraser-tool.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp index 698415480..b34a2d3ce 100644 --- a/src/ui/tools/eraser-tool.cpp +++ b/src/ui/tools/eraser-tool.cpp @@ -699,7 +699,9 @@ void EraserTool::set_to_accumulated() { this->repr->parent()->appendChild(dup); Inkscape::GC::release(dup); // parent takes over selection->set(dup); - sp_selected_path_union(selection, desktop); + if (!this->nowidth) { + sp_selected_path_union(selection, desktop); + } selection->add(item); if(item->style->fill_rule.value == SP_WIND_RULE_EVENODD){ SPCSSAttr *css = sp_repr_css_attr_new(); -- cgit v1.2.3 From 7e69baf4baa9d56e51782e80958386a806c78eac Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 2 Mar 2016 14:34:33 +0100 Subject: Another small change to miter-limit for 'arcs' join to match SVG spec. (bzr r14677) --- src/helper/geom-pathstroke.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/helper/geom-pathstroke.cpp b/src/helper/geom-pathstroke.cpp index 3ef4b15da..d2e9f9a1b 100644 --- a/src/helper/geom-pathstroke.cpp +++ b/src/helper/geom-pathstroke.cpp @@ -557,7 +557,7 @@ void extrapolate_join_internal(join_data jd, int alternative) Geom::Line bisector_chord = make_bisector_line(chord); Geom::Line limit_line; - double miter_limit = 2.0 * width * miter; + double miter_limit = width * miter; bool clipped = false; if (are_parallel(bisector_chord, ortho)) { -- cgit v1.2.3 From 4aba6b92f30733f400891d2c3a6d77c1ae1d7a47 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 2 Mar 2016 20:34:31 +0100 Subject: Fix for bug 1540070 Fixed bugs: - https://launchpad.net/bugs/1540070 (bzr r14678) --- src/live_effects/effect.cpp | 3 +- src/live_effects/effect.h | 2 + src/live_effects/lpe-bendpath.cpp | 5 +- src/live_effects/lpe-copy_rotate.cpp | 5 +- src/live_effects/lpe-envelope.cpp | 4 +- src/live_effects/lpe-lattice.cpp | 5 +- src/live_effects/lpe-lattice2.cpp | 4 +- src/live_effects/lpe-mirror_symmetry.cpp | 10 +- src/live_effects/lpe-mirror_symmetry.h | 2 - src/live_effects/lpe-offset.cpp | 10 +- src/live_effects/lpe-offset.h | 2 - src/live_effects/lpe-perspective-envelope.cpp | 4 +- src/live_effects/lpe-perspective_path.cpp | 3 +- src/live_effects/lpe-roughen.cpp | 4 +- src/live_effects/lpe-simplify.cpp | 4 +- src/live_effects/lpe-transform_2pts.cpp | 3 +- src/live_effects/lpe-vonkoch.cpp | 5 +- src/sp-lpe-item.cpp | 202 +++++++++----------------- src/sp-lpe-item.h | 4 +- 19 files changed, 91 insertions(+), 190 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index fe7bf3a97..47fd02554 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -356,7 +356,8 @@ Effect::createAndApply(EffectType type, SPDocument *doc, SPItem *item) } Effect::Effect(LivePathEffectObject *lpeobject) - : _provides_knotholder_entities(false), + : apply_to_clippath_and_mask(false), + _provides_knotholder_entities(false), oncanvasedit_it(0), is_visible(_("Is visible?"), _("If unchecked, the effect remains applied to the object but is temporarily disabled on canvas"), "is_visible", &wr, this, true), show_orig_path(false), diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index ea57ff243..898e089b7 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -121,6 +121,7 @@ public: inline bool isVisible() const { return is_visible; } void editNextParamOncanvas(SPItem * item, SPDesktop * desktop); + bool apply_to_clippath_and_mask; protected: Effect(LivePathEffectObject *lpeobject); @@ -144,6 +145,7 @@ protected: std::vector param_vector; bool _provides_knotholder_entities; + int oncanvasedit_it; BoolParam is_visible; diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index d7c0b69a4..bc112285f 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -81,6 +81,7 @@ LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) : prop_scale.param_set_increments(0.01, 0.10); _provides_knotholder_entities = true; + apply_to_clippath_and_mask = true; concatenate_before_pwd2 = true; } @@ -95,10 +96,6 @@ LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) // get the item bounding box original_bbox(lpeitem); original_height = boundingbox_Y.max() - boundingbox_Y.min(); - SPLPEItem * item = const_cast(lpeitem); - - item->apply_to_clippath(item); - item->apply_to_mask(item); } Geom::Piecewise > diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 87d8f05a9..8dfaf7525 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -61,6 +61,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : { show_orig_path = true; _provides_knotholder_entities = true; + apply_to_clippath_and_mask = true; // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter(&copiesTo360); @@ -111,10 +112,6 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) if(copiesTo360 ){ rot_pos = origin; } - SPLPEItem * item = const_cast(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); - } diff --git a/src/live_effects/lpe-envelope.cpp b/src/live_effects/lpe-envelope.cpp index 05a672ae8..e873c0b15 100644 --- a/src/live_effects/lpe-envelope.cpp +++ b/src/live_effects/lpe-envelope.cpp @@ -42,6 +42,7 @@ LPEEnvelope::LPEEnvelope(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast(&bend_path3) ); registerParameter( dynamic_cast(&bend_path4) ); concatenate_before_pwd2 = true; + apply_to_clippath_and_mask = true; } LPEEnvelope::~LPEEnvelope() @@ -54,9 +55,6 @@ LPEEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) { // get the item bounding box original_bbox(lpeitem); - SPLPEItem * item = const_cast(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); } Geom::Piecewise > diff --git a/src/live_effects/lpe-lattice.cpp b/src/live_effects/lpe-lattice.cpp index c05bae7e1..3c23e349e 100644 --- a/src/live_effects/lpe-lattice.cpp +++ b/src/live_effects/lpe-lattice.cpp @@ -78,7 +78,7 @@ LPELattice::LPELattice(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast(&grid_point14) ); registerParameter( dynamic_cast(&grid_point15) ); - + apply_to_clippath_and_mask = true; } LPELattice::~LPELattice() @@ -176,9 +176,6 @@ void LPELattice::doBeforeEffect (SPLPEItem const* lpeitem) { original_bbox(lpeitem); - SPLPEItem * item = const_cast(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); } void diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp index b749370fa..0c403daec 100644 --- a/src/live_effects/lpe-lattice2.cpp +++ b/src/live_effects/lpe-lattice2.cpp @@ -103,6 +103,7 @@ LPELattice2::LPELattice2(LivePathEffectObject *lpeobject) : registerParameter(&grid_point_28x30); registerParameter(&grid_point_29x31); registerParameter(&grid_point_32x33x34x35); + apply_to_clippath_and_mask = true; } LPELattice2::~LPELattice2() @@ -358,9 +359,6 @@ LPELattice2::doBeforeEffect (SPLPEItem const* lpeitem) horizontal(grid_point_17, grid_point_19,horiz); horizontal(grid_point_20x21, grid_point_22x23,horiz); } - SPLPEItem * item = const_cast(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); } void diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 783053df2..c13cffb6a 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -33,7 +33,7 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : reflection_line(_("Reflection line:"), _("Line which serves as 'mirror' for the reflection"), "reflection_line", &wr, this, "M0,0 L100,100") { show_orig_path = true; - + apply_to_clippath_and_mask = true; registerParameter( dynamic_cast(&discard_orig_path) ); registerParameter( dynamic_cast(&reflection_line) ); } @@ -42,14 +42,6 @@ LPEMirrorSymmetry::~LPEMirrorSymmetry() { } -void -LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) -{ - SPLPEItem * item = const_cast(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); -} - void LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) { diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 7a484a473..64a72d7b3 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -30,8 +30,6 @@ public: virtual void doOnApply (SPLPEItem const* lpeitem); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); private: diff --git a/src/live_effects/lpe-offset.cpp b/src/live_effects/lpe-offset.cpp index dd7af92a2..d611b88a1 100644 --- a/src/live_effects/lpe-offset.cpp +++ b/src/live_effects/lpe-offset.cpp @@ -31,7 +31,7 @@ LPEOffset::LPEOffset(LivePathEffectObject *lpeobject) : offset_pt(_("Offset"), _("Handle to control the distance of the offset from the curve"), "offset_pt", &wr, this) { show_orig_path = true; - + apply_to_clippath_and_mask = true; registerParameter(dynamic_cast(&offset_pt)); } @@ -57,14 +57,6 @@ static void append_half_circle(Geom::Piecewise > &pwd2, pwd2.continuousConcat(cap_pwd2); } -void -LPEOffset::doBeforeEffect (SPLPEItem const* lpeitem) -{ - SPLPEItem * item = const_cast(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); -} - Geom::Piecewise > LPEOffset::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) { diff --git a/src/live_effects/lpe-offset.h b/src/live_effects/lpe-offset.h index 997311c7d..9966fd45d 100644 --- a/src/live_effects/lpe-offset.h +++ b/src/live_effects/lpe-offset.h @@ -28,8 +28,6 @@ public: virtual void doOnApply (SPLPEItem const* lpeitem); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); private: diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index 72c1b0e99..5b29df4a7 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -56,6 +56,7 @@ LPEPerspectiveEnvelope::LPEPerspectiveEnvelope(LivePathEffectObject *lpeobject) registerParameter(&up_right_point); registerParameter(&down_left_point); registerParameter(&down_right_point); + apply_to_clippath_and_mask = true; } LPEPerspectiveEnvelope::~LPEPerspectiveEnvelope() @@ -371,9 +372,6 @@ LPEPerspectiveEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) horizontal(up_left_point, down_left_point,horiz); horizontal(up_right_point, down_right_point,horiz); } - SPLPEItem * item = const_cast(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); setDefaults(); } diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index 901519b4f..c8cdd7912 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -64,6 +64,7 @@ LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : concatenate_before_pwd2 = true; // don't split the path into its subpaths _provides_knotholder_entities = true; + apply_to_clippath_and_mask = true; } LPEPerspectivePath::~LPEPerspectivePath() @@ -100,8 +101,6 @@ LPEPerspectivePath::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Affine doc2d = Geom::Scale(1, -1) * Geom::Translate(0, item->document->getHeight().value("px")); pmat = pmat * doc2d; pmat.copy_tmat(tmat); - item->apply_to_clippath(item); - item->apply_to_mask(item); } void LPEPerspectivePath::refresh(Gtk::Entry* perspective) { diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index b4ee54f1a..105fe2fc4 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -87,6 +87,7 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) segments.param_set_increments(1, 1); segments.param_set_digits(0); seed = 0; + apply_to_clippath_and_mask = true; } LPERoughen::~LPERoughen() {} @@ -102,9 +103,6 @@ void LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem) displace_y.resetRandomizer(); global_randomize.resetRandomizer(); srand(1); - SPLPEItem * item = const_cast(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); } Gtk::Widget *LPERoughen::newWidget() diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 4b62c6c65..f807bdc8d 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -60,6 +60,7 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) helper_size.param_set_digits(2); radius_helper_nodes = 6.0; + apply_to_clippath_and_mask = true; } LPESimplify::~LPESimplify() {} @@ -71,10 +72,7 @@ LPESimplify::doBeforeEffect (SPLPEItem const* lpeitem) hp.clear(); } bbox = SP_ITEM(lpeitem)->visualBounds(); - SPLPEItem * item = const_cast(lpeitem); radius_helper_nodes = helper_size; - item->apply_to_clippath(item); - item->apply_to_mask(item); } Gtk::Widget * diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index dd1a29689..1cd59b7fa 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -78,6 +78,7 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : strech.param_set_range(0, 999.0); strech.param_set_increments(0.01, 0.01); strech.param_set_digits(4); + apply_to_clippath_and_mask = true; } LPETransform2Pts::~LPETransform2Pts() @@ -167,8 +168,6 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) previous_angle = transformed.angle(); previous_lenght = Geom::distance((Geom::Point)start, (Geom::Point)end); previous_start = start; - splpeitem->apply_to_clippath(splpeitem); - splpeitem->apply_to_mask(splpeitem); } void diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index 7b424e019..7eda7446e 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -64,7 +64,7 @@ LPEVonKoch::LPEVonKoch(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast(&drawall) ); registerParameter( dynamic_cast(&maxComplexity) ); //registerParameter( dynamic_cast(&draw_boxes) ); - + apply_to_clippath_and_mask = true; nbgenerations.param_make_integer(); nbgenerations.param_set_range(0, Geom::infinity()); maxComplexity.param_make_integer(); @@ -262,9 +262,6 @@ LPEVonKoch::doBeforeEffect (SPLPEItem const* lpeitem) tmp_pathv.push_back(tmp_path); ref_path.set_new_value(tmp_pathv,true); } - SPLPEItem * item = const_cast(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); } diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 98b77cfe8..e2afbb55b 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -209,7 +209,7 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape /** * returns true when LPE was successful. */ -bool SPLPEItem::performPathEffect(SPCurve *curve) { +bool SPLPEItem::performPathEffect(SPCurve *curve, bool clip_paths) { if (!this) { return false; } @@ -217,7 +217,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve) { if (!curve) { return false; } - + bool apply_to_clippath_and_mask = false; if (this->hasPathEffect() && this->pathEffectsEnabled()) { for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) { @@ -239,35 +239,42 @@ bool SPLPEItem::performPathEffect(SPCurve *curve) { } if (lpe->isVisible()) { + if(lpe->apply_to_clippath_and_mask){ + apply_to_clippath_and_mask = true; + } if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { // if the effect expects mouse input before being applied and the input is not finished // yet, we don't alter the path return false; } + if (clip_paths || lpe->apply_to_clippath_and_mask) { + // Groups have their doBeforeEffect called elsewhere + if (!SP_IS_GROUP(this)) { + lpe->doBeforeEffect_impl(this); + } - // Groups have their doBeforeEffect called elsewhere - if (!SP_IS_GROUP(this)) { - lpe->doBeforeEffect_impl(this); - } - - try { - lpe->doEffect(curve); - } - catch (std::exception & e) { - g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); - if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { - SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, - _("An exception occurred during execution of the Path Effect.") ); + try { + lpe->doEffect(curve); + } + catch (std::exception & e) { + g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); + if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { + SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, + _("An exception occurred during execution of the Path Effect.") ); + } + return false; + } + if (!SP_IS_GROUP(this)) { + lpe->doAfterEffect(this); } - return false; - } - if (!SP_IS_GROUP(this)) { - lpe->doAfterEffect(this); } } } } - + if(apply_to_clippath_and_mask && clip_paths){ + this->apply_to_clippath((SPItem *)this); + this->apply_to_mask((SPItem *)this); + } return true; } @@ -641,43 +648,7 @@ SPLPEItem::apply_to_clippath(SPItem *item) SPClipPath *clipPath = item->clip_ref->getObject(); if(clipPath) { SPObject * clip_data = clipPath->firstChild(); - SPCurve * clip_curve = NULL; - - if (SP_IS_PATH(clip_data)) { - clip_curve = SP_PATH(clip_data)->get_original_curve(); - } else if(SP_IS_SHAPE(clip_data)) { - clip_curve = SP_SHAPE(clip_data)->getCurve(); - } else if(SP_IS_GROUP(clip_data)) { - apply_to_clip_or_mask_group(SP_ITEM(clip_data), item); - return; - } - if(clip_curve) { - bool success = false; - if(SP_IS_GROUP(this)){ - clip_curve->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); - success = this->performPathEffect(clip_curve); - clip_curve->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); - } else { - success = this->performPathEffect(clip_curve); - } - Inkscape::XML::Node *reprClip = clip_data->getRepr(); - if (success) { - gchar *str = sp_svg_write_path(clip_curve->get_pathvector()); - reprClip->setAttribute("d", str); - g_free(str); - } else { - // LPE was unsuccesfull. Read the old 'd'-attribute. - if (gchar const * value = reprClip->attribute("d")) { - Geom::PathVector pv = sp_svg_read_pathv(value); - SPCurve *oldcurve = new SPCurve(pv); - if (oldcurve) { - SP_SHAPE(clip_data)->setCurve(oldcurve, TRUE); - oldcurve->unref(); - } - } - } - clip_curve->unref(); - } + apply_to_clip_or_mask(SP_ITEM(clip_data), item); } if(SP_IS_GROUP(item)){ std::vector item_list = sp_item_group_item_list(SP_GROUP(item)); @@ -694,42 +665,7 @@ SPLPEItem::apply_to_mask(SPItem *item) SPMask *mask = item->mask_ref->getObject(); if(mask) { SPObject *mask_data = mask->firstChild(); - SPCurve * mask_curve = NULL; - if (SP_IS_PATH(mask_data)) { - mask_curve = SP_PATH(mask_data)->get_original_curve(); - } else if(SP_IS_SHAPE(mask_data)) { - mask_curve = SP_SHAPE(mask_data)->getCurve(); - } else if(SP_IS_GROUP(mask_data)) { - apply_to_clip_or_mask_group(SP_ITEM(mask_data), item); - return; - } - if(mask_curve) { - bool success = false; - if(SP_IS_GROUP(this)){ - mask_curve->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); - success = this->performPathEffect(mask_curve); - mask_curve->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); - } else { - success = this->performPathEffect(mask_curve); - } - Inkscape::XML::Node *reprmask = mask_data->getRepr(); - if (success) { - gchar *str = sp_svg_write_path(mask_curve->get_pathvector()); - reprmask->setAttribute("d", str); - g_free(str); - } else { - // LPE was unsuccesfull. Read the old 'd'-attribute. - if (gchar const * value = reprmask->attribute("d")) { - Geom::PathVector pv = sp_svg_read_pathv(value); - SPCurve *oldcurve = new SPCurve(pv); - if (oldcurve) { - SP_SHAPE(mask_data)->setCurve(oldcurve, TRUE); - oldcurve->unref(); - } - } - } - mask_curve->unref(); - } + apply_to_clip_or_mask(SP_ITEM(mask_data), item); } if(SP_IS_GROUP(item)){ std::vector item_list = sp_item_group_item_list(SP_GROUP(item)); @@ -741,51 +677,57 @@ SPLPEItem::apply_to_mask(SPItem *item) } void -SPLPEItem::apply_to_clip_or_mask_group(SPItem *group, SPItem *item) +SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) { - if (!SP_IS_GROUP(group)) { - return; - } - std::vector item_list = sp_item_group_item_list(SP_GROUP(group)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPObject *subitem = *iter; - if (SP_IS_GROUP(subitem)) { - apply_to_clip_or_mask_group(SP_ITEM(subitem), item); - } else if (SP_IS_SHAPE(subitem)) { - SPCurve * c = NULL; - - if (SP_IS_PATH(subitem)) { - c = SP_PATH(subitem)->get_original_curve(); - } else { - c = SP_SHAPE(subitem)->getCurve(); - } - if (c) { - bool success = false; - if(SP_IS_GROUP(group)){ + if (SP_IS_GROUP(clip_mask)) { + std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_mask)); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPItem *subitem = *iter; + apply_to_clip_or_mask(subitem, item); + } + } else if (SP_IS_SHAPE(clip_mask)) { + SPCurve * c = NULL; + + if (SP_IS_PATH(clip_mask)) { + c = SP_PATH(clip_mask)->get_original_curve(); + } else { + c = SP_SHAPE(clip_mask)->getCurve(); + } + if (c) { + bool success = false; + try { + if(SP_IS_GROUP(this)){ c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); - success = this->performPathEffect(c); + success = this->performPathEffect(c, false); c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); } else { - success = this->performPathEffect(c); + success = this->performPathEffect(c, false); } - Inkscape::XML::Node *repr = subitem->getRepr(); - if (success) { - gchar *str = sp_svg_write_path(c->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - // LPE was unsuccesfull. Read the old 'd'-attribute. - if (gchar const * value = repr->attribute("d")) { - Geom::PathVector pv = sp_svg_read_pathv(value); - SPCurve *oldcurve = new SPCurve(pv); - if (oldcurve) { - SP_SHAPE(subitem)->setCurve(oldcurve, TRUE); - oldcurve->unref(); - } + } catch (std::exception & e) { + g_warning("Exception during LPE execution. \n %s", e.what()); + if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { + SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, + _("An exception occurred during execution of the Path Effect.") ); + } + success = false; + } + Inkscape::XML::Node *repr = clip_mask->getRepr(); + if (success) { + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + // LPE was unsuccesfull. Read the old 'd'-attribute. + if (gchar const * value = repr->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new SPCurve(pv); + if (oldcurve) { + SP_SHAPE(clip_mask)->setCurve(oldcurve, TRUE); + oldcurve->unref(); } } - c->unref(); } + c->unref(); } } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index c35ad8411..d5e868b2e 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -69,7 +69,7 @@ public: virtual void update_patheffect(bool write); - bool performPathEffect(SPCurve *curve); + bool performPathEffect(SPCurve *curve, bool clip_paths = true); bool pathEffectsEnabled() const; bool hasPathEffect() const; @@ -93,7 +93,7 @@ public: void addPathEffect(LivePathEffectObject * new_lpeobj); void apply_to_mask(SPItem * item); void apply_to_clippath(SPItem * item); - void apply_to_clip_or_mask_group(SPItem * group, SPItem * item); + void apply_to_clip_or_mask(SPItem * clip_mask, SPItem * item); bool forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users = 1); void editNextParamOncanvas(SPDesktop *dt); -- cgit v1.2.3 From 32829581539b00c07f592c15cb62b69d71de9bb7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 2 Mar 2016 20:44:36 +0100 Subject: Fix bug 1540155: Interactive simplify on pencit tool is hard to edit Fixed bugs: - https://launchpad.net/bugs/1540155 (bzr r14679) --- src/ui/dialog/inkscape-preferences.cpp | 10 ++++++++++ src/ui/dialog/inkscape-preferences.h | 1 + src/ui/tools/pencil-tool.cpp | 16 ++++++++++------ 3 files changed, 21 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index b6d7e25ec..b20f71a6a 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -206,6 +206,15 @@ void InkscapePreferences::AddDotSizeSpinbutton(DialogPage &p, Glib::ustring cons false ); } +void InkscapePreferences::AddBaseSimplifySpinbutton(DialogPage &p, Glib::ustring const &prefs_path, double def_value) +{ + PrefSpinButton* sb = Gtk::manage( new PrefSpinButton); + sb->init ( prefs_path + "/base-simplify", 0.0, 100.0, 1.0, 10.0, def_value, false, false); + p.add_line( false, _("Base simplify:"), *sb, _("on dinamic LPE simplify"), + _("Base simplify of dinamic LPE based simplify"), + false ); +} + static void StyleFromSelectionToTool(Glib::ustring const &prefs_path, StyleSwatch *swatch) { @@ -425,6 +434,7 @@ void InkscapePreferences::initPageTools() this->AddSelcueCheckbox(_page_pencil, "/tools/freehand/pencil", true); this->AddNewObjectsStyle(_page_pencil, "/tools/freehand/pencil"); this->AddDotSizeSpinbutton(_page_pencil, "/tools/freehand/pencil", 3.0); + this->AddBaseSimplifySpinbutton(_page_pencil, "/tools/freehand/pencil", 25.0); _page_pencil.add_group_header( _("Sketch mode")); _page_pencil.add_line( true, "", _pencil_average_all_sketches, "", _("If on, the sketch result will be the normal average of all sketches made, instead of averaging the old result with the new sketch")); diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index b7696ab8c..d1abcfc58 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -502,6 +502,7 @@ protected: static void AddConvertGuidesCheckbox(UI::Widget::DialogPage& p, Glib::ustring const &prefs_path, bool def_value); static void AddFirstAndLastCheckbox(UI::Widget::DialogPage& p, Glib::ustring const &prefs_path, bool def_value); static void AddDotSizeSpinbutton(UI::Widget::DialogPage& p, Glib::ustring const &prefs_path, double def_value); + static void AddBaseSimplifySpinbutton(UI::Widget::DialogPage& p, Glib::ustring const &prefs_path, double def_value); static void AddNewObjectsStyle(UI::Widget::DialogPage& p, Glib::ustring const &prefs_path, const gchar* banner = NULL); void on_pagelist_selection_changed(); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index bfb1c67f0..b029ca613 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -634,12 +634,14 @@ void PencilTool::_interpolate() { using Geom::Y; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4; - double tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2); + double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4; bool simplify = prefs->getInt("/tools/freehand/pencil/simplify", 0); if(simplify){ - tolerance_sq = 0; + double tol2 = prefs->getDoubleLimited("/tools/freehand/pencil/base-simplify", 25.0, 1.0, 100.0) * 0.4; + tol = std::min(tol,tol2); } + double tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2); + g_assert(is_zero(this->req_tangent) || is_unit_vector(this->req_tangent)); this->green_curve->reset(); @@ -705,12 +707,14 @@ void PencilTool::_sketchInterpolate() { } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4; - double tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2); + double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4; bool simplify = prefs->getInt("/tools/freehand/pencil/simplify", 0); if(simplify){ - tolerance_sq = 0; + double tol2 = prefs->getDoubleLimited("/tools/freehand/pencil/base-simplify", 25.0, 1.0, 100.0) * 0.4; + tol = std::min(tol,tol2); } + double tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2); + bool average_all_sketches = prefs->getBool("/tools/freehand/pencil/average_all_sketches", true); g_assert(is_zero(this->req_tangent) || is_unit_vector(this->req_tangent)); -- cgit v1.2.3 From d2d53a21a717ac8506960504385566a55b3a7b22 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Fri, 4 Mar 2016 00:29:08 +0100 Subject: Add support for the "relative to" setting when aligning baselines (fixes 167228) Fixed bugs: - https://launchpad.net/bugs/167228 (bzr r14682) --- src/ui/dialog/align-and-distribute.cpp | 49 +++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 9e7861217..5a16ecce8 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -741,7 +741,6 @@ private : if (!selection) return; std::vector selected(selection->itemList()); - if (selected.empty()) return; //Check 2 or more selected objects if (selected.size() < 2) return; @@ -794,7 +793,51 @@ private : _("Distribute text baselines")); } - } else { + } else { //align + Geom::Point ref_point; + SPItem *focus = NULL; + Geom::OptRect b = Geom::OptRect(); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + switch (AlignTarget(prefs->getInt("/dialogs/align/align-to", 6))) + { + case LAST: + focus = SP_ITEM(*selected.begin()); + break; + case FIRST: + focus = SP_ITEM(*--(selected.end())); + break; + case BIGGEST: + focus = selection->largestItem(Selection::AREA); + break; + case SMALLEST: + focus = selection->smallestItem(Selection::AREA); + break; + case PAGE: + b = desktop->getDocument()->preferredBounds(); + break; + case DRAWING: + b = desktop->getDocument()->getRoot()->desktopPreferredBounds(); + break; + case SELECTION: + b = selection->preferredBounds(); + break; + default: + g_assert_not_reached (); + break; + }; + + if(focus) { + if (SP_IS_TEXT (focus) || SP_IS_FLOWTEXT (focus)) { + ref_point = *(te_get_layout(focus)->baselineAnchorPoint())*(focus->i2dt_affine()); + } else { + ref_point = focus->desktopPreferredBounds()->min(); + } + } else { + ref_point = b->min(); + } + for (std::vector::iterator it(selected.begin()); it != selected.end(); ++it) @@ -806,7 +849,7 @@ private : if (pt) { Geom::Point base = *pt * (item)->i2dt_affine(); Geom::Point t(0.0, 0.0); - t[_orientation] = b_min[_orientation] - base[_orientation]; + t[_orientation] = ref_point[_orientation] - base[_orientation]; sp_item_move_rel(item, Geom::Translate(t)); changed = true; } -- cgit v1.2.3 From a7448ad9a0afe4616fc1ef4eb31101d852160767 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Fri, 4 Mar 2016 00:37:54 +0100 Subject: forgot to include a file in previous commit >< (bzr r14683) --- src/ui/dialog/align-and-distribute.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h index eecc30ff8..d337775cf 100644 --- a/src/ui/dialog/align-and-distribute.h +++ b/src/ui/dialog/align-and-distribute.h @@ -149,6 +149,7 @@ bool operator< (const BBoxSort &a, const BBoxSort &b); class Action { public : + enum AlignTarget { LAST=0, FIRST, BIGGEST, SMALLEST, PAGE, DRAWING, SELECTION }; Action(const Glib::ustring &id, const Glib::ustring &tiptext, guint row, guint column, @@ -183,7 +184,6 @@ public : double sx0, sx1, sy0, sy1; int verb_id; }; - enum AlignTarget { LAST=0, FIRST, BIGGEST, SMALLEST, PAGE, DRAWING, SELECTION }; ActionAlign(const Glib::ustring &id, const Glib::ustring &tiptext, guint row, guint column, -- cgit v1.2.3 From c6cfbcf0dfd490c9ab46b21219881f78c0af8bf1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 4 Mar 2016 10:51:55 +0100 Subject: Hide with widget in delete mode of eraser tool (bzr r14684) --- src/ui/tools/eraser-tool.cpp | 1 + src/widgets/eraser-toolbar.cpp | 7 +++++++ 2 files changed, 8 insertions(+) (limited to 'src') diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp index b34a2d3ce..edda211ca 100644 --- a/src/ui/tools/eraser-tool.cpp +++ b/src/ui/tools/eraser-tool.cpp @@ -449,6 +449,7 @@ bool EraserTool::root_handler(GdkEvent* event) { ret = TRUE; } if ( !eraserMode ) { + this->accumulated->reset(); Inkscape::Rubberband::get(desktop)->move(motion_dt); } } diff --git a/src/widgets/eraser-toolbar.cpp b/src/widgets/eraser-toolbar.cpp index 1fc520185..45989936f 100644 --- a/src/widgets/eraser-toolbar.cpp +++ b/src/widgets/eraser-toolbar.cpp @@ -74,12 +74,15 @@ static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) } GtkAction *split = GTK_ACTION( g_object_get_data(tbl, "split") ); GtkAction *mass = GTK_ACTION( g_object_get_data(tbl, "mass") ); + GtkAction *width = GTK_ACTION( g_object_get_data(tbl, "width") ); if(eraserMode == TRUE){ gtk_action_set_visible( split, TRUE ); gtk_action_set_visible( mass, TRUE ); + gtk_action_set_visible( width, TRUE ); } else { gtk_action_set_visible( split, FALSE ); gtk_action_set_visible( mass, FALSE ); + gtk_action_set_visible( width, FALSE ); } // only take action if run by the attr_changed listener if (!g_object_get_data( tbl, "freeze" )) { @@ -157,6 +160,7 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb sp_erc_width_value_changed, NULL /*unit tracker*/, 1, 0); ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( holder, "width", eact ); gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); } { @@ -190,12 +194,15 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb } GtkAction *split = GTK_ACTION( g_object_get_data(holder, "split") ); GtkAction *mass = GTK_ACTION( g_object_get_data(holder, "mass") ); + GtkAction *width = GTK_ACTION( g_object_get_data(holder, "width") ); if(eraserMode == TRUE){ gtk_action_set_visible( split, TRUE ); gtk_action_set_visible( mass, TRUE ); + gtk_action_set_visible( width, TRUE ); } else { gtk_action_set_visible( split, FALSE ); gtk_action_set_visible( mass, FALSE ); + gtk_action_set_visible( width, FALSE ); } } -- cgit v1.2.3 From 532e38d87f1465b0cce151bcc520f8f5b0b6bffc Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 4 Mar 2016 16:02:09 +0100 Subject: Fix bug: 230480 eraser tool always deletes selected objects Fixed bugs: - https://launchpad.net/bugs/230480 (bzr r14685) --- src/ui/tools/eraser-tool.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp index edda211ca..8a3dbc66e 100644 --- a/src/ui/tools/eraser-tool.cpp +++ b/src/ui/tools/eraser-tool.cpp @@ -682,7 +682,18 @@ void EraserTool::set_to_accumulated() { } toWorkOn.erase(std::remove(toWorkOn.begin(), toWorkOn.end(), acid), toWorkOn.end()); } else { - toWorkOn = selection->itemList(); + if ( !eraserMode ) { + Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop); + std::vector touched; + touched = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints()); + for (std::vector::const_iterator i = touched.begin();i!=touched.end();++i) { + if(selection->includes(*i)){ + toWorkOn.push_back((*i)); + } + } + } else { + toWorkOn = selection->itemList(); + } wasSelection = true; } -- cgit v1.2.3 From ec0ae472f3d3221081a1248d0a517c68a296f6f5 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 4 Mar 2016 10:33:09 -0500 Subject: Update 2geom copy to 143bbcf: Fix for multiple sequential closepath commands Fixed bugs: - https://launchpad.net/bugs/1492153 (bzr r14686) --- src/2geom/path-sink.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/2geom/path-sink.h b/src/2geom/path-sink.h index 17ede18a4..3bdb00783 100644 --- a/src/2geom/path-sink.h +++ b/src/2geom/path-sink.h @@ -179,8 +179,10 @@ public: } void closePath() { - _path.close(); - flush(); + if (_in_path) { + _path.close(); + flush(); + } } void flush() { -- cgit v1.2.3 From 1e3c55578b899990862b21e826dbe38129c3fff0 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 4 Mar 2016 10:39:45 -0500 Subject: Remove regex hack added in 14650 (bzr r14687) --- src/extension/internal/cdr-input.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index a4e26e224..f4789a08f 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -22,7 +22,6 @@ #include #include -#include #include @@ -282,12 +281,7 @@ SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u } } - // remove consecutive closepath commands (see bug 1492153) - Glib::RefPtr regex = Glib::Regex::create("(Z(?:\\s+Z)+)(?=[^<]+\")"); - Glib::ustring outString1 = Glib::ustring(tmpSVGOutput[page_num-1].cstr()); - Glib::ustring outString2 = regex->replace(outString1, 0, "Z", Glib::REGEX_MATCH_NEWLINE_ANY); - - SPDocument * doc = SPDocument::createNewDocFromMem(outString2.c_str(), outString2.bytes(), TRUE); + SPDocument * doc = SPDocument::createNewDocFromMem(tmpSVGOutput[page_num-1].cstr(), strlen(tmpSVGOutput[page_num-1].cstr()), TRUE); // Set viewBox if it doesn't exist if (doc && !doc->getRoot()->viewBox_set) { -- cgit v1.2.3 From 70f07d3a84ebcc213420c8028a2bc3d1dd4110d4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 4 Mar 2016 20:19:00 +0100 Subject: Fix for bug 415471 and 1553182 related to undo with eraser tool Fixed bugs: - https://launchpad.net/bugs/1553182 (bzr r14688) --- src/path-chemistry.cpp | 18 +++++---- src/path-chemistry.h | 4 +- src/ui/tools/eraser-tool.cpp | 89 ++++++++++++++++++++++++-------------------- 3 files changed, 60 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 7b52ac2e1..15d3f0f99 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -52,7 +52,7 @@ inline bool less_than_items(SPItem const *first, SPItem const *second) } void -sp_selected_path_combine(SPDesktop *desktop) +sp_selected_path_combine(SPDesktop *desktop, bool skip_undo) { Inkscape::Selection *selection = desktop->getSelection(); SPDocument *doc = desktop->getDocument(); @@ -172,10 +172,10 @@ sp_selected_path_combine(SPDesktop *desktop) // move to the position of the topmost, reduced by the number of deleted items repr->setPosition(position > 0 ? position : 0); - - DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_COMBINE, - _("Combine")); - + if ( !skip_undo ) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_COMBINE, + _("Combine")); + } selection->set(repr); Inkscape::GC::release(repr); @@ -188,7 +188,7 @@ sp_selected_path_combine(SPDesktop *desktop) } void -sp_selected_path_break_apart(SPDesktop *desktop) +sp_selected_path_break_apart(SPDesktop *desktop, bool skip_undo) { Inkscape::Selection *selection = desktop->getSelection(); @@ -283,8 +283,10 @@ sp_selected_path_break_apart(SPDesktop *desktop) desktop->clearWaitingCursor(); if (did) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_BREAK_APART, - _("Break apart")); + if ( !skip_undo ) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_BREAK_APART, + _("Break apart")); + } } else { desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("No path(s) to break apart in the selection.")); } diff --git a/src/path-chemistry.h b/src/path-chemistry.h index 35ab923c0..7b9beaed8 100644 --- a/src/path-chemistry.h +++ b/src/path-chemistry.h @@ -25,8 +25,8 @@ class Node; typedef unsigned int guint32; -void sp_selected_path_combine (SPDesktop *desktop); -void sp_selected_path_break_apart (SPDesktop *desktop); +void sp_selected_path_combine (SPDesktop *desktop, bool skip_undo = false); +void sp_selected_path_break_apart (SPDesktop *desktop, bool skip_undo = false); // interactive=true only has an effect if desktop != NULL, i.e. if a GUI is available void sp_selected_path_to_curves (Inkscape::Selection *selection, SPDesktop *desktop, bool interactive = true); void sp_selected_to_lpeitems(SPDesktop *desktop); diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp index 8a3dbc66e..6b32b5901 100644 --- a/src/ui/tools/eraser-tool.cpp +++ b/src/ui/tools/eraser-tool.cpp @@ -702,49 +702,57 @@ void EraserTool::set_to_accumulated() { for (std::vector::const_iterator i = toWorkOn.begin(); i != toWorkOn.end(); ++i){ SPItem *item = *i; SPUse *use = dynamic_cast(item); - if (SP_IS_GROUP(item) || use ) { - continue; - } - Geom::OptRect bbox = item->desktopVisualBounds(); - if (bbox && bbox->intersects(*eraserBbox)) { - Inkscape::XML::Node* dup = this->repr->duplicate(xml_doc); - this->repr->parent()->appendChild(dup); - Inkscape::GC::release(dup); // parent takes over - selection->set(dup); - if (!this->nowidth) { - sp_selected_path_union(selection, desktop); - } - selection->add(item); - if(item->style->fill_rule.value == SP_WIND_RULE_EVENODD){ - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property(css, "fill-rule", "evenodd"); - sp_desktop_set_style(desktop, css); - sp_repr_css_attr_unref(css); - css = 0; - } - if (this->nowidth) { - sp_selected_path_cut_skip_undo(selection, desktop); - } else { - sp_selected_path_diff_skip_undo(selection, desktop); - } - workDone = true; // TODO set this only if something was cut. - bool break_apart = prefs->getBool("/tools/eraser/break_apart", false); - if(!break_apart){ - sp_selected_path_combine(desktop); - } else { - if(!this->nowidth){ - sp_selected_path_break_apart(desktop); + if (SP_IS_PATH(item) && SP_PATH(item)->nodesInPath () == 2){ + sp_object_ref( *i, 0 ); + SPItem *item = *i; + item->deleteObject(true); + sp_object_unref(item); + workDone = true; + workDone = true; + } else if (SP_IS_GROUP(item) || use ) { + /*Do nothing*/ + } else { + Geom::OptRect bbox = item->desktopVisualBounds(); + if (bbox && bbox->intersects(*eraserBbox)) { + Inkscape::XML::Node* dup = this->repr->duplicate(xml_doc); + this->repr->parent()->appendChild(dup); + Inkscape::GC::release(dup); // parent takes over + selection->set(dup); + if (!this->nowidth) { + sp_selected_path_union_skip_undo(selection, desktop); } - } - if ( !selection->isEmpty() ) { - // If the item was not completely erased, track the new remainder. - std::vector nowSel(selection->itemList()); - for (std::vector::const_iterator i2 = nowSel.begin();i2!=nowSel.end();++i2) { - remainingItems.push_back(*i2); + selection->add(item); + if(item->style->fill_rule.value == SP_WIND_RULE_EVENODD){ + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "fill-rule", "evenodd"); + sp_desktop_set_style(desktop, css); + sp_repr_css_attr_unref(css); + css = 0; + } + if (this->nowidth) { + sp_selected_path_cut_skip_undo(selection, desktop); + } else { + sp_selected_path_diff_skip_undo(selection, desktop); + } + workDone = true; // TODO set this only if something was cut. + bool break_apart = prefs->getBool("/tools/eraser/break_apart", false); + if(!break_apart){ + sp_selected_path_combine(desktop, true); + } else { + if(!this->nowidth){ + sp_selected_path_break_apart(desktop, true); + } + } + if ( !selection->isEmpty() ) { + // If the item was not completely erased, track the new remainder. + std::vector nowSel(selection->itemList()); + for (std::vector::const_iterator i2 = nowSel.begin();i2!=nowSel.end();++i2) { + remainingItems.push_back(*i2); + } } + } else { + remainingItems.push_back(item); } - } else { - remainingItems.push_back(item); } } } else { @@ -773,7 +781,6 @@ void EraserTool::set_to_accumulated() { } } } - // Remove the eraser stroke itself: sp_repr_unparent( this->repr ); this->repr = 0; -- cgit v1.2.3 From 0a0947876040165625941a4bccc1a788173121c0 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Mon, 7 Mar 2016 20:34:38 +0100 Subject: does not zoom in to selection box if holding shift to zoom out (bzr r14692) --- src/ui/tools/zoom-tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/zoom-tool.cpp b/src/ui/tools/zoom-tool.cpp index 6a4d4dbbd..13e097c18 100644 --- a/src/ui/tools/zoom-tool.cpp +++ b/src/ui/tools/zoom-tool.cpp @@ -142,7 +142,7 @@ bool ZoomTool::root_handler(GdkEvent* event) { if ( event->button.button == 1 && !this->space_panning) { Geom::OptRect const b = Inkscape::Rubberband::get(desktop)->getRectangle(); - if (b && !within_tolerance) { + if (b && !within_tolerance && !(GDK_SHIFT_MASK & event->button.state) ) { desktop->set_display_area(*b, 10); } else if (!escaped) { double const zoom_rel( (event->button.state & GDK_SHIFT_MASK) -- cgit v1.2.3 From a3f684fa5156f66fdcd3d15cc469d84258807201 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 7 Mar 2016 22:10:20 +0100 Subject: Add GUI for 'paint-order' property. (bzr r14693) --- src/desktop-style.cpp | 76 ++++++++++++++++++++++++++---- src/desktop-style.h | 1 + src/widgets/stroke-style.cpp | 107 +++++++++++++++++++++++++++++++++++++++++++ src/widgets/stroke-style.h | 11 ++++- 4 files changed, 184 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index a81cbdd1f..c36bcee44 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -881,8 +881,7 @@ objects_query_strokecap (const std::vector &objects, SPStyle *style_res return QUERY_STYLE_NOTHING; } - int cap = -1; - gdouble prev_cap = -1; + int prev_cap = -1; bool same_cap = true; int n_stroked = 0; @@ -905,11 +904,9 @@ objects_query_strokecap (const std::vector &objects, SPStyle *style_res if (prev_cap != -1 && style->stroke_linecap.value != prev_cap) same_cap = false; prev_cap = style->stroke_linecap.value; - - cap = style->stroke_linecap.value; } - style_res->stroke_linecap.value = cap; + style_res->stroke_linecap.value = prev_cap; style_res->stroke_linecap.set = true; if (n_stroked == 0) { @@ -935,8 +932,7 @@ objects_query_strokejoin (const std::vector &objects, SPStyle *style_re return QUERY_STYLE_NOTHING; } - int join = -1; - gdouble prev_join = -1; + int prev_join = -1; bool same_join = true; int n_stroked = 0; @@ -960,11 +956,9 @@ objects_query_strokejoin (const std::vector &objects, SPStyle *style_re same_join = false; } prev_join = style->stroke_linejoin.value; - - join = style->stroke_linejoin.value; } - style_res->stroke_linejoin.value = join; + style_res->stroke_linejoin.value = prev_join; style_res->stroke_linejoin.set = true; if (n_stroked == 0) { @@ -979,6 +973,62 @@ objects_query_strokejoin (const std::vector &objects, SPStyle *style_re } } +/** + * Write to style_res the paint order of a list of objects. + */ +int +objects_query_paintorder (const std::vector &objects, SPStyle *style_res) +{ + if (objects.empty()) { + /* No objects, set empty */ + return QUERY_STYLE_NOTHING; + } + + std::string prev_order; + bool same_order = true; + int n_order = 0; + + for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { + SPObject *obj = *i; + if (!dynamic_cast(obj)) { + continue; + } + SPStyle *style = obj->style; + if (!style) { + continue; + } + + if ( style->stroke.isNone() ) { + continue; + } + + n_order ++; + + if (!prev_order.empty() && prev_order.compare( style->paint_order.value ) != 0) { + same_order = false; + } + if (style->paint_order.set) { + prev_order = style->paint_order.value; + } + } + + + g_free( style_res->paint_order.value ); + style_res->paint_order.value= g_strdup( prev_order.c_str() ); + style_res->paint_order.set = true; + + if (n_order == 0) { + return QUERY_STYLE_NOTHING; + } else if (n_order == 1) { + return QUERY_STYLE_SINGLE; + } else { + if (same_order) + return QUERY_STYLE_MULTIPLE_SAME; + else + return QUERY_STYLE_MULTIPLE_DIFFERENT; + } +} + /** * Write to style_res the average font size and spacing of objects. */ @@ -1763,6 +1813,8 @@ sp_desktop_query_style_from_list (const std::vector &list, SPStyle *sty } else if (property == QUERY_STYLE_PROPERTY_STROKEJOIN) { return objects_query_strokejoin (list, style); + } else if (property == QUERY_STYLE_PROPERTY_PAINTORDER) { + return objects_query_paintorder (list, style); } else if (property == QUERY_STYLE_PROPERTY_MASTEROPACITY) { return objects_query_opacity (list, style); @@ -1829,6 +1881,9 @@ sp_desktop_query_style_all (SPDesktop *desktop, SPStyle *query) int result_strokemiterlimit = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT); int result_strokecap = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_STROKECAP); int result_strokejoin = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_STROKEJOIN); + + int result_paintorder = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_PAINTORDER); + int result_opacity = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_MASTEROPACITY); int result_blur = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_BLUR); @@ -1842,6 +1897,7 @@ sp_desktop_query_style_all (SPDesktop *desktop, SPStyle *query) result_strokemiterlimit != QUERY_STYLE_NOTHING || result_strokecap != QUERY_STYLE_NOTHING || result_strokejoin != QUERY_STYLE_NOTHING || + result_paintorder != QUERY_STYLE_NOTHING || result_blur != QUERY_STYLE_NOTHING); } diff --git a/src/desktop-style.h b/src/desktop-style.h index bf05adadf..f3d6775a4 100644 --- a/src/desktop-style.h +++ b/src/desktop-style.h @@ -43,6 +43,7 @@ enum { // which property was queried (add when you need more) QUERY_STYLE_PROPERTY_STROKEJOIN, // stroke join QUERY_STYLE_PROPERTY_STROKECAP, // stroke cap QUERY_STYLE_PROPERTY_STROKESTYLE, // markers, dasharray, miterlimit, stroke-width, stroke-cap, stroke-join + QUERY_STYLE_PROPERTY_PAINTORDER, // paint-order QUERY_STYLE_PROPERTY_FONT_SPECIFICATION, //-inkscape-font-specification QUERY_STYLE_PROPERTY_FONTFAMILY, // font-family QUERY_STYLE_PROPERTY_FONTSTYLE, // font style diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 43dffec56..e1e5ecc17 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -381,6 +381,46 @@ StrokeStyle::StrokeStyle() : hb->pack_start(*endMarkerCombo, true, true, 0); + i++; + + /* Paint order */ + // TRANSLATORS: Paint order determines the order the 'fill', 'stroke', and 'markers are painted. + spw_label(table, _("Order:"), 0, i, NULL); + + hb = spw_hbox(table, 4, 1, i); + + Gtk::RadioButtonGroup paintOrderGrp; + + paintOrderFSM = makeRadioButton(paintOrderGrp, INKSCAPE_ICON("paint-order-fsm"), + hb, STROKE_STYLE_BUTTON_ORDER, "normal"); + paintOrderFSM->set_tooltip_text(_("Fill, Stroke, Markers")); + + paintOrderSFM = makeRadioButton(paintOrderGrp, INKSCAPE_ICON("paint-order-sfm"), + hb, STROKE_STYLE_BUTTON_ORDER, "stroke fill markers"); + paintOrderSFM->set_tooltip_text(_("Stroke, Fill, Markers")); + + paintOrderFMS = makeRadioButton(paintOrderGrp, INKSCAPE_ICON("paint-order-fms"), + hb, STROKE_STYLE_BUTTON_ORDER, "fill markers stroke"); + paintOrderFMS->set_tooltip_text(_("Fill, Markers, Stroke")); + + i++; + + hb = spw_hbox(table, 4, 1, i); + + paintOrderMFS = makeRadioButton(paintOrderGrp, INKSCAPE_ICON("paint-order-mfs"), + hb, STROKE_STYLE_BUTTON_ORDER, "markers fill stroke"); + paintOrderMFS->set_tooltip_text(_("Markers, Fill, Stroke")); + + paintOrderSMF = makeRadioButton(paintOrderGrp, INKSCAPE_ICON("paint-order-smf"), + hb, STROKE_STYLE_BUTTON_ORDER, "stroke markers fill"); + paintOrderSMF->set_tooltip_text(_("Stroke, Markers, Fill")); + + paintOrderMSF = makeRadioButton(paintOrderGrp, INKSCAPE_ICON("paint-order-msf"), + hb, STROKE_STYLE_BUTTON_ORDER, "markers stroke fill"); + paintOrderMSF->set_tooltip_text(_("Markers, Stroke, Fill")); + + i++; + setDesktop(desktop); updateLine(); @@ -801,6 +841,43 @@ StrokeStyle::setCapType (unsigned const captype) setCapButtons(tb); } +/** + * Sets the cap type for a line, and updates the stroke style widget's buttons + */ +void +StrokeStyle::setPaintOrder (gchar const *paint_order) +{ + Gtk::RadioButton *tb = paintOrderFSM; + + SPIPaintOrder temp; + temp.read( paint_order ); + + if (temp.layer[0] != SP_CSS_PAINT_ORDER_NORMAL) { + + if (temp.layer[0] == SP_CSS_PAINT_ORDER_FILL) { + if (temp.layer[1] == SP_CSS_PAINT_ORDER_STROKE) { + tb = paintOrderFSM; + } else { + tb = paintOrderFMS; + } + } else if (temp.layer[0] == SP_CSS_PAINT_ORDER_STROKE) { + if (temp.layer[1] == SP_CSS_PAINT_ORDER_FILL) { + tb = paintOrderSFM; + } else { + tb = paintOrderSMF; + } + } else { + if (temp.layer[1] == SP_CSS_PAINT_ORDER_STROKE) { + tb = paintOrderMSF; + } else { + tb = paintOrderMFS; + } + } + + } + setPaintOrderButtons(tb); +} + /** * Callback for when stroke style widget is updated, including markers, cap type, * join type, etc. @@ -825,6 +902,9 @@ StrokeStyle::updateLine() int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT); int result_cap = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKECAP); int result_join = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKEJOIN); + + int result_order = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_PAINTORDER); + SPIPaint &targPaint = (kind == FILL) ? query.fill : query.stroke; if (!sel || sel->isEmpty()) { @@ -902,6 +982,13 @@ StrokeStyle::updateLine() setCapButtons(NULL); } + if (result_order != QUERY_STYLE_MULTIPLE_DIFFERENT && + result_order != QUERY_STYLE_NOTHING ) { + setPaintOrder (query.paint_order.value); + } else { + setPaintOrder (NULL); + } + if (!sel || sel->isEmpty()) return; @@ -1109,6 +1196,11 @@ void StrokeStyle::buttonToggledCB(StrokeStyleButton *tb, StrokeStyle *spw) sp_repr_css_set_property(css, "stroke-linecap", tb->get_stroke_style()); sp_desktop_set_style (spw->desktop, css); spw->setCapButtons(tb); + break; + case STROKE_STYLE_BUTTON_ORDER: + sp_repr_css_set_property(css, "paint-order", tb->get_stroke_style()); + sp_desktop_set_style (spw->desktop, css); + //spw->setPaintButtons(tb); } sp_repr_css_attr_unref(css); @@ -1142,6 +1234,21 @@ StrokeStyle::setCapButtons(Gtk::ToggleButton *active) } +/** + * Updates the paint order style toggle buttons + */ +void +StrokeStyle::setPaintOrderButtons(Gtk::ToggleButton *active) +{ + paintOrderFSM->set_active(active == paintOrderFSM); + paintOrderSFM->set_active(active == paintOrderSFM); + paintOrderFMS->set_active(active == paintOrderFMS); + paintOrderMFS->set_active(active == paintOrderMFS); + paintOrderSMF->set_active(active == paintOrderSMF); + paintOrderMSF->set_active(active == paintOrderMSF); +} + + /** * Updates the marker combobox to highlight the appropriate marker and scroll to * that marker. diff --git a/src/widgets/stroke-style.h b/src/widgets/stroke-style.h index 2605e1acf..d83067a4a 100644 --- a/src/widgets/stroke-style.h +++ b/src/widgets/stroke-style.h @@ -127,7 +127,8 @@ private: /** List of valid types for the stroke-style radio-button widget */ enum StrokeStyleButtonType { STROKE_STYLE_BUTTON_JOIN, ///< A button to set the line-join style - STROKE_STYLE_BUTTON_CAP ///< A button to set the line-cap style + STROKE_STYLE_BUTTON_CAP, ///< A button to set the line-cap style + STROKE_STYLE_BUTTON_ORDER ///< A button to set the paint-order style }; /** @@ -158,8 +159,10 @@ private: void setDashSelectorFromStyle(SPDashSelector *dsel, SPStyle *style); void setJoinType (unsigned const jointype); void setCapType (unsigned const captype); + void setPaintOrder (gchar const *paint_order); void setJoinButtons(Gtk::ToggleButton *active); void setCapButtons(Gtk::ToggleButton *active); + void setPaintOrderButtons(Gtk::ToggleButton *active); void scaleLine(); void setScaledDash(SPCSSAttr *css, int ndash, double *dash, double offset, double scale); void setMarkerColor(SPObject *marker, int loc, SPItem *item); @@ -204,6 +207,12 @@ private: StrokeStyleButton *capButt; StrokeStyleButton *capRound; StrokeStyleButton *capSquare; + StrokeStyleButton *paintOrderFSM; + StrokeStyleButton *paintOrderSFM; + StrokeStyleButton *paintOrderFMS; + StrokeStyleButton *paintOrderMFS; + StrokeStyleButton *paintOrderSMF; + StrokeStyleButton *paintOrderMSF; SPDashSelector *dashSelector; gboolean update; -- cgit v1.2.3 From e0d7f04457c7ed18b5f4df751f66e40ad8ab18a9 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Mon, 7 Mar 2016 20:23:26 -0500 Subject: Re-order the stroke dialog so buttons are collected and miter is inline. (bzr r14694) --- src/widgets/stroke-style.cpp | 142 +++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index e1e5ecc17..84a6e77ad 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -221,6 +221,67 @@ StrokeStyle::StrokeStyle() : #endif i++; + /* Dash */ + spw_label(table, _("Dashes:"), 0, i, NULL); //no mnemonic for now + //decide what to do: + // implement a set_mnemonic_source function in the + // SPDashSelector class, so that we do not have to + // expose any of the underlying widgets? + dashSelector = Gtk::manage(new SPDashSelector); + + dashSelector->show(); + +#if WITH_GTKMM_3_0 + dashSelector->set_hexpand(); + dashSelector->set_halign(Gtk::ALIGN_FILL); + dashSelector->set_valign(Gtk::ALIGN_CENTER); + table->attach(*dashSelector, 1, i, 3, 1); +#else + table->attach(*dashSelector, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); +#endif + + dashSelector->changed_signal.connect(sigc::mem_fun(*this, &StrokeStyle::lineDashChangedCB)); + + i++; + + /* Drop down marker selectors*/ + // TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes + // (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. + + spw_label(table, _("Markers:"), 0, i, NULL); + + hb = spw_hbox(table, 1, 1, i); + i++; + + startMarkerCombo = Gtk::manage(new MarkerComboBox("marker-start", SP_MARKER_LOC_START)); + startMarkerCombo->set_tooltip_text(_("Start Markers are drawn on the first node of a path or shape")); + startMarkerConn = startMarkerCombo->signal_changed().connect( + sigc::bind( + sigc::ptr_fun(&StrokeStyle::markerSelectCB), startMarkerCombo, this, SP_MARKER_LOC_START)); + startMarkerCombo->show(); + + hb->pack_start(*startMarkerCombo, true, true, 0); + + midMarkerCombo = Gtk::manage(new MarkerComboBox("marker-mid", SP_MARKER_LOC_MID)); + midMarkerCombo->set_tooltip_text(_("Mid Markers are drawn on every node of a path or shape except the first and last nodes")); + midMarkerConn = midMarkerCombo->signal_changed().connect( + sigc::bind( + sigc::ptr_fun(&StrokeStyle::markerSelectCB), midMarkerCombo, this, SP_MARKER_LOC_MID)); + midMarkerCombo->show(); + + hb->pack_start(*midMarkerCombo, true, true, 0); + + endMarkerCombo = Gtk::manage(new MarkerComboBox("marker-end", SP_MARKER_LOC_END)); + endMarkerCombo->set_tooltip_text(_("End Markers are drawn on the last node of a path or shape")); + endMarkerConn = endMarkerCombo->signal_changed().connect( + sigc::bind( + sigc::ptr_fun(&StrokeStyle::markerSelectCB), endMarkerCombo, this, SP_MARKER_LOC_END)); + endMarkerCombo->show(); + + hb->pack_start(*endMarkerCombo, true, true, 0); + + i++; + /* Join type */ // TRANSLATORS: The line join style specifies the shape to be used at the // corners of paths. It can be "miter", "round" or "bevel". @@ -230,14 +291,6 @@ StrokeStyle::StrokeStyle() : Gtk::RadioButtonGroup joinGrp; - joinMiter = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-miter"), - hb, STROKE_STYLE_BUTTON_JOIN, "miter"); - - // TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. - // For an example, draw a triangle with a large stroke width and modify the - // "Join" option (in the Fill and Stroke dialog). - joinMiter->set_tooltip_text(_("Miter join")); - joinRound = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-round"), hb, STROKE_STYLE_BUTTON_JOIN, "round"); @@ -254,7 +307,13 @@ StrokeStyle::StrokeStyle() : // "Join" option (in the Fill and Stroke dialog). joinBevel->set_tooltip_text(_("Bevel join")); - i++; + joinMiter = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-miter"), + hb, STROKE_STYLE_BUTTON_JOIN, "miter"); + + // TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. + // For an example, draw a triangle with a large stroke width and modify the + // "Join" option (in the Fill and Stroke dialog). + joinMiter->set_tooltip_text(_("Miter join")); /* Miterlimit */ // TRANSLATORS: Miter limit: only for "miter join", this limits the length @@ -265,8 +324,6 @@ StrokeStyle::StrokeStyle() : // when they become too long. //spw_label(t, _("Miter _limit:"), 0, i); - hb = spw_hbox(table, 3, 1, i); - #if WITH_GTKMM_3_0 miterLimitAdj = new Glib::RefPtr(Gtk::Adjustment::create(4.0, 0.0, 100.0, 0.1, 10.0, 0.0)); miterLimitSpin = new Inkscape::UI::Widget::SpinButton(*miterLimitAdj, 0.1, 2); @@ -277,7 +334,6 @@ StrokeStyle::StrokeStyle() : miterLimitSpin->set_tooltip_text(_("Maximum length of the miter (in units of stroke width)")); miterLimitSpin->show(); - spw_label(table, _("Miter _limit:"), 0, i, miterLimitSpin); sp_dialog_defocus_on_enter_cpp(miterLimitSpin); hb->pack_start(*miterLimitSpin, false, false, 0); @@ -288,6 +344,7 @@ StrokeStyle::StrokeStyle() : #else miterLimitAdj->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::miterLimitChangedCB)); #endif + i++; /* Cap type */ @@ -322,67 +379,6 @@ StrokeStyle::StrokeStyle() : i++; - /* Dash */ - spw_label(table, _("Dashes:"), 0, i, NULL); //no mnemonic for now - //decide what to do: - // implement a set_mnemonic_source function in the - // SPDashSelector class, so that we do not have to - // expose any of the underlying widgets? - dashSelector = Gtk::manage(new SPDashSelector); - - dashSelector->show(); - -#if WITH_GTKMM_3_0 - dashSelector->set_hexpand(); - dashSelector->set_halign(Gtk::ALIGN_FILL); - dashSelector->set_valign(Gtk::ALIGN_CENTER); - table->attach(*dashSelector, 1, i, 3, 1); -#else - table->attach(*dashSelector, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); -#endif - - dashSelector->changed_signal.connect(sigc::mem_fun(*this, &StrokeStyle::lineDashChangedCB)); - - i++; - - /* Drop down marker selectors*/ - // TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes - // (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. - - spw_label(table, _("Markers:"), 0, i, NULL); - - hb = spw_hbox(table, 1, 1, i); - i++; - - startMarkerCombo = Gtk::manage(new MarkerComboBox("marker-start", SP_MARKER_LOC_START)); - startMarkerCombo->set_tooltip_text(_("Start Markers are drawn on the first node of a path or shape")); - startMarkerConn = startMarkerCombo->signal_changed().connect( - sigc::bind( - sigc::ptr_fun(&StrokeStyle::markerSelectCB), startMarkerCombo, this, SP_MARKER_LOC_START)); - startMarkerCombo->show(); - - hb->pack_start(*startMarkerCombo, true, true, 0); - - midMarkerCombo = Gtk::manage(new MarkerComboBox("marker-mid", SP_MARKER_LOC_MID)); - midMarkerCombo->set_tooltip_text(_("Mid Markers are drawn on every node of a path or shape except the first and last nodes")); - midMarkerConn = midMarkerCombo->signal_changed().connect( - sigc::bind( - sigc::ptr_fun(&StrokeStyle::markerSelectCB), midMarkerCombo, this, SP_MARKER_LOC_MID)); - midMarkerCombo->show(); - - hb->pack_start(*midMarkerCombo, true, true, 0); - - endMarkerCombo = Gtk::manage(new MarkerComboBox("marker-end", SP_MARKER_LOC_END)); - endMarkerCombo->set_tooltip_text(_("End Markers are drawn on the last node of a path or shape")); - endMarkerConn = endMarkerCombo->signal_changed().connect( - sigc::bind( - sigc::ptr_fun(&StrokeStyle::markerSelectCB), endMarkerCombo, this, SP_MARKER_LOC_END)); - endMarkerCombo->show(); - - hb->pack_start(*endMarkerCombo, true, true, 0); - - i++; - /* Paint order */ // TRANSLATORS: Paint order determines the order the 'fill', 'stroke', and 'markers are painted. spw_label(table, _("Order:"), 0, i, NULL); -- cgit v1.2.3 From cd166baa1470b0ca83973f76fabea9a935163344 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 8 Mar 2016 15:10:38 +0100 Subject: Add PDF/PS output support for 'paint-order' property. (bzr r14696) --- src/extension/internal/cairo-render-context.cpp | 90 ++++++++++++++++++++----- src/extension/internal/cairo-render-context.h | 9 ++- src/extension/internal/cairo-renderer.cpp | 30 ++++++++- 3 files changed, 110 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index f811f00ad..5d8b0e076 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -1453,8 +1453,11 @@ CairoRenderContext::_prepareRenderText() } } +/* We need CairoPaintOrder as markers are rendered in a separate step and may be rendered + * inbetween fill and stroke. + */ bool -CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle const *style, Geom::OptRect const &pbox) +CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle const *style, Geom::OptRect const &pbox, CairoPaintOrder order) { g_assert( _is_valid ); @@ -1476,9 +1479,10 @@ CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle con return true; } - bool no_fill = style->fill.isNone() || style->fill_opacity.value == 0; + bool no_fill = style->fill.isNone() || style->fill_opacity.value == 0 || + order == STROKE_ONLY; bool no_stroke = style->stroke.isNone() || style->stroke_width.computed < 1e-9 || - style->stroke_opacity.value == 0; + style->stroke_opacity.value == 0 || order == FILL_ONLY; if (no_fill && no_stroke) return true; @@ -1492,14 +1496,17 @@ CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle con pushLayer(); if (!no_fill) { - _setFillStyle(style, pbox); - setPathVector(pathv); - if (style->fill_rule.computed == SP_WIND_RULE_EVENODD) { cairo_set_fill_rule(_cr, CAIRO_FILL_RULE_EVEN_ODD); } else { cairo_set_fill_rule(_cr, CAIRO_FILL_RULE_WINDING); } + } + + setPathVector(pathv); + + if (!no_fill && (order == STROKE_OVER_FILL || order == FILL_ONLY)) { + _setFillStyle(style, pbox); if (no_stroke) cairo_fill(_cr); @@ -1509,10 +1516,17 @@ CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle con if (!no_stroke) { _setStrokeStyle(style, pbox); - if (no_fill) - setPathVector(pathv); - cairo_stroke(_cr); + if (no_fill || order == STROKE_OVER_FILL) + cairo_stroke(_cr); + else + cairo_stroke_preserve(_cr); + } + + if (!no_fill && order == FILL_OVER_STROKE) { + _setFillStyle(style, pbox); + + cairo_fill(_cr); } if (need_layer) @@ -1642,7 +1656,7 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const &font_ma return true; // create a cairo_font_face from PangoFont - double size = style->font_size.computed; /// \fixme why is this variable never used? + // double size = style->font_size.computed; /// \fixme why is this variable never used? gpointer fonthash = (gpointer)font; cairo_font_face_t *font_face = NULL; if(font_table.find(fonthash)!=font_table.end()) @@ -1699,30 +1713,72 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const &font_ma _showGlyphs(_cr, font, glyphtext, TRUE); } } else { - bool fill = false, stroke = false, have_path = false; + + bool fill = false; if (style->fill.isColor() || style->fill.isPaintserver()) { fill = true; } + bool stroke = false; if (style->stroke.isColor() || style->stroke.isPaintserver()) { stroke = true; } - if (fill) { + + // Text never has markers + bool stroke_over_fill = true; + if ( (style->paint_order.layer[0] == SP_CSS_PAINT_ORDER_STROKE && + style->paint_order.layer[1] == SP_CSS_PAINT_ORDER_FILL) || + + (style->paint_order.layer[0] == SP_CSS_PAINT_ORDER_STROKE && + style->paint_order.layer[2] == SP_CSS_PAINT_ORDER_FILL) || + + (style->paint_order.layer[1] == SP_CSS_PAINT_ORDER_STROKE && + style->paint_order.layer[2] == SP_CSS_PAINT_ORDER_FILL) ) { + stroke_over_fill = false; + } + + bool have_path = false; + if (fill && stroke_over_fill) { _setFillStyle(style, Geom::OptRect()); if (_is_texttopath) { _showGlyphs(_cr, font, glyphtext, true); - have_path = true; - if (stroke) cairo_fill_preserve(_cr); - else cairo_fill(_cr); + if (stroke) { + cairo_fill_preserve(_cr); + have_path = true; + } else { + cairo_fill(_cr); + } } else { _showGlyphs(_cr, font, glyphtext, false); } } + if (stroke) { _setStrokeStyle(style, Geom::OptRect()); - if (!have_path) _showGlyphs(_cr, font, glyphtext, true); - cairo_stroke(_cr); + if (!have_path) { + _showGlyphs(_cr, font, glyphtext, true); + } + if (fill && _is_texttopath && !stroke_over_fill) { + cairo_stroke_preserve(_cr); + have_path = true; + } else { + cairo_stroke(_cr); + } + } + + if (fill && !stroke_over_fill) { + _setFillStyle(style, Geom::OptRect()); + if (_is_texttopath) { + if (!have_path) { + // Could happen if both 'stroke' and 'stroke_over_fill' are false + _showGlyphs(_cr, font, glyphtext, true); + } + cairo_fill(_cr); + } else { + _showGlyphs(_cr, font, glyphtext, false); + } } + } cairo_restore(_cr); diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index b3ab3655a..dfa6084d1 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -148,7 +148,14 @@ public: void addClippingRect(double x, double y, double width, double height); /* Rendering methods */ - bool renderPathVector(Geom::PathVector const &pathv, SPStyle const *style, Geom::OptRect const &pbox); + enum CairoPaintOrder { + STROKE_OVER_FILL, + FILL_OVER_STROKE, + FILL_ONLY, + STROKE_ONLY + }; + + bool renderPathVector(Geom::PathVector const &pathv, SPStyle const *style, Geom::OptRect const &pbox, CairoPaintOrder order = STROKE_OVER_FILL); bool renderImage(Inkscape::Pixbuf *pb, Geom::Affine const &image_transform, SPStyle const *style); bool renderGlyphtext(PangoFont *font, Geom::Affine const &font_matrix, diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index a4561fd11..5dc20ab06 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -194,7 +194,20 @@ static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) return; } - ctx->renderPathVector(pathv, style, pbox); + if (style->paint_order.layer[0] == SP_CSS_PAINT_ORDER_NORMAL || + (style->paint_order.layer[0] == SP_CSS_PAINT_ORDER_FILL && + style->paint_order.layer[1] == SP_CSS_PAINT_ORDER_STROKE)) { + ctx->renderPathVector(pathv, style, pbox, CairoRenderContext::STROKE_OVER_FILL); + } else if (style->paint_order.layer[0] == SP_CSS_PAINT_ORDER_STROKE && + style->paint_order.layer[1] == SP_CSS_PAINT_ORDER_FILL ) { + ctx->renderPathVector(pathv, style, pbox, CairoRenderContext::FILL_OVER_STROKE); + } else if (style->paint_order.layer[0] == SP_CSS_PAINT_ORDER_STROKE && + style->paint_order.layer[1] == SP_CSS_PAINT_ORDER_MARKER ) { + ctx->renderPathVector(pathv, style, pbox, CairoRenderContext::STROKE_ONLY); + } else if (style->paint_order.layer[0] == SP_CSS_PAINT_ORDER_FILL && + style->paint_order.layer[1] == SP_CSS_PAINT_ORDER_MARKER ) { + ctx->renderPathVector(pathv, style, pbox, CairoRenderContext::FILL_ONLY); + } // START marker for (int i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START @@ -287,6 +300,21 @@ static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); } } + + if (style->paint_order.layer[1] == SP_CSS_PAINT_ORDER_FILL && + style->paint_order.layer[2] == SP_CSS_PAINT_ORDER_STROKE) { + ctx->renderPathVector(pathv, style, pbox, CairoRenderContext::STROKE_OVER_FILL); + } else if (style->paint_order.layer[1] == SP_CSS_PAINT_ORDER_STROKE && + style->paint_order.layer[2] == SP_CSS_PAINT_ORDER_FILL ) { + ctx->renderPathVector(pathv, style, pbox, CairoRenderContext::FILL_OVER_STROKE); + } else if (style->paint_order.layer[2] == SP_CSS_PAINT_ORDER_STROKE && + style->paint_order.layer[1] == SP_CSS_PAINT_ORDER_MARKER ) { + ctx->renderPathVector(pathv, style, pbox, CairoRenderContext::STROKE_ONLY); + } else if (style->paint_order.layer[2] == SP_CSS_PAINT_ORDER_FILL && + style->paint_order.layer[1] == SP_CSS_PAINT_ORDER_MARKER ) { + ctx->renderPathVector(pathv, style, pbox, CairoRenderContext::FILL_ONLY); + } + } static void sp_group_render(SPGroup *group, CairoRenderContext *ctx) -- cgit v1.2.3 From 9836d660348065f224b68a0f13765b73c65d54f3 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Thu, 10 Mar 2016 23:00:32 +0100 Subject: Displays filename instead of blank string in unnamed palettes Fixed bugs: - https://launchpad.net/bugs/780659 (bzr r14697) --- src/ui/dialog/swatches.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index ed1cd2079..924ebe03d 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -393,10 +393,10 @@ static bool parseNum( char*& str, int& val ) { } -void _loadPaletteFile( gchar const *filename, gboolean user/*=FALSE*/ ) +void _loadPaletteFile( gchar const *filename, gchar const *path, gboolean user/*=FALSE*/ ) { char block[1024]; - FILE *f = Inkscape::IO::fopen_utf8name( filename, "r" ); + FILE *f = Inkscape::IO::fopen_utf8name(path, "r" ); if ( f ) { char* result = fgets( block, sizeof(block), f ); if ( result ) { @@ -405,6 +405,7 @@ void _loadPaletteFile( gchar const *filename, gboolean user/*=FALSE*/ ) bool hasErr = false; SwatchPage *onceMore = new SwatchPage(); + onceMore->_name = filename; do { result = fgets( block, sizeof(block), f ); @@ -521,7 +522,7 @@ compare_swatch_names(SwatchPage const *a, SwatchPage const *b) { static void loadEmUp() { static bool beenHere = false; - gboolean userPalete = true; + gboolean userPalette = true; if ( !beenHere ) { beenHere = true; @@ -549,7 +550,7 @@ static void loadEmUp() if ( !g_str_has_suffix(lower, "~") ) { gchar* full = g_build_filename(dirname, filename, NULL); if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { - _loadPaletteFile(full, userPalete); + _loadPaletteFile(filename, full, userPalette); } g_free(full); } @@ -563,7 +564,7 @@ static void loadEmUp() // toss the dirname g_free(dirname); sources.pop_front(); - userPalete = false; + userPalette = false; } } -- cgit v1.2.3 From 43884ced57f56cf41ad2d7fac3a8f5ba87f78276 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Fri, 11 Mar 2016 02:06:39 +0100 Subject: Improvements on the "new from template" dialog -> greyed buttons when no dialogs selected (bug 1363450) -> selected template deselects when filtered out -> filtering down to 1 template selects it -> selected template keeps looking selected when filtered Fixed bugs: - https://launchpad.net/bugs/1363450 (bzr r14698) --- src/ui/dialog/new-from-template.cpp | 18 +++++++++++++++--- src/ui/dialog/new-from-template.h | 6 ++++-- src/ui/dialog/template-load-tab.cpp | 38 +++++++++++++++++++++++++++++-------- src/ui/dialog/template-load-tab.h | 4 +++- src/ui/dialog/template-widget.cpp | 26 ++++++++++++++++--------- src/ui/dialog/template-widget.h | 1 + 6 files changed, 70 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/new-from-template.cpp b/src/ui/dialog/new-from-template.cpp index e30b148bb..74ec7111e 100644 --- a/src/ui/dialog/new-from-template.cpp +++ b/src/ui/dialog/new-from-template.cpp @@ -29,10 +29,12 @@ NewFromTemplate::NewFromTemplate() set_title(_("New From Template")); resize(400, 400); + _main_widget = new TemplateLoadTab(this); + #if WITH_GTKMM_3_0 - get_content_area()->pack_start(_main_widget); + get_content_area()->pack_start(*_main_widget); #else - get_vbox()->pack_start(_main_widget); + get_vbox()->pack_start(*_main_widget); #endif Gtk::Alignment *align; @@ -49,14 +51,24 @@ NewFromTemplate::NewFromTemplate() _create_template_button.signal_clicked().connect( sigc::mem_fun(*this, &NewFromTemplate::_createFromTemplate)); + _create_template_button.set_sensitive(false); show_all(); } +NewFromTemplate::~NewFromTemplate() +{ + delete _main_widget; +} + +void NewFromTemplate::setCreateButtonSensitive(bool value) +{ + _create_template_button.set_sensitive(value); +} void NewFromTemplate::_createFromTemplate() { - _main_widget.createTemplate(); + _main_widget->createTemplate(); _onClose(); } diff --git a/src/ui/dialog/new-from-template.h b/src/ui/dialog/new-from-template.h index 2b40af2a6..c0b65affb 100644 --- a/src/ui/dialog/new-from-template.h +++ b/src/ui/dialog/new-from-template.h @@ -27,11 +27,13 @@ class NewFromTemplate : public Gtk::Dialog friend class TemplateLoadTab; public: static void load_new_from_template(); - + void setCreateButtonSensitive(bool value); + virtual ~NewFromTemplate(); + private: NewFromTemplate(); Gtk::Button _create_template_button; - TemplateLoadTab _main_widget; + TemplateLoadTab* _main_widget; void _createFromTemplate(); void _onClose(); diff --git a/src/ui/dialog/template-load-tab.cpp b/src/ui/dialog/template-load-tab.cpp index fca1f7b30..7eb04ff79 100644 --- a/src/ui/dialog/template-load-tab.cpp +++ b/src/ui/dialog/template-load-tab.cpp @@ -35,10 +35,11 @@ namespace Inkscape { namespace UI { -TemplateLoadTab::TemplateLoadTab() +TemplateLoadTab::TemplateLoadTab(NewFromTemplate* parent) : _current_keyword("") , _keywords_combo(true) , _current_search_type(ALL) + , _parent_widget(parent) { set_border_width(10); @@ -94,7 +95,8 @@ void TemplateLoadTab::_displayTemplateInfo() if (templateSelectionRef->get_selected()) { _current_template = (*templateSelectionRef->get_selected())[_columns.textValue]; - _info_widget->display(_tdata[_current_template]); + _info_widget->display(_tdata[_current_template]); + _parent_widget->setCreateButtonSensitive(true); } } @@ -148,11 +150,10 @@ void TemplateLoadTab::_keywordSelected() void TemplateLoadTab::_refreshTemplatesList() { - _tlist_store->clear(); - + _tlist_store->clear(); + switch (_current_search_type){ case ALL :{ - for (std::map::iterator it = _tdata.begin() ; it != _tdata.end() ; ++it) { Gtk::TreeModel::iterator iter = _tlist_store->append(); Gtk::TreeModel::Row row = *iter; @@ -160,7 +161,7 @@ void TemplateLoadTab::_refreshTemplatesList() } break; } - + case LIST_KEYWORD: { for (std::map::iterator it = _tdata.begin() ; it != _tdata.end() ; ++it) { if (it->second.keywords.count(_current_keyword.lowercase()) != 0){ @@ -171,10 +172,10 @@ void TemplateLoadTab::_refreshTemplatesList() } break; } - + case USER_SPECIFIED : { for (std::map::iterator it = _tdata.begin() ; it != _tdata.end() ; ++it) { - if (it->second.keywords.count(_current_keyword.lowercase()) != 0 || + if (it->second.keywords.count(_current_keyword.lowercase()) != 0 || it->second.display_name.lowercase().find(_current_keyword.lowercase()) != Glib::ustring::npos || it->second.author.lowercase().find(_current_keyword.lowercase()) != Glib::ustring::npos || it->second.short_description.lowercase().find(_current_keyword.lowercase()) != Glib::ustring::npos || @@ -188,6 +189,27 @@ void TemplateLoadTab::_refreshTemplatesList() break; } } + + // reselect item + Gtk::TreeIter* item_to_select = NULL; + for (Gtk::TreeModel::Children::iterator it = _tlist_store->children().begin(); it != _tlist_store->children().end(); ++it) { + Gtk::TreeModel::Row row = *it; + if (_current_template == row[_columns.textValue]) { + item_to_select = new Gtk::TreeIter(it); + break; + } + } + if (_tlist_store->children().size() == 1) { + item_to_select = new Gtk::TreeIter(_tlist_store->children().begin()); + } + if (item_to_select) { + _tlist_view.get_selection()->select(*item_to_select); + delete item_to_select; + } else { + _current_template = ""; + _info_widget->clear(); + _parent_widget->setCreateButtonSensitive(false); + } } diff --git a/src/ui/dialog/template-load-tab.h b/src/ui/dialog/template-load-tab.h index 920ae6ca2..d11c4c77f 100644 --- a/src/ui/dialog/template-load-tab.h +++ b/src/ui/dialog/template-load-tab.h @@ -28,6 +28,7 @@ namespace Inkscape { namespace UI { class TemplateWidget; +class NewFromTemplate; class TemplateLoadTab : public Gtk::HBox { @@ -47,7 +48,7 @@ public: Inkscape::Extension::Effect *tpl_effect; }; - TemplateLoadTab(); + TemplateLoadTab(NewFromTemplate* parent); virtual ~TemplateLoadTab(); virtual void createTemplate(); @@ -95,6 +96,7 @@ private: }; SearchType _current_search_type; + NewFromTemplate* _parent_widget; void _getDataFromNode(Inkscape::XML::Node *, TemplateData &); void _getProceduralTemplates(); diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index eff75b311..0d110d853 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -56,6 +56,7 @@ TemplateWidget::TemplateWidget() _more_info_button.signal_clicked().connect( sigc::mem_fun(*this, &TemplateWidget::_displayTemplateDetails)); + _more_info_button.set_sensitive(false); } @@ -85,14 +86,12 @@ void TemplateWidget::create() void TemplateWidget::display(TemplateLoadTab::TemplateData data) { + clear(); _current_template = data; _template_name_label.set_text(_current_template.display_name); _short_description_label.set_text(_current_template.short_description); - - _preview_render.hide(); - _preview_image.hide(); - + std::string imagePath = Glib::build_filename(Glib::path_get_dirname(_current_template.path), _current_template.preview_name); if (data.preview_name != ""){ _preview_image.set(imagePath); @@ -103,17 +102,26 @@ void TemplateWidget::display(TemplateLoadTab::TemplateData data) _preview_render.showImage(gPath); _preview_render.show(); } - - if (_effect_prefs != NULL){ - remove (*_effect_prefs); - _effect_prefs = NULL; - } + if (data.is_procedural){ _effect_prefs = data.tpl_effect->get_imp()->prefs_effect(data.tpl_effect, SP_ACTIVE_DESKTOP, NULL, NULL); pack_start(*_effect_prefs); } + _more_info_button.set_sensitive(true); } +void TemplateWidget::clear() +{ + _template_name_label.set_text(""); + _short_description_label.set_text(""); + _preview_render.hide(); + _preview_image.hide(); + if (_effect_prefs != NULL){ + remove (*_effect_prefs); + _effect_prefs = NULL; + } + _more_info_button.set_sensitive(false); +} void TemplateWidget::_displayTemplateDetails() { diff --git a/src/ui/dialog/template-widget.h b/src/ui/dialog/template-widget.h index bb35d26a0..13488089c 100644 --- a/src/ui/dialog/template-widget.h +++ b/src/ui/dialog/template-widget.h @@ -28,6 +28,7 @@ public: TemplateWidget (); void create(); void display(TemplateLoadTab::TemplateData); + void clear(); private: TemplateLoadTab::TemplateData _current_template; -- cgit v1.2.3 From baf25c4bd70f2cd99ed7888c94a6a77b4781e225 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Fri, 11 Mar 2016 12:33:16 -0800 Subject: patch for bug 1538361, work around limits in mingw/MSVCRT (bzr r14699) --- src/extension/internal/emf-print.cpp | 2 +- src/extension/internal/text_reassemble.c | 82 ++++++++++++++++---------------- 2 files changed, 42 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index 3dfa5cb23..1c85182ae 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -253,7 +253,7 @@ unsigned int PrintEmf::begin(Inkscape::Extension::Print *mod, SPDocument *doc) char *oldlocale = g_strdup(setlocale(LC_NUMERIC, NULL)); setlocale(LC_NUMERIC, "C"); - snprintf(buff, sizeof(buff) - 1, "Drawing=%.1lfx%.1lfpx, %.1lfx%.1lfmm", _width, _height, Inkscape::Util::Quantity::convert(dwInchesX, "in", "mm"), Inkscape::Util::Quantity::convert(dwInchesY, "in", "mm")); + snprintf(buff, sizeof(buff) - 1, "Drawing=%.1fx%.1fpx, %.1fx%.1fmm", _width, _height, Inkscape::Util::Quantity::convert(dwInchesX, "in", "mm"), Inkscape::Util::Quantity::convert(dwInchesY, "in", "mm")); setlocale(LC_NUMERIC, oldlocale); g_free(oldlocale); rec = textcomment_set(buff); diff --git a/src/extension/internal/text_reassemble.c b/src/extension/internal/text_reassemble.c index fa983b83d..b23176ed5 100644 --- a/src/extension/internal/text_reassemble.c +++ b/src/extension/internal/text_reassemble.c @@ -67,11 +67,11 @@ Optional compiler switches for development: File: text_reassemble.c -Version: 0.0.17 -Date: 21-MAY-2015 +Version: 0.0.18 +Date: 11-MAR-2016 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu -Copyright: 2015 David Mathog and California Institute of Technology (Caltech) +Copyright: 2016 David Mathog and California Institute of Technology (Caltech) */ #ifdef __cplusplus @@ -223,7 +223,7 @@ char *TR_construct_fontspec(const TCHUNK_SPECS *tsp, const char *fontname){ int newlen = 128 + strlen(fontname); /* too big, but not by much */ char *newfs = NULL; newfs = (char *) malloc(newlen); - sprintf(newfs,"%s:slant=%d:weight=%d:size=%lf:width=%d",fontname,tsp->italics,tsp->weight,tsp->fs,(tsp->co ? 75 : tsp->condensed)); + sprintf(newfs,"%s:slant=%d:weight=%d:size=%f:width=%d",fontname,tsp->italics,tsp->weight,tsp->fs,(tsp->co ? 75 : tsp->condensed)); return(newfs); } @@ -804,7 +804,7 @@ int ftinfo_load_fontname(FT_INFO *fti, const char *fontspec){ int fb; if(FcPatternGetBool( fpat, FC_OUTLINE, 0, &fb)== FcResultMatch){ printf("outline: %d\n",fb);fflush(stdout); } if(FcPatternGetBool( fpat, FC_SCALABLE, 0, &fb)== FcResultMatch){ printf("scalable: %d\n",fb);fflush(stdout); } - if(FcPatternGetDouble( fpat, FC_DPI, 0, &fd)== FcResultMatch){ printf("DPI: %lf\n",fd);fflush(stdout); } + if(FcPatternGetDouble( fpat, FC_DPI, 0, &fd)== FcResultMatch){ printf("DPI: %f\n",fd);fflush(stdout); } if(FcPatternGetInteger( fpat, FC_FONTVERSION, 0, &fb)== FcResultMatch){ printf("fontversion: %d\n",fb);fflush(stdout); } if(FcPatternGetString( fpat, FC_FULLNAME , 0, (FcChar8 **)&fs)== FcResultMatch){ printf("FULLNAME : %s\n",fs);fflush(stdout); } if(FcPatternGetString( fpat, FC_FAMILY , 0, (FcChar8 **)&fs)== FcResultMatch){ printf("FAMILY : %s\n",fs);fflush(stdout); } @@ -831,7 +831,7 @@ void ftinfo_dump(const FT_INFO *fti){ printf("fti used: %d\n",fti->used); for(i=0; i< fti->used; i++){ fsp = &(fti->fonts[i]); - printf("fti font: %6d space: %6d used: %6d spcadv %8lf fsize %8lf \n",i,fsp->space,fsp->used,fsp->spcadv,fsp->fsize); + printf("fti font: %6d space: %6d used: %6d spcadv %8f fsize %8f \n",i,fsp->space,fsp->used,fsp->spcadv,fsp->fsize); printf(" file: %s\n",fsp->file); printf(" fspc: %s\n",fsp->fontspec); for(j=0;jused;j++){ @@ -1123,18 +1123,18 @@ void cxinfo_dump(const TR_INFO *tri){ printf("cxi phase1: %d\n",cxi->phase1); printf("cxi lines: %d\n",cxi->lines); printf("cxi paras: %d\n",cxi->paras); - printf("cxi xy: %lf , %lf\n",tri->x,tri->y); + printf("cxi xy: %f , %f\n",tri->x,tri->y); for(i=0;iused;i++){ csp = &(cxi->cx[i]); bsp = &(bri->rects[csp->rt_cidx]); printf("cxi cx[%d] type:%d rt_tidx:%d kids_used:%d kids_space:%d\n",i, csp->type, csp->rt_cidx, csp->kids.used, csp->kids.space); - printf("cxi cx[%d] br (LL,UR) (%lf,%lf),(%lf,%lf)\n",i,bsp->xll,bsp->yll,bsp->xur,bsp->yur); + printf("cxi cx[%d] br (LL,UR) (%f,%f),(%f,%f)\n",i,bsp->xll,bsp->yll,bsp->xur,bsp->yur); for(j=0;jkids.used;j++){ k = csp->kids.members[j]; bsp = &(bri->rects[k]); if(csp->type == TR_TEXT || csp->type == TR_LINE){ - printf("cxi cx[%d] member:%3d tp_idx:%3d ldir:%d rt_tidx:%3d br (LL,UR) (%8.3lf,%8.3lf),(%8.3lf,%8.3lf) xy (%8.3lf,%8.3lf) kern (%8.3lf,%8.3lf) text:<%s> decor:%5.5x\n", + printf("cxi cx[%d] member:%3d tp_idx:%3d ldir:%d rt_tidx:%3d br (LL,UR) (%8.3f,%8.3f),(%8.3f,%8.3f) xy (%8.3f,%8.3f) kern (%8.3f,%8.3f) text:<%s> decor:%5.5x\n", i, j, k, tpi->chunks[k].ldir, tpi->chunks[k].rt_tidx, bsp->xll,bsp->yll,bsp->xur,bsp->yur, tpi->chunks[k].x, tpi->chunks[k].y, @@ -1311,7 +1311,7 @@ int brinfo_merge(BR_INFO *bri, int dst, int src){ bri->rects[dst].xur = TEREMAX(bri->rects[dst].xur, bri->rects[src].xur); bri->rects[dst].yur = TEREMIN(bri->rects[dst].yur, bri->rects[src].yur); /* MIN because Y is positive DOWN */ /* -printf("bri_Merge into rect:%d (LL,UR) dst:(%lf,%lf),(%lf,%lf) src:(%lf,%lf),(%lf,%lf)\n",dst, +printf("bri_Merge into rect:%d (LL,UR) dst:(%f,%f),(%f,%f) src:(%f,%f),(%f,%f)\n",dst, (bri->rects[dst].xll), (bri->rects[dst].yll), (bri->rects[dst].xur), @@ -1374,7 +1374,7 @@ int brinfo_overlap(const BR_INFO *bri, int dst, int src, RT_PAD *rp_dst, RT_PAD } } /* -printf("Overlap status:%d\nOverlap trects (LL,UR) dst:(%lf,%lf),(%lf,%lf) src:(%lf,%lf),(%lf,%lf)\n", +printf("Overlap status:%d\nOverlap trects (LL,UR) dst:(%f,%f),(%f,%f) src:(%f,%f),(%f,%f)\n", status, (br_dst->xll - rp_dst->left ), (br_dst->yll - rp_dst->down ), @@ -1384,7 +1384,7 @@ status, (br_src->yll - rp_src->down ), (br_src->xur + rp_src->right), (br_src->yur + rp_src->up )); -printf("Overlap brects (LL,UR) dst:(%lf,%lf),(%lf,%lf) src:(%lf,%lf),(%lf,%lf)\n", +printf("Overlap brects (LL,UR) dst:(%f,%f),(%f,%f) src:(%f,%f),(%f,%f)\n", (br_dst->xll), (br_dst->yll), (br_dst->xur), @@ -1393,7 +1393,7 @@ printf("Overlap brects (LL,UR) dst:(%lf,%lf),(%lf,%lf) src:(%lf,%lf),(%lf,%lf)\n (br_src->yll), (br_src->xur), (br_src->yur)); -printf("Overlap rprect (LL,UR) dst:(%lf,%lf),(%lf,%lf) src:(%lf,%lf),(%lf,%lf)\n", +printf("Overlap rprect (LL,UR) dst:(%f,%f),(%f,%f) src:(%f,%f),(%f,%f)\n", (rp_dst->left), (rp_dst->down), (rp_dst->right), @@ -1481,7 +1481,7 @@ enum tr_classes brinfo_pp_alignment(const BR_INFO *bri, int dst, int src, double newtype = TR_PARA_UJ; } /* -printf("pp_align newtype:%d brects (LL,UR) dst:(%lf,%lf),(%lf,%lf) src:(%lf,%lf),(%lf,%lf)\n", +printf("pp_align newtype:%d brects (LL,UR) dst:(%f,%f),(%f,%f) src:(%f,%f),(%f,%f)\n", newtype, (br_dst->xll), (br_dst->yll), @@ -1779,7 +1779,7 @@ int trinfo_load_textrec(TR_INFO *tri, const TCHUNK_SPECS *tsp, double escapement tpi->chunks[current].y = x * sin(escapement) + y * cos(escapement); /* Careful! face bbox does NOT scale with FT_Set_Char_Size -printf("Face idx:%d bbox: xMax/Min:%ld,%ld yMax/Min:%ld,%ld UpEM:%d asc/des:%d,%d height:%d size:%lf\n", +printf("Face idx:%d bbox: xMax/Min:%ld,%ld yMax/Min:%ld,%ld UpEM:%d asc/des:%d,%d height:%d size:%f\n", idx, fsp->face->bbox.xMax,fsp->face->bbox.xMin, fsp->face->bbox.yMax,fsp->face->bbox.yMin, @@ -1955,7 +1955,7 @@ void TR_layout_2_svg(TR_INFO *tri){ /* put rectangles down for each text string - debugging!!! This will not work properly for any Narrow fonts */ esc = tri->esc; esc *= 2.0 * M_PI / 360.0; /* degrees to radians and change direction of rotation */ - sprintf(stransform,"transform=\"matrix(%lf,%lf,%lf,%lf,%lf,%lf)\"\n",cos(esc),-sin(esc),sin(esc),cos(esc), 1.25*x,1.25*y); + sprintf(stransform,"transform=\"matrix(%f,%f,%f,%f,%f,%f)\"\n",cos(esc),-sin(esc),sin(esc),cos(esc), 1.25*x,1.25*y); for(i=cxi->phase1; iused;i++){ /* over all complex members from phase2 == TR_PARA_* complexes */ csp = &(cxi->cx[i]); for(j=0; jkids.used; j++){ /* over all members of these complexes, which are phase1 complexes */ @@ -1968,11 +1968,11 @@ void TR_layout_2_svg(TR_INFO *tri){ #if DBG_TR_PARA TRPRINT(tri, "rects[csp->rt_cidx].xur - bri->rects[csp->rt_cidx].xll)); + sprintf(obuf,"width=\"%f\"\n", 1.25*(bri->rects[csp->rt_cidx].xur - bri->rects[csp->rt_cidx].xll)); TRPRINT(tri, obuf); - sprintf(obuf,"height=\"%lf\"\n",1.25*(bri->rects[csp->rt_cidx].yll - bri->rects[csp->rt_cidx].yur)); + sprintf(obuf,"height=\"%f\"\n",1.25*(bri->rects[csp->rt_cidx].yll - bri->rects[csp->rt_cidx].yur)); TRPRINT(tri, obuf); - sprintf(obuf,"x=\"%lf\" y=\"%lf\"\n",1.25*(bri->rects[csp->rt_cidx].xll),1.25*(bri->rects[csp->rt_cidx].yur)); + sprintf(obuf,"x=\"%f\" y=\"%f\"\n",1.25*(bri->rects[csp->rt_cidx].xll),1.25*(bri->rects[csp->rt_cidx].yur)); TRPRINT(tri, obuf); TRPRINT(tri, stransform); TRPRINT(tri, "/>\n"); @@ -1983,23 +1983,23 @@ void TR_layout_2_svg(TR_INFO *tri){ newy = 1.25*(bri->rects[tsp->rt_tidx].yur); TRPRINT(tri, "rects[tsp->rt_tidx].xur - bri->rects[tsp->rt_tidx].xll)); + sprintf(obuf,"width=\"%f\"\n", 1.25*(bri->rects[tsp->rt_tidx].xur - bri->rects[tsp->rt_tidx].xll)); TRPRINT(tri, obuf); - sprintf(obuf,"height=\"%lf\"\n",1.25*(bri->rects[tsp->rt_tidx].yll - bri->rects[tsp->rt_tidx].yur)); + sprintf(obuf,"height=\"%f\"\n",1.25*(bri->rects[tsp->rt_tidx].yll - bri->rects[tsp->rt_tidx].yur)); TRPRINT(tri, obuf); - sprintf(obuf,"x=\"%lf\" y=\"%lf\"\n",1.25*(bri->rects[tsp->rt_tidx].xll),newy); + sprintf(obuf,"x=\"%f\" y=\"%f\"\n",1.25*(bri->rects[tsp->rt_tidx].xll),newy); TRPRINT(tri, obuf); TRPRINT(tri, stransform); TRPRINT(tri, "/>\n"); newy = 1.25*(bri->rects[tsp->rt_tidx].yll - tsp->boff); - sprintf(obuf,"fs*1.25); /*IMPORTANT, if the FS is given in pt it looks like crap in browsers. As if px != 1.25 pt, maybe 96 dpi not 90?*/ + sprintf(obuf,"font-size:%fpx;",tsp->fs*1.25); /*IMPORTANT, if the FS is given in pt it looks like crap in browsers. As if px != 1.25 pt, maybe 96 dpi not 90?*/ TRPRINT(tri, obuf); sprintf(obuf,"font-style:%s;",(tsp->italics ? "italic" : "normal")); TRPRINT(tri, obuf); @@ -2025,7 +2025,7 @@ void TR_layout_2_svg(TR_INFO *tri){ if(tri->usebk){ esc = tri->esc; esc *= 2.0 * M_PI / 360.0; /* degrees to radians and change direction of rotation */ - sprintf(stransform,"transform=\"matrix(%lf,%lf,%lf,%lf,%lf,%lf)\"\n",cos(esc),-sin(esc),sin(esc),cos(esc), 1.25*x,1.25*y); + sprintf(stransform,"transform=\"matrix(%f,%f,%f,%f,%f,%f)\"\n",cos(esc),-sin(esc),sin(esc),cos(esc), 1.25*x,1.25*y); for(i=cxi->phase1; iused;i++){ /* over all complex members from phase2 == TR_PARA_* complexes */ TRPRINT(tri, "\n"); /* group backgrounds for each object in the SVG */ @@ -2037,11 +2037,11 @@ void TR_layout_2_svg(TR_INFO *tri){ TRPRINT(tri, "bkcolor.Red,tri->bkcolor.Green,tri->bkcolor.Blue); TRPRINT(tri, obuf); - sprintf(obuf,"width=\"%lf\"\n", 1.25*(bri->rects[cline_sp->rt_cidx].xur - bri->rects[cline_sp->rt_cidx].xll)); + sprintf(obuf,"width=\"%f\"\n", 1.25*(bri->rects[cline_sp->rt_cidx].xur - bri->rects[cline_sp->rt_cidx].xll)); TRPRINT(tri, obuf); - sprintf(obuf,"height=\"%lf\"\n",1.25*(bri->rects[cline_sp->rt_cidx].yll - bri->rects[cline_sp->rt_cidx].yur)); + sprintf(obuf,"height=\"%f\"\n",1.25*(bri->rects[cline_sp->rt_cidx].yll - bri->rects[cline_sp->rt_cidx].yur)); TRPRINT(tri, obuf); - sprintf(obuf,"x=\"%lf\" y=\"%lf\"\n",1.25*(bri->rects[cline_sp->rt_cidx].xll),1.25*(bri->rects[cline_sp->rt_cidx].yur)); + sprintf(obuf,"x=\"%f\" y=\"%f\"\n",1.25*(bri->rects[cline_sp->rt_cidx].xll),1.25*(bri->rects[cline_sp->rt_cidx].yur)); TRPRINT(tri, obuf); TRPRINT(tri, stransform); TRPRINT(tri, "/>\n"); @@ -2056,11 +2056,11 @@ void TR_layout_2_svg(TR_INFO *tri){ TRPRINT(tri, "bkcolor.Red,tri->bkcolor.Green,tri->bkcolor.Blue); TRPRINT(tri, obuf); - sprintf(obuf,"width=\"%lf\"\n", 1.25*(bri->rects[csp->rt_cidx].xur - bri->rects[csp->rt_cidx].xll)); + sprintf(obuf,"width=\"%f\"\n", 1.25*(bri->rects[csp->rt_cidx].xur - bri->rects[csp->rt_cidx].xll)); TRPRINT(tri, obuf); - sprintf(obuf,"height=\"%lf\"\n",1.25*(bri->rects[csp->rt_cidx].yll - bri->rects[csp->rt_cidx].yur)); + sprintf(obuf,"height=\"%f\"\n",1.25*(bri->rects[csp->rt_cidx].yll - bri->rects[csp->rt_cidx].yur)); TRPRINT(tri, obuf); - sprintf(obuf,"x=\"%lf\" y=\"%lf\"\n",1.25*(bri->rects[csp->rt_cidx].xll),1.25*(bri->rects[csp->rt_cidx].yur)); + sprintf(obuf,"x=\"%f\" y=\"%f\"\n",1.25*(bri->rects[csp->rt_cidx].xll),1.25*(bri->rects[csp->rt_cidx].yur)); TRPRINT(tri, obuf); TRPRINT(tri, stransform); TRPRINT(tri, "/>\n"); @@ -2072,11 +2072,11 @@ void TR_layout_2_svg(TR_INFO *tri){ TRPRINT(tri, "bkcolor.Red,tri->bkcolor.Green,tri->bkcolor.Blue); TRPRINT(tri, obuf); - sprintf(obuf,"width=\"%lf\"\n", 1.25*(bri->rects[tsp->rt_tidx].xur - bri->rects[tsp->rt_tidx].xll)); + sprintf(obuf,"width=\"%f\"\n", 1.25*(bri->rects[tsp->rt_tidx].xur - bri->rects[tsp->rt_tidx].xll)); TRPRINT(tri, obuf); - sprintf(obuf,"height=\"%lf\"\n",1.25*(bri->rects[tsp->rt_tidx].yll - bri->rects[tsp->rt_tidx].yur)); + sprintf(obuf,"height=\"%f\"\n",1.25*(bri->rects[tsp->rt_tidx].yll - bri->rects[tsp->rt_tidx].yur)); TRPRINT(tri, obuf); - sprintf(obuf,"x=\"%lf\" y=\"%lf\"\n",newx,newy); + sprintf(obuf,"x=\"%f\" y=\"%f\"\n",newx,newy); TRPRINT(tri, obuf); TRPRINT(tri, stransform); TRPRINT(tri, "/>\n"); @@ -2135,7 +2135,7 @@ void TR_layout_2_svg(TR_INFO *tri){ TRPRINT(tri, "fs*1.25); /*IMPORTANT, if the FS is given in pt it looks like crap in browsers. As if px != 1.25 pt, maybe 96 dpi not 90?*/ + sprintf(obuf,"font-size:%fpx;",tsp->fs*1.25); /*IMPORTANT, if the FS is given in pt it looks like crap in browsers. As if px != 1.25 pt, maybe 96 dpi not 90?*/ TRPRINT(tri, obuf); sprintf(obuf,"font-style:%s;",(tsp->italics ? "italic" : "normal")); TRPRINT(tri, obuf); @@ -2146,7 +2146,7 @@ void TR_layout_2_svg(TR_INFO *tri){ TRPRINT(tri, obuf); if(tsp->vadvance){ lineheight = tsp->vadvance *100.0; } else { lineheight = 125.0; } - sprintf(obuf,"line-height:%lf%%;",lineheight); + sprintf(obuf,"line-height:%f%%;",lineheight); TRPRINT(tri, obuf); TRPRINT(tri, "letter-spacing:0px;"); TRPRINT(tri, "word-spacing:0px;"); @@ -2174,14 +2174,14 @@ void TR_layout_2_svg(TR_INFO *tri){ } TRPRINT(tri, obuf); TRPRINT(tri, "\"\n"); /* End of style specification */ - sprintf(obuf,"transform=\"matrix(%lf,%lf,%lf,%lf,%lf,%lf)\"\n",cos(esc),-sin(esc),sin(esc),cos(esc),1.25*x,1.25*y); + sprintf(obuf,"transform=\"matrix(%f,%f,%f,%f,%f,%f)\"\n",cos(esc),-sin(esc),sin(esc),cos(esc),1.25*x,1.25*y); TRPRINT(tri, obuf); tmpx = 1.25*((ldir == LDIR_RL ? bri->rects[kdx].xur : bri->rects[kdx].xll) + recenter); - sprintf(obuf,"x=\"%lf\" y=\"%lf\"\n>",tmpx,1.25*(bri->rects[kdx].yll - tsp->boff)); + sprintf(obuf,"x=\"%f\" y=\"%f\"\n>",tmpx,1.25*(bri->rects[kdx].yll - tsp->boff)); TRPRINT(tri, obuf); } tmpx = 1.25*((ldir == LDIR_RL ? bri->rects[kdx].xur : bri->rects[kdx].xll) + recenter); - sprintf(obuf,"",tmpx,1.25*(bri->rects[kdx].yll - tsp->boff)); + sprintf(obuf,"",tmpx,1.25*(bri->rects[kdx].yll - tsp->boff)); TRPRINT(tri, obuf); } TRPRINT(tri, "xkern; dy = 1.25 * tsp->ykern; - sprintf(obuf,"dx=\"%lf\" dy=\"%lf\" ",dx, dy); + sprintf(obuf,"dx=\"%f\" dy=\"%f\" ",dx, dy); TRPRINT(tri, obuf); sprintf(obuf,"style=\"fill:#%2.2X%2.2X%2.2X;",tsp->color.Red,tsp->color.Green,tsp->color.Blue); TRPRINT(tri, obuf); - sprintf(obuf,"font-size:%lfpx;",tsp->fs*1.25); /*IMPORTANT, if the FS is given in pt it looks like crap in browsers. As if px != 1.25 pt, maybe 96 dpi not 90?*/ + sprintf(obuf,"font-size:%fpx;",tsp->fs*1.25); /*IMPORTANT, if the FS is given in pt it looks like crap in browsers. As if px != 1.25 pt, maybe 96 dpi not 90?*/ TRPRINT(tri, obuf); sprintf(obuf,"font-style:%s;",(tsp->italics ? "italic" : "normal")); TRPRINT(tri, obuf); -- cgit v1.2.3 From c9d12eb92288ab99118138376cf5c3b76d6a22da Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 12 Mar 2016 17:42:06 +0100 Subject: Add new TTF to the logo in seamless pattern extension Add checkboard background to the same extension Update template to 0.01+devel Fix a bug on SPPatern when apply a transform = Affine() (bzr r14700) --- src/sp-pattern.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index dd351a8d5..55110f3c5 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -390,10 +390,11 @@ const gchar *SPPattern::produce(const std::vector &reprs, repr->setAttribute("patternUnits", "userSpaceOnUse"); sp_repr_set_svg_double(repr, "width", bounds.dimensions()[Geom::X]); sp_repr_set_svg_double(repr, "height", bounds.dimensions()[Geom::Y]); - - Glib::ustring t = sp_svg_transform_write(transform); - repr->setAttribute("patternTransform", t); - + //TODO: Maybe is better handle it in sp_svg_transform_write + if(transform != Geom::Affine()){ + Glib::ustring t = sp_svg_transform_write(transform); + repr->setAttribute("patternTransform", t); + } defsrepr->appendChild(repr); const gchar *pat_id = repr->attribute("id"); SPObject *pat_object = document->getObjectById(pat_id); -- cgit v1.2.3 From 1c9e7ee09d40b8e06b80d0a09eca17d1b0fb8357 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 12 Mar 2016 18:50:04 -0500 Subject: Add a units box to line height and wire in the style units, plus some cleanup (bzr r14701) --- src/desktop-style.cpp | 8 ++- src/libnrtype/Layout-TNG.cpp | 2 +- src/sp-text.cpp | 9 --- src/style.cpp | 4 +- src/ui/widget/unit-tracker.cpp | 10 +++ src/ui/widget/unit-tracker.h | 1 + src/util/units.cpp | 70 ++++++++++++++---- src/util/units.h | 8 +++ src/widgets/select-toolbar.cpp | 159 +++++++++++++++++++---------------------- src/widgets/text-toolbar.cpp | 81 +++++++++++++++++---- src/widgets/toolbox.cpp | 6 ++ 11 files changed, 233 insertions(+), 125 deletions(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index c36bcee44..c28302d22 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -1049,6 +1049,7 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r double letterspacing_prev = 0; double wordspacing_prev = 0; double linespacing_prev = 0; + int linespacing_unit = 0; int texts = 0; int no_size = 0; @@ -1105,6 +1106,11 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r linespacing_current = style->line_height.computed; linespacing_normal = false; } + if (linespacing_unit == 0) { + linespacing_unit = style->line_height.unit; + } else if (linespacing_unit != style->line_height.unit) { + linespacing_unit = SP_CSS_UNIT_PERCENT; + } linespacing += linespacing_current; if ((size_prev != 0 && style->font_size.computed != size_prev) || @@ -1148,7 +1154,7 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r style_res->line_height.normal = linespacing_normal; style_res->line_height.computed = linespacing; style_res->line_height.value = linespacing; - style_res->line_height.unit = SP_CSS_UNIT_PERCENT; + style_res->line_height.unit = linespacing_unit; if (texts > 1) { if (different) { diff --git a/src/libnrtype/Layout-TNG.cpp b/src/libnrtype/Layout-TNG.cpp index 8b0889188..ec488b584 100644 --- a/src/libnrtype/Layout-TNG.cpp +++ b/src/libnrtype/Layout-TNG.cpp @@ -14,7 +14,7 @@ namespace Inkscape { namespace Text { const gunichar Layout::UNICODE_SOFT_HYPHEN = 0x00AD; -const double Layout::LINE_HEIGHT_NORMAL = 1.25; +const double Layout::LINE_HEIGHT_NORMAL = 125; Layout::Layout() : _input_truncated(0), diff --git a/src/sp-text.cpp b/src/sp-text.cpp index afbe0b147..4a5b1b1d6 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -302,15 +302,6 @@ Inkscape::XML::Node *SPText::write(Inkscape::XML::Document *xml_doc, Inkscape::X this->attributes.writeTo(repr); this->rebuildLayout(); // copied from update(), see LP Bug 1339305 - // deprecated attribute, but keep it around for backwards compatibility - if (this->style->line_height.set && !this->style->line_height.inherit && !this->style->line_height.normal && this->style->line_height.unit == SP_CSS_UNIT_PERCENT) { - Inkscape::SVGOStringStream os; - os << (this->style->line_height.value * 100.0) << "%"; - this->getRepr()->setAttribute("sodipodi:linespacing", os.str().c_str()); - } else { - this->getRepr()->setAttribute("sodipodi:linespacing", NULL); - } - // SVG 2 Auto-wrapped text if( this->width.computed > 0.0 ) { sp_repr_set_svg_double(repr, "width", this->width.computed); diff --git a/src/style.cpp b/src/style.cpp index 35138d25b..99beaed22 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -113,7 +113,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : font_weight( "font-weight", enum_font_weight, SP_CSS_FONT_WEIGHT_NORMAL, SP_CSS_FONT_WEIGHT_400 ), font_stretch( "font-stretch", enum_font_stretch, SP_CSS_FONT_STRETCH_NORMAL ), font_size(), - line_height( "line-height", 1.25 ), // SPILengthOrNormal + line_height( "line-height", 125 ), // SPILengthOrNormal font_family( "font-family", "sans-serif" ), // SPIString w/default font(), // SPIFont font_specification( "-inkscape-font-specification" ), // SPIString @@ -1957,7 +1957,7 @@ sp_css_attr_scale(SPCSSAttr *css, double ex) sp_css_attr_scale_property_single(css, "kerning", ex); sp_css_attr_scale_property_single(css, "letter-spacing", ex); sp_css_attr_scale_property_single(css, "word-spacing", ex); - sp_css_attr_scale_property_single(css, "line-height", ex, true); + //sp_css_attr_scale_property_single(css, "line-height", ex, true); return css; } diff --git a/src/ui/widget/unit-tracker.cpp b/src/ui/widget/unit-tracker.cpp index c6318db25..a1501c229 100644 --- a/src/ui/widget/unit-tracker.cpp +++ b/src/ui/widget/unit-tracker.cpp @@ -12,6 +12,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include "style-internal.h" #include "unit-tracker.h" #include "widgets/ege-select-one-action.h" @@ -121,6 +122,15 @@ void UnitTracker::addUnit(Inkscape::Util::Unit const *u) gtk_list_store_set(_store, &iter, COLUMN_STRING, u ? u->abbr.c_str() : "NULL", -1); } +void UnitTracker::prependUnit(Inkscape::Util::Unit const *u) +{ + GtkTreeIter iter; + gtk_list_store_prepend(_store, &iter); + gtk_list_store_set(_store, &iter, COLUMN_STRING, u ? u->abbr.c_str() : "NULL", -1); + /* Re-shuffle our default selection here (_active gets out of sync) */ + setActiveUnit(_activeUnit); +} + void UnitTracker::setFullVal(GtkAdjustment *adj, gdouble val) { _priorValues[adj] = val; diff --git a/src/ui/widget/unit-tracker.h b/src/ui/widget/unit-tracker.h index 06245930e..0fe5bda80 100644 --- a/src/ui/widget/unit-tracker.h +++ b/src/ui/widget/unit-tracker.h @@ -42,6 +42,7 @@ public: Inkscape::Util::Unit const * getActiveUnit() const; void addUnit(Inkscape::Util::Unit const *u); + void prependUnit(Inkscape::Util::Unit const *u); void addAdjustment(GtkAdjustment *adj); void setFullVal(GtkAdjustment *adj, gdouble val); diff --git a/src/util/units.cpp b/src/util/units.cpp index 2c72ec3ae..2e7a3b1d2 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -81,7 +81,21 @@ unsigned const svg_length_lookup[] = { UNIT_CODE_PERCENT }; - +/* From SP_CSS_UNIT_* to unit */ +unsigned const sp_css_unit_lookup[] = { + 0, + UNIT_CODE_PX, + UNIT_CODE_PT, + UNIT_CODE_PC, + UNIT_CODE_MM, + UNIT_CODE_CM, + UNIT_CODE_IN, + UNIT_CODE_EM, + UNIT_CODE_EX, + UNIT_CODE_PERCENT + // UNIT_CODE_FT Missing, + // UNIT_CODE_MT Missing, +}; // maps unit codes obtained from their abbreviations to their SVGLength unit indexes typedef INK_UNORDERED_MAP UnitCodeLookup; @@ -213,6 +227,10 @@ bool Unit::compatibleWith(Glib::ustring const &u) const { return compatibleWith(unit_table.getUnit(u)); } +bool Unit::compatibleWith(char const *u) const +{ + return compatibleWith(unit_table.getUnit(u)); +} bool Unit::operator==(Unit const &other) const { @@ -231,7 +249,29 @@ int Unit::svgUnit() const return 0; } - +double Unit::convert(double from_dist, Unit const *to) const +{ + // Percentage + if (to->type == UNIT_TYPE_DIMENSIONLESS) { + return from_dist * to->factor; + } + + // Incompatible units + if (type != to->type) { + return -1; + } + + // Compatible units + return from_dist * factor / to->factor; +} +double Unit::convert(double from_dist, Glib::ustring const &to) const +{ + return convert(from_dist, unit_table.getUnit(to)); +} +double Unit::convert(double from_dist, char const *to) const +{ + return convert(from_dist, unit_table.getUnit(to)); +} Unit UnitTable::_empty_unit; @@ -283,6 +323,19 @@ Unit const *UnitTable::getUnit(SVGLength::Unit u) const } return &_empty_unit; } +/* SP_CSS_UNIT lookup */ +Unit const *UnitTable::getUnit(unsigned int u) const +{ + if (u == 0 || u > 9) { + return &_empty_unit; + } + + UnitCodeMap::const_iterator f = _unit_map.find(sp_css_unit_lookup[u]); + if (f != _unit_map.end()) { + return &(*f->second); + } + return &_empty_unit; +} Unit const *UnitTable::findUnit(double factor, UnitType type) const { @@ -505,18 +558,7 @@ Glib::ustring Quantity::string() const { double Quantity::convert(double from_dist, Unit const *from, Unit const *to) { - // Percentage - if (to->type == UNIT_TYPE_DIMENSIONLESS) { - return from_dist * to->factor; - } - - // Incompatible units - if (from->type != to->type) { - return -1; - } - - // Compatible units - return from_dist * from->factor / to->factor; + return from->convert(from_dist, to); } double Quantity::convert(double from_dist, Glib::ustring const &from, Unit const *to) { diff --git a/src/util/units.h b/src/util/units.h index 13777fd1b..a840a37ec 100644 --- a/src/util/units.h +++ b/src/util/units.h @@ -75,6 +75,11 @@ public: /** Get SVG unit code. */ int svgUnit() const; + + /** Convert value from this unit **/ + double convert(double from_dist, Unit const *to) const; + double convert(double from_dist, Glib::ustring const &to) const; + double convert(double from_dist, char const *to) const; }; class Quantity @@ -147,6 +152,9 @@ public: /** Retrieve a given unit based on its SVGLength unit */ Unit const *getUnit(SVGLength::Unit u) const; + + /** Retrieve a given unit based on its SP_CSS_UNIT */ + Unit const *getUnit(unsigned int u) const; /** Retrieve a quantity based on its string identifier */ Quantity parseQuantity(Glib::ustring const &q) const; diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index e49c4c00a..3cd6c0e28 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -136,13 +136,13 @@ sp_selection_layout_widget_change_selection(SPWidget *spw, Inkscape::Selection * } static void -sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) +sp_object_layout_any_value_changed(GtkAdjustment *adj, GObject *tbl) { - if (g_object_get_data(G_OBJECT(spw), "update")) { + if (g_object_get_data(tbl, "update")) { return; } - UnitTracker *tracker = reinterpret_cast(g_object_get_data(G_OBJECT(spw), "tracker")); + UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); if ( !tracker || tracker->isUpdating() ) { /* * When only units are being changed, don't treat changes @@ -150,7 +150,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) */ return; } - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); + g_object_set_data(tbl, "update", GINT_TO_POINTER(TRUE)); SPDesktop *desktop = SP_ACTIVE_DESKTOP; Inkscape::Selection *selection = desktop->getSelection(); @@ -168,7 +168,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) Geom::OptRect bbox_user = selection->bounds(bbox_type); if ( !bbox_user ) { - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); + g_object_set_data(tbl, "update", GINT_TO_POINTER(FALSE)); return; } @@ -181,10 +181,10 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) Unit const *unit = tracker->getActiveUnit(); g_return_if_fail(unit != NULL); - GtkAdjustment* a_x = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "X" ) ); - GtkAdjustment* a_y = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "Y" ) ); - GtkAdjustment* a_w = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "width" ) ); - GtkAdjustment* a_h = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "height" ) ); + GtkAdjustment* a_x = GTK_ADJUSTMENT( g_object_get_data( tbl, "X" ) ); + GtkAdjustment* a_y = GTK_ADJUSTMENT( g_object_get_data( tbl, "Y" ) ); + GtkAdjustment* a_w = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) ); + GtkAdjustment* a_h = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) ); if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { x0 = Quantity::convert(gtk_adjustment_get_value(a_x), unit, "px"); @@ -205,7 +205,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) } // Keep proportions if lock is on - GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(G_OBJECT(spw), "lock") ); + GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "lock") ); if ( gtk_toggle_action_get_active(lock) ) { if (adj == a_h) { x1 = x0 + yrel * bbox_user->dimensions()[Geom::X]; @@ -265,68 +265,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) desktop->getCanvas()->endForcedFullRedraws(); } - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); -} - -static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRate, guint digits, Inkscape::UI::Widget::UnitTracker *unit_tracker ) -{ -#if WITH_GTKMM_3_0 - Glib::RefPtr adj = Glib::wrap(adjustment, true); - Inkscape::UI::Widget::SpinButton *inkSpinner = new Inkscape::UI::Widget::SpinButton(adj, climbRate, digits); -#else - Inkscape::UI::Widget::SpinButton *inkSpinner = new Inkscape::UI::Widget::SpinButton(*Glib::wrap(adjustment, true), climbRate, digits); -#endif - inkSpinner->addUnitTracker(unit_tracker); - inkSpinner = Gtk::manage( inkSpinner ); - GtkWidget *widget = GTK_WIDGET( inkSpinner->gobj() ); - return widget; -} - -// TODO create_adjustment_action appears to be a rogue tile copy from toolbox.cpp. Resolve it to be unified: - -static EgeAdjustmentAction * create_adjustment_action( gchar const *name, - gchar const *label, - gchar const *shortLabel, - gchar const *data, - gdouble lower, - GtkWidget* focusTarget, - UnitTracker* tracker, - GtkWidget* spw, - gchar const *tooltip, - gboolean altx ) -{ - static bool init = false; - if ( !init ) { - init = true; - ege_adjustment_action_set_compact_tool_factory( createCustomSlider ); - } - - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0.0, lower, 1e6, SPIN_STEP, SPIN_PAGE_STEP, 0 ) ); - if (tracker) { - tracker->addAdjustment(adj); - } - if ( spw ) { - g_object_set_data( G_OBJECT(spw), data, adj ); - } - - EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, Q_(label), tooltip, 0, SPIN_STEP, 3, tracker ); - if ( shortLabel ) { - g_object_set( act, "short_label", Q_(shortLabel), NULL ); - } - - g_signal_connect( G_OBJECT(adj), "value_changed", G_CALLBACK(sp_object_layout_any_value_changed), spw ); - if ( focusTarget ) { - ege_adjustment_action_set_focuswidget( act, focusTarget ); - } - - if ( altx ) { // this spinbutton will be activated by alt-x - g_object_set( G_OBJECT(act), "self-id", "altx", NULL ); - } - - // Using a cast just to make sure we pass in the right kind of function pointer - g_object_set( G_OBJECT(act), "tool-post", static_cast(sp_set_font_size_smaller), NULL ); - - return act; + g_object_set_data(tbl, "update", GINT_TO_POINTER(FALSE)); } // toggle button callbacks and updaters @@ -497,21 +436,60 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb // four spinbuttons - eact = create_adjustment_action( "XAction", C_("Select toolbar", "X position"), C_("Select toolbar", "X:"), "X", - -1e6, GTK_WIDGET(desktop->canvas), tracker, spw, - _("Horizontal coordinate of selection"), TRUE ); + eact = create_adjustment_action( + /* name= */ "XAction", + /* label= */ C_("Select toolbar", "X position"), + /* shortLabel= */ C_("Select toolbar", "X:"), + /* tooltip= */ C_("Select toolbar", "Horizontal coordinate of selection"), + /* path= */ "/tools/select/X", + /* def(default) */ 0.0, + /* focusTarget= */ GTK_WIDGET(desktop->canvas), + /* dataKludge= */ G_OBJECT(spw), + /* altx, altx_mark */ TRUE, "altx", + /* lower, uppper, step, page */ -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + /* descrLabels, descrValues, descrCount */ 0, 0, 0, + /* callback= */ sp_object_layout_any_value_changed, + /* unit_tracker= */ tracker, + /* climb, digits, factor */ SPIN_STEP, 3, 1); + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); - eact = create_adjustment_action( "YAction", C_("Select toolbar", "Y position"), C_("Select toolbar", "Y:"), "Y", - -1e6, GTK_WIDGET(desktop->canvas), tracker, spw, - _("Vertical coordinate of selection"), FALSE ); + eact = create_adjustment_action( + /* name= */ "YAction", + /* label= */ C_("Select toolbar", "Y position"), + /* shortLabel= */ C_("Select toolbar", "Y:"), + /* tooltip= */ C_("Select toolbar", "Vertical coordinate of selection"), + /* path= */ "/tools/select/Y", + /* def(default) */ 0.0, + /* focusTarget= */ GTK_WIDGET(desktop->canvas), + /* dataKludge= */ G_OBJECT(spw), + /* altx, altx_mark */ TRUE, "altx", + /* lower, uppper, step, page */ -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + /* descrLabels, descrValues, descrCount */ 0, 0, 0, + /* callback= */ sp_object_layout_any_value_changed, + /* unit_tracker= */ tracker, + /* climb, digits, factor */ SPIN_STEP, 3, 1); + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); - eact = create_adjustment_action( "WidthAction", C_("Select toolbar", "Width"), C_("Select toolbar", "W:"), "width", - 0.0, GTK_WIDGET(desktop->canvas), tracker, spw, - _("Width of selection"), FALSE ); + eact = create_adjustment_action( + /* name= */ "WidthAction", + /* label= */ C_("Select toolbar", "Width"), + /* shortLabel= */ C_("Select toolbar", "W:"), + /* tooltip= */ C_("Select toolbar", "Width of selection"), + /* path= */ "/tools/select/width", + /* def(default) */ 0.0, + /* focusTarget= */ GTK_WIDGET(desktop->canvas), + /* dataKludge= */ G_OBJECT(spw), + /* altx, altx_mark */ TRUE, "altx", + /* lower, uppper, step, page */ 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + /* descrLabels, descrValues, descrCount */ 0, 0, 0, + /* callback= */ sp_object_layout_any_value_changed, + /* unit_tracker= */ tracker, + /* climb, digits, factor */ SPIN_STEP, 3, 1); + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); @@ -528,9 +506,22 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); } - eact = create_adjustment_action( "HeightAction", C_("Select toolbar", "Height"), C_("Select toolbar", "H:"), "height", - 0.0, GTK_WIDGET(desktop->canvas), tracker, spw, - _("Height of selection"), FALSE ); + eact = create_adjustment_action( + /* name= */ "HeightAction", + /* label= */ C_("Select toolbar", "Height"), + /* shortLabel= */ C_("Select toolbar", "H:"), + /* tooltip= */ C_("Select toolbar", "Height of selection"), + /* path= */ "/tools/select/height", + /* def(default) */ 0.0, + /* focusTarget= */ GTK_WIDGET(desktop->canvas), + /* dataKludge= */ G_OBJECT(spw), + /* altx, altx_mark */ TRUE, "altx", + /* lower, uppper, step, page */ 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + /* descrLabels, descrValues, descrCount */ 0, 0, 0, + /* callback= */ sp_object_layout_any_value_changed, + /* unit_tracker= */ tracker, + /* climb, digits, factor */ SPIN_STEP, 3, 1); + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 5ca92b4c0..c49f0bc05 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -54,12 +54,17 @@ #include "ui/icon-names.h" #include "ui/tools/text-tool.h" #include "ui/tools/tool-base.h" +#include "ui/widget/unit-tracker.h" +#include "util/units.h" #include "verbs.h" #include "xml/repr.h" using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; using Inkscape::UI::PrefPusher; +using Inkscape::UI::Widget::UnitTracker; +using Inkscape::Util::Unit; +using Inkscape::Util::unit_table; //#define DEBUG_TEXT @@ -504,8 +509,14 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) { - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); + + if ( !tracker || tracker->isUpdating() || g_object_get_data(tbl, "freeze")) { + /* + * When only units are being changed, don't treat changes + * to adjuster values as object changes. + * or quit if run by the _changed callbacks + */ return; } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); @@ -514,7 +525,18 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) // Set css line height. SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream osfs; - osfs << gtk_adjustment_get_value(adj)*100 << "%"; + + gdouble value = gtk_adjustment_get_value(adj); + + Unit const *unit = tracker->getActiveUnit(); + + // Value can only be in px or percent or naked pc (e.g. 0.7 for 70%) + if (unit->abbr != "%") { + value = unit->convert(value, "px"); + unit = unit_table.getUnit("px"); + } + + osfs << value << unit->abbr; sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); // Apply line-height to selected objects. @@ -1073,21 +1095,31 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Line height (spacing) double height; + + Unit const *lh_unit; + UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); + if (query.line_height.normal) { - height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; + lh_unit = unit_table.getUnit("%"); + height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL * 100; + } else if (query.line_height.unit == SP_CSS_UNIT_PERCENT) { + lh_unit = unit_table.getUnit("%"); + height = query.line_height.value * 100; } else { - if (query.line_height.unit == SP_CSS_UNIT_PERCENT) { - height = query.line_height.value; - } else { - height = query.line_height.computed; - } + lh_unit = tracker->getActiveUnit(); + // Can get unit like this: unit_table.getUnit(query.line_height.unit); + height = Inkscape::Util::Quantity::convert(query.line_height.computed, "px", lh_unit); } + // Set before value is set + tracker->setActiveUnit(lh_unit); + GtkAction* lineHeightAction = GTK_ACTION( g_object_get_data( tbl, "TextLineHeightAction" ) ); GtkAdjustment *lineHeightAdjustment = ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( lineHeightAction )); gtk_adjustment_set_value( lineHeightAdjustment, height ); + height = gtk_adjustment_get_value( lineHeightAdjustment ); // Word spacing double wordSpacing; @@ -1290,6 +1322,15 @@ static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*p static void text_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); +static void destroy_tracker( GObject* obj, gpointer /*user_data*/ ) +{ + UnitTracker *tracker = reinterpret_cast(g_object_get_data(obj, "tracker")); + if ( tracker ) { + delete tracker; + g_object_set_data( obj, "tracker", 0 ); + } +} + // Define all the "widgets" in the toolbar. void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { @@ -1588,22 +1629,29 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje gchar const* labels[] = {_("Smaller spacing"), 0, 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, _("Larger spacing")}; gdouble values[] = { 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1,2, 1.3, 1.4, 1.5, 2.0}; + // Add the units menu. + UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); + tracker->prependUnit(unit_table.getUnit("%")); + + g_object_set_data( holder, "tracker", tracker ); + g_signal_connect( holder, "destroy", G_CALLBACK(destroy_tracker), holder ); + EgeAdjustmentAction *eact = create_adjustment_action( "TextLineHeightAction", /* name */ _("Line Height"), /* label */ _("Line:"), /* short label */ - _("Spacing between baselines (times font size)"), /* tooltip */ + _("Spacing between baselines"), /* tooltip */ "/tools/text/lineheight", /* preferences path */ - 0.0, /* default */ + 125, /* default */ GTK_WIDGET(desktop->canvas), /* focusTarget */ holder, /* dataKludge */ FALSE, /* set alt-x keyboard shortcut? */ NULL, /* altx_mark */ - 0.0, 10.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ + 0.0, 1e6, 1.0, 10.0, /* lower, upper, step (arrow up/down), page up/down */ labels, values, G_N_ELEMENTS(labels), /* drop down menu */ sp_text_lineheight_value_changed, /* callback */ - NULL, /* unit tracker */ - 0.1, /* step (used?) */ + tracker, /* unit tracker */ + 1.0, /* step (used?) */ 2, /* digits to show */ 1.0 /* factor (multiplies default) */ ); @@ -1611,6 +1659,11 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); g_object_set_data( holder, "TextLineHeightAction", eact ); g_object_set( G_OBJECT(eact), "iconId", "text_line_spacing", NULL ); + + GtkAction* act = tracker->createAction( "TextLineHeightUnitAction", _("Units"), ("") ); + gtk_action_group_add_action( mainActions, act ); + g_object_set_data( holder, "TextLineHeightUnitAction", act ); + } /* Word spacing */ diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 72537f727..f4d7ebf25 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -55,6 +55,7 @@ #include "ui/tools-switch.h" #include "../ui/icon-names.h" #include "../ui/widget/style-swatch.h" +#include "../ui/widget/unit-tracker.h" #include "../verbs.h" #include "../widgets/button.h" #include "../widgets/spinbutton-events.h" @@ -515,6 +516,7 @@ static gchar const * ui_descr = " " " " " " + " " " " " " " " @@ -1122,6 +1124,10 @@ EgeAdjustmentAction * create_adjustment_action( gchar const *name, g_object_set_data( dataKludge, prefs->getEntry(path).getEntryName().data(), adj ); } + if (unit_tracker) { + unit_tracker->addAdjustment(adj); + } + // Using a cast just to make sure we pass in the right kind of function pointer g_object_set( G_OBJECT(act), "tool-post", static_cast(sp_set_font_size_smaller), NULL ); -- cgit v1.2.3 From d7b1e066fa7c7d9e6a83d688fe48c5f06620bf10 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Mon, 14 Mar 2016 00:50:24 +0100 Subject: "Relative to" option for node alignment. - Node tool has those new "relative to" alignment options : last selected, first selected, current behaviour (middle), max value(rightmost/topmost) or min value(leftmost/bottommost). - Verbs: --If the node tool is active and whole objects are selected (no individual node is), works as usual for objects; --Else, align horizontal/vertical (SP_VERB_ALIGN_HORIZONTAL_CENTER) honor the "relative to" settings, SP_VERB_ALIGN_HORIZONTAL_LEFT (ctrl+alt+pavnum4) aligns vertically on the leftmost node (same behavior as SP_VERB_ALIGN_HORIZONTAL_LEFT when the setting is "align relative to min value"), and so on with all alignment verbs Fixed bugs: - https://launchpad.net/bugs/171287 (bzr r14703) --- src/ui/dialog/align-and-distribute.cpp | 76 ++++++++++++++++++++++++++++++++- src/ui/dialog/align-and-distribute.h | 11 +++++ src/ui/tool/control-point-selection.cpp | 29 ++++++++++++- src/ui/tool/control-point-selection.h | 3 ++ 4 files changed, 116 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 5a16ecce8..8f87932b8 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -42,6 +42,7 @@ #include "ui/icon-names.h" #include "ui/tools/node-tool.h" #include "ui/tool/multi-path-manipulator.h" +#include "ui/tool/control-point-selection.h" #include "verbs.h" #include "widgets/icon.h" #include "sp-root.h" @@ -88,6 +89,42 @@ Action::Action(const Glib::ustring &id, } +void ActionAlign::do_node_action(Inkscape::UI::Tools::NodeTool *nt, int verb) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int prev_pref = prefs->getInt("/dialogs/align/align-nodes-to"); + switch(verb){ + case SP_VERB_ALIGN_HORIZONTAL_LEFT: + prefs->setInt("/dialogs/align/align-nodes-to", MIN_NODE ); + nt->_multipath->alignNodes(Geom::Y); + break; + case SP_VERB_ALIGN_HORIZONTAL_CENTER: + nt->_multipath->alignNodes(Geom::Y); + break; + case SP_VERB_ALIGN_HORIZONTAL_RIGHT: + prefs->setInt("/dialogs/align/align-nodes-to", MAX_NODE ); + nt->_multipath->alignNodes(Geom::Y); + break; + case SP_VERB_ALIGN_VERTICAL_TOP: + prefs->setInt("/dialogs/align/align-nodes-to", MAX_NODE ); + nt->_multipath->alignNodes(Geom::X); + break; + case SP_VERB_ALIGN_VERTICAL_CENTER: + nt->_multipath->alignNodes(Geom::X); + break; + case SP_VERB_ALIGN_VERTICAL_BOTTOM: + prefs->setInt("/dialogs/align/align-nodes-to", MIN_NODE ); + nt->_multipath->alignNodes(Geom::X); + break; + case SP_VERB_ALIGN_VERTICAL_HORIZONTAL_CENTER: + nt->_multipath->alignNodes(Geom::X); + nt->_multipath->alignNodes(Geom::Y); + break; + default:return; + } + prefs->setInt("/dialogs/align/align-nodes-to", prev_pref ); +} + void ActionAlign::do_action(SPDesktop *desktop, int index) { Inkscape::Selection *selection = desktop->getSelection(); @@ -187,6 +224,14 @@ ActionAlign::Coeffs const ActionAlign::_allCoeffs[11] = { void ActionAlign::do_verb_action(SPDesktop *desktop, int verb) { + Inkscape::UI::Tools::ToolBase *event_context = desktop->getEventContext(); + if (INK_IS_NODE_TOOL(event_context)) { + Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(event_context); + if(!nt->_selected_nodes->empty()){ + do_node_action(nt, verb); + return; + } + } do_action(desktop, verb_to_coeff(verb)); } @@ -871,6 +916,9 @@ static void on_tool_changed(AlignAndDistribute *daad) SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop && desktop->getEventContext()) daad->setMode(tools_active(desktop) == TOOLS_NODES); + else + daad->setMode(false); + } static void on_selection_changed(AlignAndDistribute *daad) @@ -905,6 +953,7 @@ AlignAndDistribute::AlignAndDistribute() _nodesTable(1, 4, true), #endif _anchorLabel(_("Relative to: ")), + _anchorLabelNode(_("Relative to: ")), _selgrpLabel(_("_Treat selection as group: "), 1) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -1043,9 +1092,20 @@ AlignAndDistribute::AlignAndDistribute() _combo.set_active(prefs->getInt("/dialogs/align/align-to", 6)); _combo.signal_changed().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_ref_change)); + _comboNode.append(_("Last selected")); + _comboNode.append(_("First selected")); + _comboNode.append(_("Middle of selection")); + _comboNode.append(_("Min value")); + _comboNode.append(_("Max value")); + _comboNode.set_active(prefs->getInt("/dialogs/align/align-nodes-to", 2)); + _comboNode.signal_changed().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_node_ref_change)); + _anchorBox.pack_end(_combo, false, false); _anchorBox.pack_end(_anchorLabel, false, false); + _anchorBoxNode.pack_end(_comboNode, false, false); + _anchorBoxNode.pack_end(_anchorLabelNode, false, false); + _selgrpLabel.set_mnemonic_widget(_selgrp); _selgrpBox.pack_end(_selgrp, false, false); _selgrpBox.pack_end(_selgrpLabel, false, false); @@ -1063,11 +1123,15 @@ AlignAndDistribute::AlignAndDistribute() _alignBox.pack_start(_selgrpBox); _alignBox.pack_start(_alignTableBox); + _alignBoxNode.pack_start(_anchorBoxNode, false, false); + _alignBoxNode.pack_start(_nodesTableBox); + + _alignFrame.add(_alignBox); _distributeFrame.add(_distributeTableBox); _rearrangeFrame.add(_rearrangeTableBox); _removeOverlapFrame.add(_removeOverlapTableBox); - _nodesFrame.add(_nodesTableBox); + _nodesFrame.add(_alignBoxNode); Gtk::Box *contents = _getContents(); contents->set_spacing(4); @@ -1078,7 +1142,7 @@ AlignAndDistribute::AlignAndDistribute() contents->pack_start(_distributeFrame, true, true); contents->pack_start(_rearrangeFrame, true, true); contents->pack_start(_removeOverlapFrame, true, true); - contents->pack_start(_nodesFrame, true, true); + contents->pack_start(_nodesFrame, true, false); //Connect to the global tool change signal _toolChangeConn = INKSCAPE.signal_eventcontext_set.connect(sigc::hide<0>(sigc::bind(sigc::ptr_fun(&on_tool_changed), this))); @@ -1124,6 +1188,13 @@ void AlignAndDistribute::on_ref_change(){ //Make blink the master } +void AlignAndDistribute::on_node_ref_change(){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/dialogs/align/align-nodes-to", _comboNode.get_active_row_number()); + + //Make blink the master +} + void AlignAndDistribute::on_selgrp_toggled(){ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setInt("/dialogs/align/sel-as-groups", _selgrp.get_active()); @@ -1149,6 +1220,7 @@ void AlignAndDistribute::setMode(bool nodeEdit) ((_rearrangeFrame).*(mSel))(); ((_removeOverlapFrame).*(mSel))(); ((_nodesFrame).*(mNode))(); + _getContents()->queue_resize(); } void AlignAndDistribute::addAlignButton(const Glib::ustring &id, const Glib::ustring tiptext, diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h index d337775cf..f8cc61af2 100644 --- a/src/ui/dialog/align-and-distribute.h +++ b/src/ui/dialog/align-and-distribute.h @@ -18,6 +18,7 @@ #include #include "ui/widget/panel.h" #include "ui/widget/frame.h" + #include #include #include @@ -35,6 +36,9 @@ class SPItem; namespace Inkscape { namespace UI { +namespace Tools{ +class NodeTool; +} namespace Dialog { class Action; @@ -68,6 +72,7 @@ public: protected: void on_ref_change(); + void on_node_ref_change(); void on_selgrp_toggled(); void addDistributeButton(const Glib::ustring &id, const Glib::ustring tiptext, guint row, guint col, bool onInterSpace, @@ -114,15 +119,19 @@ protected: Gtk::HBox _anchorBox; Gtk::HBox _selgrpBox; Gtk::VBox _alignBox; + Gtk::VBox _alignBoxNode; Gtk::HBox _alignTableBox; Gtk::HBox _distributeTableBox; Gtk::HBox _rearrangeTableBox; Gtk::HBox _removeOverlapTableBox; Gtk::HBox _nodesTableBox; Gtk::Label _anchorLabel; + Gtk::Label _anchorLabelNode; Gtk::Label _selgrpLabel; Gtk::CheckButton _selgrp; Gtk::ComboBoxText _combo; + Gtk::HBox _anchorBoxNode; + Gtk::ComboBoxText _comboNode; SPDesktop *_desktop; DesktopTracker _deskTrack; @@ -150,6 +159,7 @@ class Action { public : enum AlignTarget { LAST=0, FIRST, BIGGEST, SMALLEST, PAGE, DRAWING, SELECTION }; + enum AlignTargetNode { LAST_NODE=0, FIRST_NODE, MID_NODE, MIN_NODE, MAX_NODE }; Action(const Glib::ustring &id, const Glib::ustring &tiptext, guint row, guint column, @@ -213,6 +223,7 @@ private : } static void do_action(SPDesktop *desktop, int index); + static void do_node_action(Inkscape::UI::Tools::NodeTool *nt, int index); guint _index; AlignAndDistribute &_dialog; diff --git a/src/ui/tool/control-point-selection.cpp b/src/ui/tool/control-point-selection.cpp index 998f74ee0..f36ad7374 100644 --- a/src/ui/tool/control-point-selection.cpp +++ b/src/ui/tool/control-point-selection.cpp @@ -19,6 +19,8 @@ #include "ui/tool/transform-handle-set.h" #include "ui/tool/node.h" + + #include namespace Inkscape { @@ -82,6 +84,7 @@ std::pair ControlPointSelection::insert(c } found = _points.insert(x).first; + _points_list.push_back(x); x->updateState(); _pointChanged(x, true); @@ -97,6 +100,7 @@ std::pair ControlPointSelection::insert(c void ControlPointSelection::erase(iterator pos) { SelectableControlPoint *erased = *pos; + _points_list.remove(*pos); _points.erase(pos); erased->updateState(); _pointChanged(erased, false); @@ -219,8 +223,11 @@ void ControlPointSelection::transform(Geom::Affine const &m) /** Align control points on the specified axis. */ void ControlPointSelection::align(Geom::Dim2 axis) { + enum AlignTargetNode { LAST_NODE=0, FIRST_NODE, MID_NODE, MIN_NODE, MAX_NODE }; if (empty()) return; Geom::Dim2 d = static_cast((axis + 1) % 2); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Geom::OptInterval bound; for (iterator i = _points.begin(); i != _points.end(); ++i) { @@ -229,7 +236,27 @@ void ControlPointSelection::align(Geom::Dim2 axis) if (!bound) { return; } - double new_coord = bound->middle(); + double new_coord; + switch (AlignTargetNode(prefs->getInt("/dialogs/align/align-nodes-to", 2))){ + case FIRST_NODE: + new_coord=(_points_list.front())->position()[d]; + break; + case LAST_NODE: + new_coord=(_points_list.back())->position()[d]; + break; + case MID_NODE: + new_coord=bound->middle(); + break; + case MIN_NODE: + new_coord=bound->min(); + break; + case MAX_NODE: + new_coord=bound->max(); + break; + default: + return; + } + for (iterator i = _points.begin(); i != _points.end(); ++i) { Geom::Point pos = (*i)->position(); pos[d] = new_coord; diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index 2d812c0a3..f122a468d 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -12,6 +12,7 @@ #ifndef SEEN_UI_TOOL_CONTROL_POINT_SELECTION_H #define SEEN_UI_TOOL_CONTROL_POINT_SELECTION_H +#include #include #include #include @@ -140,6 +141,8 @@ private: double _rotationRadius(Geom::Point const &); set_type _points; + //the purpose of this list is to keep track of first and last selected + std::list _points_list; set_type _all_points; INK_UNORDERED_MAP _original_positions; INK_UNORDERED_MAP _last_trans; -- cgit v1.2.3