From 6febb5a75ac5b7d8b41c4cf6c49799c094b98199 Mon Sep 17 00:00:00 2001 From: Jasper van de Gronde Date: Thu, 21 Mar 2013 12:15:43 +0100 Subject: Handle bitmap downsampling ourselves, see bug #804162 in launchpad. (bzr r12227) --- src/display/drawing-image.cpp | 124 ++++++++++++++++++++++++++++++++++++++---- src/display/drawing-image.h | 3 + 2 files changed, 115 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp index 0c8ac9681..185b62285 100644 --- a/src/display/drawing-image.cpp +++ b/src/display/drawing-image.cpp @@ -22,6 +22,7 @@ DrawingImage::DrawingImage(Drawing &drawing) : DrawingItem(drawing) , _pixbuf(NULL) , _surface(NULL) + , _new_surface(NULL) , _style(NULL) {} @@ -30,6 +31,7 @@ DrawingImage::~DrawingImage() if (_style) sp_style_unref(_style); if (_pixbuf) { + if (_new_surface) cairo_surface_destroy(_new_surface); cairo_surface_destroy(_surface); g_object_unref(_pixbuf); } @@ -118,26 +120,124 @@ unsigned DrawingImage::_renderItem(DrawingContext &ct, Geom::IntRect const &/*ar if (!outline) { if (!_pixbuf) return RENDER_OK; - + Inkscape::DrawingContext::Save save(ct); ct.transform(_ctm); ct.newPath(); ct.rectangle(_clipbox); ct.clip(); - ct.translate(_origin); - ct.scale(_scale); - ct.setSource(_surface, 0, 0); + ///////////////////////////////////////////////////////////////////////////// + // BEGIN: Hack to avoid Cairo bug + // The total transform (which is RIGHT-multiplied with the item points to get display points) equals: + // scale*translate_origin*_ctm = scale*translate(origin)*expansion*expansionInv*_ctm + // = scale*expansion*translate(origin*expansion)*expansionInv*_ctm + // To avoid a Cairo bug, we handle the scale*expansion part ourselves. + // See https://bugs.launchpad.net/inkscape/+bug/804162 + + Geom::Scale expansion(_ctm.expansion()); + int orgwidth = cairo_image_surface_get_width(_surface); + int orgheight = cairo_image_surface_get_height(_surface); + + if (_scale[Geom::X]*expansion[Geom::X]*orgwidth*255.0<1.0 || _scale[Geom::Y]*expansion[Geom::Y]*orgheight*255.0<1.0) { + // Resized image too small to actually see anything + return RENDER_OK; + } + + // Split scale*expansion in a part that is <= 1.0 and a part that is >= 1.0. We only take care of the part <= 1.0. + Geom::Scale scaleExpansionSmall(std::min(fabs(_scale[Geom::X]*expansion[Geom::X]),1),std::min(fabs(_scale[Geom::Y]*expansion[Geom::Y]),1)); + Geom::Scale scaleExpansionLarge(_scale[Geom::X]*expansion[Geom::X]/scaleExpansionSmall[Geom::X],_scale[Geom::Y]*expansion[Geom::Y]/scaleExpansionSmall[Geom::Y]); + + Geom::Point newSize(Geom::Point(orgwidth,orgheight)*scaleExpansionSmall); + if ((newSize-Geom::Point(orgwidth,orgheight)).length()<0.1) { + // Just use _surface directly. + ct.scale(expansion.inverse()); // This should not include scale (see derivation above) + ct.translate(_origin*expansion); + ct.scale(scaleExpansionLarge); + ct.setSource(_surface, 0, 0); + } else if (!_new_surface || (newSize-_rescaledSize).length()>0.1) { + // Rescaled image is sufficiently different from cached image to recompute + if (_new_surface) cairo_surface_destroy(_new_surface); + _rescaledSize = newSize; + + // This essentially considers an image to be composed of rectangular pixels and computes the least-squares approximation of the original. + // When the scale factor is really large or small this essentially results in using a box filter, while for scale factors approaching 1 it is more like a "tent" kernel. + int newwidth = static_cast(floor(orgwidth*scaleExpansionSmall[Geom::X])+1); + int newheight = static_cast(floor(orgheight*scaleExpansionSmall[Geom::Y])+1); + std::vector xBegin(newwidth, -1), yBegin(newheight, -1); + std::vector< std::vector > xCoefs(xBegin.size()), yCoefs(yBegin.size()); + for(int x=0; x(scaleExpansionSmall[Geom::X]); // x-coord in target coordinates where the current source pixel begins + double coordEnd = (x+1)*static_cast(scaleExpansionSmall[Geom::X]); // x-coord in target coordinates where the current source pixel ends + int begin = static_cast(floor(coordBegin)); // First pixel (x-coord) affected by the current source pixel + int end = static_cast(ceil(coordEnd)); // First pixel (x-coord) NOT affected by the current source pixel (a zero contribution is counted as not affecting the pixel) + for(int nx=begin; nx(std::min(nx+1,coordEnd) - std::max(nx,coordBegin))); + } + } + for(int y=0; y(scaleExpansionSmall[Geom::Y]); // y-coord in target coordinates where the current source pixel begins + double coordEnd = (y+1)*static_cast(scaleExpansionSmall[Geom::Y]); // y-coord in target coordinates where the current source pixel ends + int begin = static_cast(floor(coordBegin)); // First pixel (y-coord) affected by the current source pixel + int end = static_cast(ceil(coordEnd)); // First pixel (y-coord) NOT affected by the current source pixel (a zero contribution is counted as not affecting the pixel) + for(int ny=begin; ny(std::min(ny+1,coordEnd) - std::max(ny,coordBegin))); + } + } + + _new_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, newwidth,newheight); + unsigned char * orgdata = cairo_image_surface_get_data(_surface); + unsigned char * newdata = cairo_image_surface_get_data(_new_surface); + int orgstride = cairo_image_surface_get_stride(_surface); + int newstride = cairo_image_surface_get_stride(_new_surface); + + cairo_surface_flush(_surface); + cairo_surface_flush(_new_surface); + + for(int y=0; y(yCoefs[y].size()); oy++) { + for(int ox=0; ox(xCoefs[x].size()); ox++) { + for(int c=0; c<4; c++) { + tempSum[c] += xCoefs[x][ox]*yCoefs[y][oy]*orgdata[c+4*(xBegin[x]+ox)+orgstride*(yBegin[y]+oy)]; + } + } + } + for(int c=0; c<4; c++) { + newdata[c+4*x+newstride*y] = static_cast(tempSum[c]); + } + } + } + + cairo_surface_mark_dirty(_new_surface); + + ct.scale(expansion.inverse()); // This should not include scale (see derivation above) + ct.translate(_origin*expansion); + ct.scale(scaleExpansionLarge); + ct.setSource(_new_surface, 0, 0); + } else { + // No need to regenerate, but we do draw from _new_surface. + ct.scale(expansion.inverse()); // This should not include scale (see derivation above) + ct.translate(_origin*expansion); + ct.scale(scaleExpansionLarge); + ct.setSource(_new_surface, 0, 0); + } + + // END: Hack to avoid Cairo bug + ///////////////////////////////////////////////////////////////////////////// - cairo_matrix_t tt; - Geom::Affine total; - cairo_get_matrix(ct.raw(), &tt); - ink_matrix_to_2geom(total, tt); + // TODO: If Cairo's problems are gone, uncomment the following: + //ct.translate(_origin); + //ct.scale(_scale); + //ct.setSource(_surface, 0, 0); - if (total.expansionX() > 1.0 || total.expansionY() > 1.0) { - cairo_pattern_t *p = cairo_get_source(ct.raw()); - cairo_pattern_set_filter(p, CAIRO_FILTER_NEAREST); - } //ct.paint(_opacity); ct.paint(); diff --git a/src/display/drawing-image.h b/src/display/drawing-image.h index 306096d0e..593185c97 100644 --- a/src/display/drawing-image.h +++ b/src/display/drawing-image.h @@ -45,6 +45,9 @@ protected: cairo_surface_t *_surface; SPStyle *_style; + cairo_surface_t *_new_surface; // Part of hack around Cairo bug + Geom::Point _rescaledSize; // Part of hack around Cairo bug + // TODO: the following three should probably be merged into a new Geom::Viewbox object Geom::Rect _clipbox; ///< for preserveAspectRatio Geom::Point _origin; -- cgit v1.2.3 From 787604447932202d97e7e9d4fcd3bec5403417d9 Mon Sep 17 00:00:00 2001 From: Jasper van de Gronde Date: Thu, 21 Mar 2013 12:24:40 +0100 Subject: Clarified choice of downsampling routine. (bzr r12228) --- src/display/drawing-image.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp index 185b62285..2bfd71713 100644 --- a/src/display/drawing-image.cpp +++ b/src/display/drawing-image.cpp @@ -160,8 +160,10 @@ unsigned DrawingImage::_renderItem(DrawingContext &ct, Geom::IntRect const &/*ar if (_new_surface) cairo_surface_destroy(_new_surface); _rescaledSize = newSize; - // This essentially considers an image to be composed of rectangular pixels and computes the least-squares approximation of the original. + // This essentially considers an image to be composed of rectangular pixels (box kernel) and computes the least-squares approximation of the original. // When the scale factor is really large or small this essentially results in using a box filter, while for scale factors approaching 1 it is more like a "tent" kernel. + // Although the quality of the result is not great, it is typically better than an ordinary box filter, and it is guaranteed to preserve the overall brightness of the image. + // The best improvement would probably be to do the same kind of thing based on a tent kernel, but that's quite a bit more complicated, and probably not worth the trouble for a hack like this. int newwidth = static_cast(floor(orgwidth*scaleExpansionSmall[Geom::X])+1); int newheight = static_cast(floor(orgheight*scaleExpansionSmall[Geom::Y])+1); std::vector xBegin(newwidth, -1), yBegin(newheight, -1); -- cgit v1.2.3 From e3096f8a83b23a48faf938c0dece352169e6e7ca Mon Sep 17 00:00:00 2001 From: Raphael Rosch Date: Fri, 22 Mar 2013 16:57:02 -0400 Subject: ability to scroll inside the filter dock -- gain some screen real estate! Fixed bugs: - https://launchpad.net/bugs/1062134 (bzr r12229) --- src/ui/dialog/filter-effects-dialog.cpp | 103 +++++++++++++++++++++++++++----- src/ui/dialog/filter-effects-dialog.h | 3 +- 2 files changed, 89 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 5afc85f10..d65f5c48c 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -1149,7 +1149,9 @@ FilterEffectsDialog::FilterModifier::FilterModifier(FilterEffectsDialog& d) ((Gtk::CellRendererText*)_list.get_column(1)->get_first_cell())-> signal_edited().connect(sigc::mem_fun(*this, &FilterEffectsDialog::FilterModifier::on_name_edited)); - sw->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + sw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + _list.get_column(1)->set_resizable(true); + sw->set_shadow_type(Gtk::SHADOW_IN); show_all_children(); _add.signal_clicked().connect(sigc::mem_fun(*this, &FilterModifier::add_filter)); @@ -1554,6 +1556,7 @@ FilterEffectsDialog::PrimitiveList::PrimitiveList(FilterEffectsDialog& d) set_model(_model); append_column(_("_Effect"), _columns.type); + get_column(0)->set_resizable(true); set_headers_visible(); _observer->signal_changed().connect(signal_primitive_changed().make_slot()); @@ -1724,7 +1727,6 @@ bool FilterEffectsDialog::PrimitiveList::on_expose_signal(GdkEventExpose * /*evt bool FilterEffectsDialog::PrimitiveList::on_draw_signal(const Cairo::RefPtr & cr) { cr->set_line_width(1.0); - #if GTK_CHECK_VERSION(3,0,0) // In GTK+ 3, the draw function receives the widget window, not the // bin_window (i.e., just the area under the column headers). We @@ -1836,6 +1838,7 @@ bool FilterEffectsDialog::PrimitiveList::on_draw_signal(const Cairo::RefPtr con_poly; int con_drag_y = 0; + int con_drag_x = 0; bool inside; const SPFilterPrimitive* row_prim = (*row)[_columns.primitive]; const int inputs = input_count(row_prim); @@ -1863,16 +1866,22 @@ bool FilterEffectsDialog::PrimitiveList::on_draw_signal(const Cairo::RefPtrrestore(); if(_in_drag == (i + 1)) + { con_drag_y = con_poly[2].get_y(); + con_drag_x = con_poly[2].get_x(); + } if(_in_drag != (i + 1) || row_prim != prim) + { draw_connection(cr, row, i, text_start_x, outline_x, con_poly[2].get_y(), row_count); + } } } else { // Draw "in" shape inside = do_connection_node(row, 0, con_poly, mx, my); con_drag_y = con_poly[2].get_y(); + con_drag_x = con_poly[2].get_x(); cr->save(); @@ -1894,13 +1903,18 @@ bool FilterEffectsDialog::PrimitiveList::on_draw_signal(const Cairo::RefPtrsave(); @@ -1922,7 +1936,9 @@ bool FilterEffectsDialog::PrimitiveList::on_draw_signal(const Cairo::RefPtrsave(); cr->set_source_rgb(0.0, 0.0, 0.0); - cr->move_to(outline_x, con_drag_y); - cr->line_to(mx, con_drag_y); + cr->move_to(con_drag_x, con_drag_y); + cr->line_to(mx, con_drag_y); cr->line_to(mx, my); cr->stroke(); cr->restore(); @@ -2153,7 +2169,8 @@ bool FilterEffectsDialog::PrimitiveList::on_button_press_event(GdkEventButton* e if(_in_drag) { _scroll_connection = Glib::signal_timeout().connect(sigc::mem_fun(*this, &PrimitiveList::on_scroll_timeout), 150); - _autoscroll = 0; + _autoscroll_x = 0; + _autoscroll_y = 0; get_selection()->select(path); return true; } @@ -2169,22 +2186,43 @@ bool FilterEffectsDialog::PrimitiveList::on_motion_notify_event(GdkEventMotion* Gdk::Rectangle vis; get_visible_rect(vis); int vis_x, vis_y; + + int vis_x2, vis_y2; // NOTE: insaner added -- necessary to get the scrolling while dragging to work + convert_widget_to_tree_coords(vis.get_x(), vis.get_y(), vis_x2, vis_y2); + convert_tree_to_widget_coords(vis.get_x(), vis.get_y(), vis_x, vis_y); const int top = vis_y + vis.get_height(); + const int right_edge = vis_x + vis.get_width(); // When autoscrolling during a connection drag, set the speed based on // where the mouse is in relation to the edges. if(e->y < vis_y) - _autoscroll = -(int)(speed + (vis_y - e->y) / 5); + _autoscroll_y = -(int)(speed + (vis_y - e->y) / 5); else if(e->y < vis_y + limit) - _autoscroll = -speed; + _autoscroll_y = -speed; else if(e->y > top) - _autoscroll = (int)(speed + (e->y - top) / 5); + _autoscroll_y = (int)(speed + (e->y - top) / 5); else if(e->y > top - limit) - _autoscroll = speed; + _autoscroll_y = speed; else - _autoscroll = 0; - + _autoscroll_y = 0; + + // NOTE: insaner added -- necessary to get the scrolling while dragging to work + double e2 = ( e->x - vis_x2/2); + // horizontal scrolling + if(e2 < vis_x) + _autoscroll_x = -(int)(speed + (vis_x - e2) / 5); + else if(e2 < vis_x + limit) + _autoscroll_x = -speed; + else if(e2 > right_edge) + _autoscroll_x = (int)(speed + (e2 - right_edge) / 5); + else if(e2 > right_edge - limit) + _autoscroll_x = speed; + else + _autoscroll_x = 0; + + + queue_draw(); return Gtk::TreeView::on_motion_notify_event(e); @@ -2379,10 +2417,10 @@ void FilterEffectsDialog::PrimitiveList::on_drag_end(const Glib::RefPtr a = dynamic_cast(get_parent())->get_vadjustment(); - double v = a->get_value() + _autoscroll; + double v = a->get_value() + _autoscroll_y; if(v < 0) v = 0; @@ -2392,7 +2430,7 @@ bool FilterEffectsDialog::PrimitiveList::on_scroll_timeout() a->set_value(v); #else Gtk::Adjustment& a = *dynamic_cast(get_parent())->get_vadjustment(); - double v = a.get_value() + _autoscroll; + double v = a.get_value() + _autoscroll_y; if(v < 0) v = 0; @@ -2405,6 +2443,34 @@ bool FilterEffectsDialog::PrimitiveList::on_scroll_timeout() queue_draw(); } + + if(_autoscroll_x) { +#if WITH_GTKMM_3_0 + Glib::RefPtr a_h = dynamic_cast(get_parent())->get_hadjustment(); + double h = a_h->get_value() + _autoscroll_x; + + if(h < 0) + h = 0; + if(h > a_h->get_upper() - a_h->get_page_size()) + h = a_h->get_upper() - a_h->get_page_size(); + + a_h->set_value(h); +#else + Gtk::Adjustment& a_h = *dynamic_cast(get_parent())->get_hadjustment(); + double h = a_h.get_value() + _autoscroll_x; + + if(h < 0) + h = 0; + if(h > a_h.get_upper() - a_h.get_page_size()) + h = a_h.get_upper() - a_h.get_page_size(); + + a_h.set_value(h); + +#endif + + queue_draw(); + } + return true; } @@ -2452,6 +2518,7 @@ FilterEffectsDialog::FilterEffectsDialog() #endif Gtk::ScrolledWindow* sw_prims = Gtk::manage(new Gtk::ScrolledWindow); + Gtk::ScrolledWindow* sw_infobox = Gtk::manage(new Gtk::ScrolledWindow); Gtk::HBox* infobox = Gtk::manage(new Gtk::HBox(/*homogeneous:*/false, /*spacing:*/4)); Gtk::HBox* hb_prims = Gtk::manage(new Gtk::HBox); @@ -2460,13 +2527,15 @@ FilterEffectsDialog::FilterEffectsDialog() hpaned->pack2(_primitive_box); _primitive_box.pack_start(*sw_prims); _primitive_box.pack_start(*hb_prims, false, false); - _primitive_box.pack_start(*infobox,false, false); + _primitive_box.pack_start(*sw_infobox, false, false); sw_prims->add(_primitive_list); + sw_infobox->add(*infobox); infobox->pack_start(_infobox_icon, false, false); infobox->pack_start(_infobox_desc, false, false); _infobox_desc.set_line_wrap(true); _infobox_desc.set_size_request(200, -1); + hb_prims->pack_start(_add_primitive, false, false); hb_prims->pack_start(_add_primitive_type, false, false); _getContents()->pack_start(_settings_tabs, false, false); @@ -2481,8 +2550,10 @@ FilterEffectsDialog::FilterEffectsDialog() _add_primitive_type.signal_changed().connect( sigc::mem_fun(*this, &FilterEffectsDialog::update_primitive_infobox)); - sw_prims->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + sw_prims->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); /* NOTE: insaner -- SCROLL the connections panel thing!!! */ sw_prims->set_shadow_type(Gtk::SHADOW_IN); + sw_infobox->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_NEVER); + // al_settings->set_padding(0, 0, 12, 0); // fr_settings->set_shadow_type(Gtk::SHADOW_NONE); // ((Gtk::Label*)fr_settings->get_label_widget())->set_use_markup(); diff --git a/src/ui/dialog/filter-effects-dialog.h b/src/ui/dialog/filter-effects-dialog.h index 355a8b1b2..658aac790 100644 --- a/src/ui/dialog/filter-effects-dialog.h +++ b/src/ui/dialog/filter-effects-dialog.h @@ -236,7 +236,8 @@ private: SPFilterPrimitive* _drag_prim; sigc::signal _signal_primitive_changed; sigc::connection _scroll_connection; - int _autoscroll; + int _autoscroll_y; + int _autoscroll_x; std::auto_ptr _observer; int _input_type_width; int _input_type_height; -- cgit v1.2.3 From 5950073a4ce60212f2990d0faf053fb78ec1fb9c Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Fri, 22 Mar 2013 21:48:03 +0100 Subject: Translations. Translatable files clean-up (find.cpp removal). Translations. Inkscape.pot update. Preferences. Filters preferences text fix (see Bug #1133033). Extensions. Fix for Bug #1158377 (Printing marks needs more precision). (bzr r12230) --- src/ui/dialog/inkscape-preferences.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index fb814e066..34a908995 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -598,7 +598,7 @@ void InkscapePreferences::initPageUI() _("When on, will allow dynamic layout of components that are not completely finished being refactored"), true); /* show infobox */ - _show_filters_info_box.init( _("Show filter primitives infobox"), "/options/showfiltersinfobox/value", true); + _show_filters_info_box.init( _("Show filter primitives infobox (requires restart)"), "/options/showfiltersinfobox/value", true); _page_ui.add_line(false, "", _show_filters_info_box, "", _("Show icons and descriptions for the filter primitives available at the filter effects dialog")); -- cgit v1.2.3 From 08a6910ae3366ca64e9da171c3e016bf93ac34b6 Mon Sep 17 00:00:00 2001 From: Raphael Rosch Date: Fri, 22 Mar 2013 17:01:41 -0400 Subject: pick a better filter editor icon Fixed bugs: - https://launchpad.net/bugs/1092313 (bzr r12231) --- 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 f8bfbab40..b8e72bc9b 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -2793,7 +2793,7 @@ Verb *Verb::_base_verbs[] = { new DialogVerb(SP_VERB_DIALOG_LIVE_PATH_EFFECT, "DialogLivePathEffect", N_("Path E_ffects ..."), N_("Manage, edit, and apply path effects"), NULL), new DialogVerb(SP_VERB_DIALOG_FILTER_EFFECTS, "DialogFilterEffects", N_("Filter _Editor..."), - N_("Manage, edit, and apply SVG filters"), NULL), + N_("Manage, edit, and apply SVG filters"), INKSCAPE_ICON("dialog-filters")), new DialogVerb(SP_VERB_DIALOG_SVG_FONTS, "DialogSVGFonts", N_("SVG Font Editor..."), N_("Edit SVG fonts"), NULL), new DialogVerb(SP_VERB_DIALOG_PRINT_COLORS_PREVIEW, "DialogPrintColorsPreview", N_("Print Colors..."), -- cgit v1.2.3 From cc6fe77184f30e426d307fb5472d13fc16b25788 Mon Sep 17 00:00:00 2001 From: Raphael Rosch Date: Fri, 22 Mar 2013 17:06:44 -0400 Subject: filter name is random filter232 when first added Fixed bugs: - https://launchpad.net/bugs/1089406 (bzr r12232) --- src/extension/internal/filter/filter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/extension/internal/filter/filter.cpp b/src/extension/internal/filter/filter.cpp index 9f7a45f7f..a2c565699 100644 --- a/src/extension/internal/filter/filter.cpp +++ b/src/extension/internal/filter/filter.cpp @@ -144,11 +144,11 @@ void Filter::effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::Vie if (filter == NULL) { Inkscape::XML::Node * newfilterroot = xmldoc->createElement("svg:filter"); + merge_filters(newfilterroot, filterdoc->root(), xmldoc); defsrepr->appendChild(newfilterroot); Glib::ustring url = "url(#"; url += newfilterroot->attribute("id"); url += ")"; - merge_filters(newfilterroot, filterdoc->root(), xmldoc); Inkscape::GC::release(newfilterroot); -- cgit v1.2.3 From 4ce710c02e31930664f81c1137e6b24e7297703a Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Mar 2013 13:15:49 +0000 Subject: Use subclass of RadioButton rather than setting gobject data in Stroke Style dialog: fixes cast-align issue. (bzr r12233) --- src/widgets/stroke-style.cpp | 134 +++++++++++++++++++++++++------------------ src/widgets/stroke-style.h | 51 ++++++++++++---- 2 files changed, 120 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 0f79a609b..c6934f0a6 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -87,6 +87,33 @@ SPObject* getMarkerObj(gchar const *n, SPDocument *doc) namespace Inkscape { + +/** + * Construct a stroke-style radio button with a given icon + * + * \param[in] grp The Gtk::RadioButtonGroup to which to add the new button + * \param[in] icon The icon to use for the button + * \param[in] button_type The type of stroke-style radio button (join/cap) + * \param[in] stroke_style The style attribute to associate with the button + */ +StrokeStyle::StrokeStyleButton::StrokeStyleButton(Gtk::RadioButtonGroup &grp, + char const *icon, + StrokeStyleButtonType button_type, + gchar const *stroke_style) + : + Gtk::RadioButton(grp), + button_type(button_type), + stroke_style(stroke_style) +{ + show(); + set_mode(false); + + Gtk::Widget *px = manage(Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_LARGE_TOOLBAR, icon))); + g_assert(px != NULL); + px->show(); + add(*px); +} + /** * Create the fill or stroke style widget, and hook up all the signals. */ @@ -194,24 +221,27 @@ StrokeStyle::StrokeStyle() : hb = spw_hbox(table, 3, 1, i); - //tb = NULL; + Gtk::RadioButtonGroup joinGrp; + + joinMiter = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-miter"), + hb, STROKE_STYLE_BUTTON_JOIN, "miter"); - joinMiter = makeRadioButton(NULL, INKSCAPE_ICON("stroke-join-miter"), - hb, "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(joinMiter, INKSCAPE_ICON("stroke-join-round"), - hb, "join", "round"); + joinRound = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-round"), + hb, STROKE_STYLE_BUTTON_JOIN, "round"); + // TRANSLATORS: Round join: joining lines with a rounded corner. // For an example, draw a triangle with a large stroke width and modify the // "Join" option (in the Fill and Stroke dialog). joinRound->set_tooltip_text(_("Round join")); - joinBevel = makeRadioButton(joinMiter, INKSCAPE_ICON("stroke-join-bevel"), - hb, "join", "bevel"); + joinBevel = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-bevel"), + hb, STROKE_STYLE_BUTTON_JOIN, "bevel"); + // TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. // For an example, draw a triangle with a large stroke width and modify the // "Join" option (in the Fill and Stroke dialog). @@ -260,20 +290,25 @@ StrokeStyle::StrokeStyle() : hb = spw_hbox(table, 3, 1, i); - capButt = makeRadioButton(capButt, INKSCAPE_ICON("stroke-cap-butt"), - hb, "cap", "butt"); + Gtk::RadioButtonGroup capGrp; + + capButt = makeRadioButton(capGrp, INKSCAPE_ICON("stroke-cap-butt"), + hb, STROKE_STYLE_BUTTON_CAP, "butt"); + // TRANSLATORS: Butt cap: the line shape does not extend beyond the end point // of the line; the ends of the line are square capButt->set_tooltip_text(_("Butt cap")); - capRound = makeRadioButton(capButt, INKSCAPE_ICON("stroke-cap-round"), - hb, "cap", "round"); + capRound = makeRadioButton(capGrp, INKSCAPE_ICON("stroke-cap-round"), + hb, STROKE_STYLE_BUTTON_CAP, "round"); + // TRANSLATORS: Round cap: the line shape extends beyond the end point of the // line; the ends of the line are rounded capRound->set_tooltip_text(_("Round cap")); - capSquare = makeRadioButton(capButt, INKSCAPE_ICON("stroke-cap-square"), - hb, "cap", "square"); + capSquare = makeRadioButton(capGrp, INKSCAPE_ICON("stroke-cap-square"), + hb, STROKE_STYLE_BUTTON_CAP, "square"); + // TRANSLATORS: Square cap: the line shape extends beyond the end point of the // line; the ends of the line are square capSquare->set_tooltip_text(_("Square cap")); @@ -394,39 +429,36 @@ void StrokeStyle::setDesktop(SPDesktop *desktop) /** - * Helper function for creating radio buttons. This should probably be re-thought out - * when reimplementing this with Gtkmm. + * Helper function for creating stroke-style radio buttons. + * + * \param[in] grp The Gtk::RadioButtonGroup in which to add the button + * \param[in] icon The icon for the button + * \param[in] hb The Gtk::Box container in which to add the button + * \param[in] button_type The type (join/cap) for the button + * \param[in] stroke_style The style attribute to associate with the button + * + * \details After instantiating the button, it is added to a container box and + * a handler for the toggle event is connected. */ -Gtk::RadioButton * -StrokeStyle::makeRadioButton(Gtk::RadioButton *tb, char const *icon, - Gtk::HBox *hb, gchar const *key, gchar const *data) +StrokeStyle::StrokeStyleButton * +StrokeStyle::makeRadioButton(Gtk::RadioButtonGroup &grp, + char const *icon, + Gtk::HBox *hb, + StrokeStyleButtonType button_type, + gchar const *stroke_style) { g_assert(icon != NULL); g_assert(hb != NULL); - if (tb == NULL) { - tb = new Gtk::RadioButton(); - } else { - Gtk::RadioButtonGroup grp = tb->get_group(); - tb = new Gtk::RadioButton(grp); - } + StrokeStyleButton *tb = new StrokeStyleButton(grp, icon, button_type, stroke_style); - tb->show(); - tb->set_mode(false); hb->pack_start(*tb, false, false, 0); set_data(icon, tb); - tb->set_data(key, (gpointer*)data); - tb->signal_toggled().connect(sigc::bind( + tb->signal_toggled().connect(sigc::bind( sigc::ptr_fun(&StrokeStyle::buttonToggledCB), tb, this)); - Gtk::Widget *px = manage(Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_LARGE_TOOLBAR, icon))); - g_assert(px != NULL); - px->show(); - tb->add(*px); - return tb; - } /** @@ -1120,38 +1152,30 @@ StrokeStyle::lineDashChangedCB() * calls the respective routines to update css properties, etc. * */ -void StrokeStyle::buttonToggledCB(Gtk::ToggleButton *tb, StrokeStyle *spw) +void StrokeStyle::buttonToggledCB(StrokeStyleButton *tb, StrokeStyle *spw) { if (spw->update) { return; } if (tb->get_active()) { - - gchar const *join - = static_cast(tb->get_data("join")); - gchar const *cap - = static_cast(tb->get_data("cap")); - - if (join) { - spw->miterLimitSpin->set_sensitive(!strcmp(join, "miter")); + if (tb->get_button_type() == STROKE_STYLE_BUTTON_JOIN) { + spw->miterLimitSpin->set_sensitive(!strcmp(tb->get_stroke_style(), "miter")); } /* TODO: Create some standardized method */ SPCSSAttr *css = sp_repr_css_attr_new(); - if (join) { - sp_repr_css_set_property(css, "stroke-linejoin", join); - - sp_desktop_set_style (spw->desktop, css); - - spw->setJoinButtons(tb); - } else if (cap) { - sp_repr_css_set_property(css, "stroke-linecap", cap); - - sp_desktop_set_style (spw->desktop, css); - - spw->setCapButtons(tb); + switch (tb->get_button_type()) { + case STROKE_STYLE_BUTTON_JOIN: + sp_repr_css_set_property(css, "stroke-linejoin", tb->get_stroke_style()); + sp_desktop_set_style (spw->desktop, css); + spw->setJoinButtons(tb); + break; + case STROKE_STYLE_BUTTON_CAP: + sp_repr_css_set_property(css, "stroke-linecap", tb->get_stroke_style()); + sp_desktop_set_style (spw->desktop, css); + spw->setCapButtons(tb); } sp_repr_css_attr_unref(css); diff --git a/src/widgets/stroke-style.h b/src/widgets/stroke-style.h index 5f05b97d1..fd9940db1 100644 --- a/src/widgets/stroke-style.h +++ b/src/widgets/stroke-style.h @@ -104,6 +104,7 @@ void sp_stroke_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop) SPObject *getMarkerObj(gchar const *n, SPDocument *doc); namespace Inkscape { +class StrokeStyleButton; class StrokeStyle : public Gtk::VBox { @@ -113,7 +114,33 @@ public: void setDesktop(SPDesktop *desktop); 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 + }; + + /** + * A custom radio-button for setting the stroke style. It can be configured + * to set either the join or cap style by setting the button_type field. + */ + class StrokeStyleButton : public Gtk::RadioButton { + public: + StrokeStyleButton(Gtk::RadioButtonGroup &grp, + char const *icon, + StrokeStyleButtonType button_type, + gchar const *stroke_style); + + /** Get the type (line/cap) of the stroke-style button */ + inline StrokeStyleButtonType get_button_type() {return button_type;} + + /** Get the stroke style attribute associated with the button */ + inline gchar const * get_stroke_style() {return stroke_style;} + + private: + StrokeStyleButtonType button_type; ///< The type (line/cap) of the button + gchar const *stroke_style; ///< The stroke style associated with the button + }; void updateLine(); void updateAllMarkers(GSList const *objects); @@ -129,8 +156,12 @@ private: SPObject *forkMarker(SPObject *marker, int loc, SPItem *item); const char *getItemColorForMarker(SPItem *item, Inkscape::PaintTarget fill_or_stroke, int loc); - Gtk::RadioButton * makeRadioButton(Gtk::RadioButton *tb, char const *icon, - Gtk::HBox *hb, gchar const *key, gchar const *data); + StrokeStyleButton * makeRadioButton(Gtk::RadioButtonGroup &grp, + char const *icon, + Gtk::HBox *hb, + StrokeStyleButtonType button_type, + gchar const *stroke_style); + static gboolean setStrokeWidthUnit(SPUnitSelector *, SPUnit const *old, SPUnit const *new_units, @@ -143,7 +174,7 @@ private: void miterLimitChangedCB(); void lineDashChangedCB(); static void markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMarkerLoc const which); - static void buttonToggledCB(Gtk::ToggleButton *tb, StrokeStyle *spw); + static void buttonToggledCB(StrokeStyleButton *tb, StrokeStyle *spw); MarkerComboBox *startMarkerCombo; @@ -161,12 +192,12 @@ private: Inkscape::UI::Widget::SpinButton *miterLimitSpin; Inkscape::UI::Widget::SpinButton *widthSpin; GtkWidget *unitSelector; - Gtk::RadioButton *joinMiter; - Gtk::RadioButton *joinRound; - Gtk::RadioButton *joinBevel; - Gtk::RadioButton *capButt; - Gtk::RadioButton *capRound; - Gtk::RadioButton *capSquare; + StrokeStyleButton *joinMiter; + StrokeStyleButton *joinRound; + StrokeStyleButton *joinBevel; + StrokeStyleButton *capButt; + StrokeStyleButton *capRound; + StrokeStyleButton *capSquare; SPDashSelector *dashSelector; gboolean update; -- cgit v1.2.3 From b933e932d2ddfacf2d91b2f44fbffcff93aa2490 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Mar 2013 13:36:44 +0000 Subject: Hide remaining non-critical GDL warnings. These will stop being our problem after Gtk+ 3 migration (bzr r12234) --- src/libgdl/Makefile_insert | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libgdl/Makefile_insert b/src/libgdl/Makefile_insert index 6669a28fa..e4cab95fc 100644 --- a/src/libgdl/Makefile_insert +++ b/src/libgdl/Makefile_insert @@ -49,9 +49,9 @@ libgdl/clean: # of changes we make to GDL than to fix these minor issues in trunk. if CC_WNO_UNUSED_BUT_SET_VARIABLE_SUPPORTED -libgdl_libgdl_a_CFLAGS = -Wno-unused-parameter -Wno-sign-compare -Wno-unused-variable -Wno-unused-but-set-variable $(AM_CFLAGS) +libgdl_libgdl_a_CFLAGS = -Wno-unused-parameter -Wno-sign-compare -Wno-unused-variable -Wno-unused-but-set-variable -Wno-missing-field-initializers $(AM_CFLAGS) else -libgdl_libgdl_a_CFLAGS = -Wno-unused-parameter -Wno-sign-compare -Wno-unused-variable $(AM_CFLAGS) +libgdl_libgdl_a_CFLAGS = -Wno-unused-parameter -Wno-sign-compare -Wno-unused-variable -Wno-missing-field-initializers $(AM_CFLAGS) endif libgdl_libgdl_a_SOURCES = \ -- cgit v1.2.3 From 4dfa1ac03459ef68f137de21c6840382f60c0e77 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Mar 2013 14:05:04 +0000 Subject: Fix more clang warnings (bzr r12235) --- src/display/cairo-templates.h | 12 ++++++------ src/display/drawing-image.cpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/display/cairo-templates.h b/src/display/cairo-templates.h index 45b6790e6..57ec98f81 100644 --- a/src/display/cairo-templates.h +++ b/src/display/cairo-templates.h @@ -66,9 +66,9 @@ void ink_cairo_surface_blend(cairo_surface_t *in1, cairo_surface_t *in2, cairo_s int limit = w * h; - guint32 *const in1_data = (guint32*) cairo_image_surface_get_data(in1); - guint32 *const in2_data = (guint32*) cairo_image_surface_get_data(in2); - guint32 *const out_data = (guint32*) cairo_image_surface_get_data(out); + guint32 *const in1_data = reinterpret_cast(cairo_image_surface_get_data(in1)); + guint32 *const in2_data = reinterpret_cast(cairo_image_surface_get_data(in2)); + guint32 *const out_data = reinterpret_cast(cairo_image_surface_get_data(out)); // NOTE // OpenMP probably doesn't help much here. @@ -199,8 +199,8 @@ void ink_cairo_surface_filter(cairo_surface_t *in, cairo_surface_t *out, Filter fast_path &= (stridein == w * bppin); fast_path &= (strideout == w * bppout); - guint32 *const in_data = (guint32*) cairo_image_surface_get_data(in); - guint32 *const out_data = (guint32*) cairo_image_surface_get_data(out); + guint32 *const in_data = reinterpret_cast(cairo_image_surface_get_data(in)); + guint32 *const out_data = reinterpret_cast(cairo_image_surface_get_data(out)); #if HAVE_OPENMP Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -695,4 +695,4 @@ pxclamp(gint32 v, gint32 low, gint32 high) { fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp index 2bfd71713..3f1a86ee7 100644 --- a/src/display/drawing-image.cpp +++ b/src/display/drawing-image.cpp @@ -22,8 +22,8 @@ DrawingImage::DrawingImage(Drawing &drawing) : DrawingItem(drawing) , _pixbuf(NULL) , _surface(NULL) - , _new_surface(NULL) , _style(NULL) + , _new_surface(NULL) {} DrawingImage::~DrawingImage() -- cgit v1.2.3 From baf2d5e96d2455281d4c65ea6331322ce99a2de4 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Mar 2013 16:41:52 +0000 Subject: Convert a couple of C-style pointer casts (bzr r12237) --- src/extension/internal/cairo-render-context.cpp | 2 +- src/extension/internal/image-resolution.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index b6a58c526..cf6730650 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -708,7 +708,7 @@ CairoRenderContext::popLayer(void) for (int row = 0 ; row < height; row++) { unsigned char *row_data = pixels + (row * stride); for (int i = 0 ; i < width; i++) { - guint32 *pixel = (guint32 *)row_data + i; + guint32 *pixel = reinterpret_cast(row_data) + i; float lum_alpha = (((*pixel & 0x00ff0000) >> 16) * coeff_r + ((*pixel & 0x0000ff00) >> 8) * coeff_g + ((*pixel & 0x000000ff) ) * coeff_b ); diff --git a/src/extension/internal/image-resolution.cpp b/src/extension/internal/image-resolution.cpp index 3b3b85d06..51a3fe9c1 100644 --- a/src/extension/internal/image-resolution.cpp +++ b/src/extension/internal/image-resolution.cpp @@ -159,10 +159,10 @@ static double exifDouble(ExifEntry *entry, ExifByteOrder byte_order) { return double(r.numerator) / double(r.denominator); } case EXIF_FORMAT_FLOAT: { - return double(((float *)entry->data)[0]); + return double((reinterpret_cast(entry->data))[0]); } case EXIF_FORMAT_DOUBLE: { - return ((double *)entry->data)[0]; + return (reinterpret_cast(entry->data))[0]; } default: { return nan(0); -- cgit v1.2.3