diff options
| author | Jabiertxof <jtx@jtx> | 2017-03-16 19:08:44 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx> | 2017-03-16 19:08:44 +0000 |
| commit | 8330d0ef2b97c73121ead78ea9fbcec6ee01f879 (patch) | |
| tree | 1b1717d1706ee6ebfecc800f2cc80430eb0450e0 /src/ui/tools | |
| parent | update to trunk (diff) | |
| parent | Fix rendering when canvas rotated. General code clean-up and documentation. (diff) | |
| download | inkscape-8330d0ef2b97c73121ead78ea9fbcec6ee01f879.tar.gz inkscape-8330d0ef2b97c73121ead78ea9fbcec6ee01f879.zip | |
Update to trunk
(bzr r13645.1.170)
Diffstat (limited to 'src/ui/tools')
| -rw-r--r-- | src/ui/tools/flood-tool.cpp | 59 | ||||
| -rw-r--r-- | src/ui/tools/freehand-base.h | 6 | ||||
| -rw-r--r-- | src/ui/tools/mesh-tool.cpp | 2 | ||||
| -rw-r--r-- | src/ui/tools/select-tool.cpp | 2 | ||||
| -rw-r--r-- | src/ui/tools/text-tool.cpp | 56 | ||||
| -rw-r--r-- | src/ui/tools/text-tool.h | 1 | ||||
| -rw-r--r-- | src/ui/tools/tool-base.cpp | 26 |
7 files changed, 116 insertions, 36 deletions
diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp index 1801a0ea0..6e1d085aa 100644 --- a/src/ui/tools/flood-tool.cpp +++ b/src/ui/tools/flood-tool.cpp @@ -21,6 +21,7 @@ #include <config.h> #endif +#include <cmath> #include "trace/potrace/inkscape-potrace.h" #include <2geom/pathvector.h> #include <gdk/gdkkeysyms.h> @@ -186,6 +187,21 @@ inline unsigned char * get_trace_pixel(guchar *trace_px, int x, int y, int width } /** + * \brief Check whether two unsigned integers are close to each other + * + * \param[in] a The 1st unsigned int + * \param[in] b The 2nd unsigned int + * \param[in] d The threshold for comparison + * + * \return true if |a-b| <= d; false otherwise + */ +static bool compare_guint32(guint32 const a, guint32 const b, guint32 const d) +{ + const int difference = std::abs(static_cast<int>(a) - static_cast<int>(b)); + return difference <= d; +} + +/** * Compare a pixel in a pixel buffer with another pixel to determine if a point should be included in the fill operation. * @param check The pixel in the pixel buffer to check. * @param orig The original selected pixel to use as the fill target color. @@ -196,7 +212,6 @@ inline unsigned char * get_trace_pixel(guchar *trace_px, int x, int y, int width */ static bool compare_pixels(guint32 check, guint32 orig, guint32 merged_orig_pixel, guint32 dtc, int threshold, PaintBucketChannels method) { - int diff = 0; float hsl_check[3] = {0,0,0}, hsl_orig[3] = {0,0,0}; guint32 ac = 0, rc = 0, gc = 0, bc = 0; @@ -222,27 +237,35 @@ static bool compare_pixels(guint32 check, guint32 orig, guint32 merged_orig_pixe switch (method) { case FLOOD_CHANNELS_ALPHA: - return abs(static_cast<int>(ac) - ao) <= threshold; + return compare_guint32(ac, ao, threshold); case FLOOD_CHANNELS_R: - return abs(static_cast<int>(ac ? unpremul_alpha(rc, ac) : 0) - (ao ? unpremul_alpha(ro, ao) : 0)) <= threshold; + return compare_guint32(ac ? unpremul_alpha(rc, ac) : 0, + ao ? unpremul_alpha(ro, ao) : 0, + threshold); case FLOOD_CHANNELS_G: - return abs(static_cast<int>(ac ? unpremul_alpha(gc, ac) : 0) - (ao ? unpremul_alpha(go, ao) : 0)) <= threshold; + return compare_guint32(ac ? unpremul_alpha(gc, ac) : 0, + ao ? unpremul_alpha(go, ao) : 0, + threshold); case FLOOD_CHANNELS_B: - return abs(static_cast<int>(ac ? unpremul_alpha(bc, ac) : 0) - (ao ? unpremul_alpha(bo, ao) : 0)) <= threshold; + return compare_guint32(ac ? unpremul_alpha(bc, ac) : 0, + ao ? unpremul_alpha(bo, ao) : 0, + threshold); case FLOOD_CHANNELS_RGB: - guint32 amc, rmc, bmc, gmc; - //amc = 255*255 - (255-ac)*(255-ad); amc = (amc + 127) / 255; - //amc = (255-ac)*ad + 255*ac; amc = (amc + 127) / 255; - amc = 255; // Why are we looking at desktop? Cairo version ignores destop alpha - rmc = (255-ac)*rd + 255*rc; rmc = (rmc + 127) / 255; - gmc = (255-ac)*gd + 255*gc; gmc = (gmc + 127) / 255; - bmc = (255-ac)*bd + 255*bc; bmc = (bmc + 127) / 255; - - diff += abs(static_cast<int>(amc ? unpremul_alpha(rmc, amc) : 0) - (amop ? unpremul_alpha(rmop, amop) : 0)); - diff += abs(static_cast<int>(amc ? unpremul_alpha(gmc, amc) : 0) - (amop ? unpremul_alpha(gmop, amop) : 0)); - diff += abs(static_cast<int>(amc ? unpremul_alpha(bmc, amc) : 0) - (amop ? unpremul_alpha(bmop, amop) : 0)); - return ((diff / 3) <= ((threshold * 3) / 4)); - + { + guint32 amc, rmc, bmc, gmc; + //amc = 255*255 - (255-ac)*(255-ad); amc = (amc + 127) / 255; + //amc = (255-ac)*ad + 255*ac; amc = (amc + 127) / 255; + amc = 255; // Why are we looking at desktop? Cairo version ignores destop alpha + rmc = (255-ac)*rd + 255*rc; rmc = (rmc + 127) / 255; + gmc = (255-ac)*gd + 255*gc; gmc = (gmc + 127) / 255; + bmc = (255-ac)*bd + 255*bc; bmc = (bmc + 127) / 255; + + int diff = 0; // The total difference between each of the 3 color components + diff += std::abs(static_cast<int>(amc ? unpremul_alpha(rmc, amc) : 0) - static_cast<int>(amop ? unpremul_alpha(rmop, amop) : 0)); + diff += std::abs(static_cast<int>(amc ? unpremul_alpha(gmc, amc) : 0) - static_cast<int>(amop ? unpremul_alpha(gmop, amop) : 0)); + diff += std::abs(static_cast<int>(amc ? unpremul_alpha(bmc, amc) : 0) - static_cast<int>(amop ? unpremul_alpha(bmop, amop) : 0)); + return ((diff / 3) <= ((threshold * 3) / 4)); + } case FLOOD_CHANNELS_H: return ((int)(fabs(hsl_check[0] - hsl_orig[0]) * 100.0) <= threshold); case FLOOD_CHANNELS_S: diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index a3e7b42f9..3ee4cd7d0 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -76,8 +76,10 @@ public: GSList *white_curves; GSList *white_anchors; - //ALternative curve to use on continuing exisiting curve in case of bspline or spirolive - //because usigh anchor curves give memory and random bugs, - and obscure code- in some plataform reported by su_v in mac + // Alternative curve to use on continuing the exisiting curve in case of + // bspline or spirolive, because using anchor curves gives random memory + // bugs as reported by su_v when running this code on macOS (as well as + // making the code hard to understand). SPCurve *overwrite_curve; // Start anchor diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index e628094d9..ac43b6c9d 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -1137,7 +1137,7 @@ static void sp_mesh_new_default(MeshTool &rc) { Inkscape::FOR_FILL : Inkscape::FOR_STROKE; // Ensure mesh is immediately editable. - // Editting both fill and stroke at same time doesn't work well so avoid. + // Editing both fill and stroke at same time doesn't work well so avoid. if (fill_or_stroke == Inkscape::FOR_FILL) { prefs->setBool("/tools/mesh/edit_fill", true ); prefs->setBool("/tools/mesh/edit_stroke", false); diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp index 6c450b3dc..bae1793ed 100644 --- a/src/ui/tools/select-tool.cpp +++ b/src/ui/tools/select-tool.cpp @@ -142,7 +142,7 @@ void SelectTool::setup() { this->_describer = new Inkscape::SelectionDescriber( desktop->selection, desktop->messageStack(), - _("Click selection to toggle scale/rotation handles"), + _("Click selection to toggle scale/rotation handles (or Shift+s)"), _("No objects selected. Click, Shift+click, Alt+scroll mouse on top of objects, or drag around objects to select.") ); diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp index 559187764..649bbb045 100644 --- a/src/ui/tools/text-tool.cpp +++ b/src/ui/tools/text-tool.cpp @@ -48,6 +48,8 @@ #include "ui/control-manager.h" #include "verbs.h" #include "xml/node-event-vector.h" +#include "xml/attribute-record.h" +#include "xml/sp-css-attr.h" using Inkscape::ControlManager; using Inkscape::DocumentUndo; @@ -1357,6 +1359,59 @@ SPCSSAttr *sp_text_get_style_at_cursor(ToolBase const *ec) return NULL; } +static bool css_attrs_are_equal(SPCSSAttr const *first, SPCSSAttr const *second) +{ + Inkscape::Util::List<Inkscape::XML::AttributeRecord const> attrs = first->attributeList(); + for ( ; attrs ; attrs++) { + gchar const *other_attr = second->attribute(g_quark_to_string(attrs->key)); + if (other_attr == NULL || strcmp(attrs->value, other_attr)) + return false; + } + attrs = second->attributeList(); + for ( ; attrs ; attrs++) { + gchar const *other_attr = first->attribute(g_quark_to_string(attrs->key)); + if (other_attr == NULL || strcmp(attrs->value, other_attr)) + return false; + } + return true; +} + +std::vector<SPCSSAttr*> sp_text_get_selected_style(ToolBase const *ec, unsigned *k, int *b, std::vector<unsigned> *positions) +{ + std::vector<SPCSSAttr*> vec; + SPCSSAttr *css, *css_new; + TextTool *tc = SP_TEXT_CONTEXT(ec); + Inkscape::Text::Layout::iterator i = std::min(tc->text_sel_start, tc->text_sel_end); + SPObject const *obj = sp_te_object_at_position(tc->text, i); + if (obj) { + css = take_style_from_item(const_cast<SPObject*>(obj)); + } + vec.push_back(css); + positions->push_back(0); + i.nextCharacter(); + *k = 1; + *b = 1; + while (i != std::max(tc->text_sel_start, tc->text_sel_end)) + { + obj = sp_te_object_at_position(tc->text, i); + if (obj) { + css_new = take_style_from_item(const_cast<SPObject*>(obj)); + } + if(!css_attrs_are_equal(css, css_new)) + { + vec.push_back(css_new); + css = sp_repr_css_attr_new(); + sp_repr_css_merge(css, css_new); + positions->push_back(*k); + (*b)++; + } + i.nextCharacter(); + (*k)++; + } + positions->push_back(*k); + return vec; +} + /** Deletes the currently selected characters. Returns false if there is no text selection currently. @@ -1442,7 +1497,6 @@ bool TextTool::_styleSet(SPCSSAttr const *css) _("Set text style")); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - return true; } diff --git a/src/ui/tools/text-tool.h b/src/ui/tools/text-tool.h index 289ee180d..f2e6fea1a 100644 --- a/src/ui/tools/text-tool.h +++ b/src/ui/tools/text-tool.h @@ -94,6 +94,7 @@ private: bool sp_text_paste_inline(ToolBase *ec); Glib::ustring sp_text_get_selected_text(ToolBase const *ec); SPCSSAttr *sp_text_get_style_at_cursor(ToolBase const *ec); +std::vector<SPCSSAttr*> sp_text_get_selected_style(ToolBase const *ec, unsigned *k, int *b, std::vector<unsigned> *positions); bool sp_text_delete_selection(ToolBase *ec); void sp_text_context_place_cursor (TextTool *tc, SPObject *text, Inkscape::Text::Layout::iterator where); void sp_text_context_place_cursor_at (TextTool *tc, SPObject *text, Geom::Point const p); diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index aab256712..8c7f54d14 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -497,7 +497,7 @@ bool ToolBase::root_handler(GdkEvent* event) { Geom::Point const motion_w(event->motion.x, event->motion.y); Geom::Point const moved_w(motion_w - button_w); - this->desktop->scroll_world(moved_w, true); // we're still scrolling, do not redraw + this->desktop->scroll_relative(moved_w, true); // we're still scrolling, do not redraw ret = TRUE; } } else if (zoom_rb) { @@ -575,7 +575,7 @@ bool ToolBase::root_handler(GdkEvent* event) { Geom::Point const motion_w(event->button.x, event->button.y); Geom::Point const moved_w(motion_w - button_w); - this->desktop->scroll_world(moved_w); + this->desktop->scroll_relative(moved_w); desktop->updateNow(); ret = TRUE; } else if (zoom_rb == event->button.button) { @@ -675,7 +675,7 @@ bool ToolBase::root_handler(GdkEvent* event) { acceleration, desktop->getCanvas())); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); - this->desktop->scroll_world(i, 0); + this->desktop->scroll_relative(Geom::Point(i, 0)); ret = TRUE; } break; @@ -688,7 +688,7 @@ bool ToolBase::root_handler(GdkEvent* event) { acceleration, desktop->getCanvas())); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); - this->desktop->scroll_world(0, i); + this->desktop->scroll_relative(Geom::Point(0, i)); ret = TRUE; } break; @@ -701,7 +701,7 @@ bool ToolBase::root_handler(GdkEvent* event) { acceleration, desktop->getCanvas())); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); - this->desktop->scroll_world(-i, 0); + this->desktop->scroll_relative(Geom::Point(-i, 0)); ret = TRUE; } break; @@ -714,7 +714,7 @@ bool ToolBase::root_handler(GdkEvent* event) { acceleration, desktop->getCanvas())); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); - this->desktop->scroll_world(0, -i); + this->desktop->scroll_relative(Geom::Point(0, -i)); ret = TRUE; } break; @@ -856,11 +856,11 @@ bool ToolBase::root_handler(GdkEvent* event) { if (event->scroll.state & GDK_SHIFT_MASK) { switch (event->scroll.direction) { case GDK_SCROLL_UP: - desktop->scroll_world(wheel_scroll, 0); + desktop->scroll_relative(Geom::Point(wheel_scroll, 0)); break; case GDK_SCROLL_DOWN: - desktop->scroll_world(-wheel_scroll, 0); + desktop->scroll_relative(Geom::Point(-wheel_scroll, 0)); break; default: @@ -896,24 +896,24 @@ bool ToolBase::root_handler(GdkEvent* event) { } else { switch (event->scroll.direction) { case GDK_SCROLL_UP: - desktop->scroll_world(0, wheel_scroll); + desktop->scroll_relative(Geom::Point(0, wheel_scroll)); break; case GDK_SCROLL_DOWN: - desktop->scroll_world(0, -wheel_scroll); + desktop->scroll_relative(Geom::Point(0, -wheel_scroll)); break; case GDK_SCROLL_LEFT: - desktop->scroll_world(wheel_scroll, 0); + desktop->scroll_relative(Geom::Point(wheel_scroll, 0)); break; case GDK_SCROLL_RIGHT: - desktop->scroll_world(-wheel_scroll, 0); + desktop->scroll_relative(Geom::Point(-wheel_scroll, 0)); break; case GDK_SCROLL_SMOOTH: gdk_event_get_scroll_deltas(event, &delta_x, &delta_y); - desktop->scroll_world(delta_x, delta_y); + desktop->scroll_relative(Geom::Point(delta_x, delta_y)); break; } } |
