From 73317394a0079e3602e6c596f8d2a249d5b4a114 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Mon, 20 Jan 2014 19:06:46 +0100 Subject: Fix for bug #1270287 (The toolbox buttons toggle between being pressed and released). Fixed bugs: - https://launchpad.net/bugs/1270287 (bzr r12961) --- src/desktop.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/desktop.cpp b/src/desktop.cpp index bf3b70d43..364b5e930 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -668,6 +668,7 @@ void SPDesktop::set_event_context2(const std::string& toolName) old_tool->finish(); delete old_tool; } else { + _event_context_changed_signal.emit(this, event_context); return; } } -- cgit v1.2.3 From 1534dc84087db1b26f1e86e79436eb63f3dffd3f Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Mon, 20 Jan 2014 20:56:38 +0100 Subject: cppcheck stuff (bzr r12963) --- src/line-geometry.cpp | 16 +++++++++------- src/ui/dialog/template-load-tab.cpp | 7 ++----- src/ui/tools/text-tool.cpp | 4 ++-- src/widgets/icon.cpp | 4 ++-- 4 files changed, 15 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/line-geometry.cpp b/src/line-geometry.cpp index e9f07f96f..982762a12 100644 --- a/src/line-geometry.cpp +++ b/src/line-geometry.cpp @@ -28,8 +28,9 @@ namespace Box3D { * of the segment. Otherwise interpret it as the direction of the line. * FIXME: Think of a better way to distinguish between the two constructors of lines. */ -Line::Line(Geom::Point const &start, Geom::Point const &vec, bool is_endpoint) { - pt = start; +Line::Line(Geom::Point const &start, Geom::Point const &vec, bool is_endpoint): + pt(start) +{ if (is_endpoint) v_dir = vec - start; else @@ -38,11 +39,12 @@ Line::Line(Geom::Point const &start, Geom::Point const &vec, bool is_endpoint) { d0 = Geom::dot(normal, pt); } -Line::Line(Line const &line) { - pt = line.pt; - v_dir = line.v_dir; - normal = line.normal; - d0 = line.d0; +Line::Line(Line const &line): + pt(line.pt), + v_dir(line.v_dir), + normal(line.normal), + d0(line.d0) +{ } Line &Line::operator=(Line const &line) { diff --git a/src/ui/dialog/template-load-tab.cpp b/src/ui/dialog/template-load-tab.cpp index 4f2d51ef7..6b1f4542f 100644 --- a/src/ui/dialog/template-load-tab.cpp +++ b/src/ui/dialog/template-load-tab.cpp @@ -220,12 +220,9 @@ TemplateLoadTab::TemplateData TemplateLoadTab::_processTemplateFile(const std::s n = result.display_name.rfind(".svg"); result.display_name.replace(n, 4, 1, ' '); - Inkscape::XML::Document *rdoc; - rdoc = sp_repr_read_file(path.data(), SP_SVG_NS_URI); - Inkscape::XML::Node *myRoot; - + Inkscape::XML::Document *rdoc = sp_repr_read_file(path.data(), SP_SVG_NS_URI); if (rdoc){ - myRoot = rdoc->root(); + Inkscape::XML::Node *myRoot = rdoc->root(); if (strcmp(myRoot->name(), "svg:svg") != 0){ // Wrong file format return result; } diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp index c73164c09..9b5ab1016 100644 --- a/src/ui/tools/text-tool.cpp +++ b/src/ui/tools/text-tool.cpp @@ -1335,7 +1335,7 @@ bool sp_text_paste_inline(ToolBase *ec) paste_string_uchar == 0x00000009 || paste_string_uchar == 0x0000000A || paste_string_uchar == 0x0000000D) { - itr++; + ++itr; } else { itr = text.erase(itr); } @@ -1637,7 +1637,7 @@ static void sp_text_context_update_text_selection(TextTool *tc) // the selection update (can't do both atomically, alas) if (!tc->desktop) return; - for (std::vector::iterator it = tc->text_selection_quads.begin() ; it != tc->text_selection_quads.end() ; it++) { + for (std::vector::iterator it = tc->text_selection_quads.begin() ; it != tc->text_selection_quads.end() ; ++it) { sp_canvas_item_hide(*it); sp_canvas_item_destroy(*it); } diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index 768a835c9..a9c30ee8f 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -1310,11 +1310,11 @@ guchar *IconImpl::load_svg_pixels(std::list const &names, } static void addToIconSet(GdkPixbuf* pb, gchar const* name, GtkIconSize lsize, unsigned psize) { - static bool dump = Inkscape::Preferences::get()->getBool("/debug/icons/dumpGtk"); Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); bool icon_found = icon_theme->has_icon(name); if ( !icon_found ) { Gtk::IconTheme::add_builtin_icon( name, psize, Glib::wrap(pb) ); + static bool dump = Inkscape::Preferences::get()->getBool("/debug/icons/dumpGtk"); if (dump) { g_message(" set in a builtin for %s:%d:%d", name, lsize, psize); } @@ -1354,7 +1354,6 @@ static std::string getDestDir( unsigned psize ) bool IconImpl::prerenderIcon(gchar const *name, GtkIconSize lsize, unsigned psize) { bool loadNeeded = false; - static bool dump = Inkscape::Preferences::get()->getBool("/debug/icons/dumpGtk"); static bool useCache = Inkscape::Preferences::get()->getBool("/debug/icons/useCache", true); static bool cacheValidated = false; if (!cacheValidated) { @@ -1366,6 +1365,7 @@ bool IconImpl::prerenderIcon(gchar const *name, GtkIconSize lsize, unsigned psiz Glib::ustring key = icon_cache_key(name, psize); if ( !get_cached_pixbuf(key) ) { + static bool dump = Inkscape::Preferences::get()->getBool("/debug/icons/dumpGtk"); if ((internalNames.find(name) != internalNames.end()) || (!gtk_icon_theme_has_icon(gtk_icon_theme_get_default(), name))) { if (dump) { -- cgit v1.2.3 From 0e330f5f1fc975666d7a934e3d2efe594ac0b876 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Mon, 20 Jan 2014 17:06:21 -0500 Subject: 1. make scaling of stroke of horizontal line the same as nearly horizontal line. 2. remove vertical offset when using Transform dialog to attempt to vertically scale horizontal line. (bzr r12964) --- src/sp-item-transform.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/sp-item-transform.cpp b/src/sp-item-transform.cpp index 854fb9cd7..7fa591fee 100644 --- a/src/sp-item-transform.cpp +++ b/src/sp-item-transform.cpp @@ -144,13 +144,11 @@ Geom::Affine get_scale_transform_for_uniform_stroke(Geom::Rect const &bbox_visua gdouble r1 = r0; if ((fabs(w0 - stroke_x) < 1e-6) || w1 == 0) { // We have a vertical line at hand - r1 = transform_stroke ? r0 * sqrt(h1/h0) : r0; - scale_x = 1; - scale_y = preserve ? h1/h0 : (h1 - r1)/(h0 - r0); + scale_y = h1/h0; + scale_x = transform_stroke ? 1 : scale_y; } else if ((fabs(h0 - stroke_y) < 1e-6) || h1 == 0) { // We have a horizontal line at hand - r1 = transform_stroke ? r0 * sqrt(w1/w0) : r0; - scale_x = preserve ? w1/w0 : (w1 - r1)/(w0 - r0); - scale_y = 1; + scale_x = w1/w0; + scale_y = transform_stroke ? 1 : scale_x; } else { // We have a true 2D object at hand if (transform_stroke && !preserve) { /* Initial area of the geometric bounding box: A0 = (w0-r0)*(h0-r0) @@ -297,13 +295,13 @@ Geom::Affine get_scale_transform_for_variable_stroke(Geom::Rect const &bbox_visu gdouble r1w = r0w; if ((fabs(w0 - r0w) < 1e-6) || w1 == 0) { // We have a vertical line at hand - r1h = transform_stroke ? r0h * sqrt(h1/h0) : r0h; - scale_x = 1; - scale_y = preserve ? h1/h0 : (h1 - r1h)/(h0 - r0h); + scale_y = h1/h0; + scale_x = transform_stroke ? 1 : scale_y; + unbudge *= Geom::Translate (flip_x * 0.5 * (w1 - w0), 0); // compensate for the fact that this operation cannot be performed } else if ((fabs(h0 - r0h) < 1e-6) || h1 == 0) { // We have a horizontal line at hand - r1w = transform_stroke ? r0w * sqrt(w1/w0) : r0w; - scale_x = preserve ? w1/w0 : (w1 - r1w)/(w0 - r0w); - scale_y = 1; + scale_x = w1/w0; + scale_y = transform_stroke ? 1 : scale_x; + unbudge *= Geom::Translate (0, flip_y * 0.5 * (h1 - h0)); // compensate for the fact that this operation cannot be performed } else { // We have a true 2D object at hand if (transform_stroke && !preserve) { /* Initial area of the geometric bounding box: A0 = (w0-r0w)*(h0-r0h) -- cgit v1.2.3 From 77c9748e54f9170aac7c8b292377951f73da487f Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Mon, 20 Jan 2014 20:11:09 -0500 Subject: Fix imprecise viewBox dimensions on page size change (bug #1235279). Fixed bugs: - https://launchpad.net/bugs/1235279 (bzr r12965) --- src/document.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index e56adee68..8b956d5e7 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -585,6 +585,7 @@ Inkscape::Util::Quantity SPDocument::getWidth() const void SPDocument::setWidth(const Inkscape::Util::Quantity &width) { gdouble old_computed = root->width.computed; + gdouble old_value = root->width.value; root->width.computed = width.value("px"); /* SVG does not support meters as a unit, so we must translate meters to * cm when writing */ @@ -596,8 +597,14 @@ void SPDocument::setWidth(const Inkscape::Util::Quantity &width) root->width.unit = (SVGLength::Unit) width.unit->svgUnit(); } - if (root->viewBox_set) - root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.computed / old_computed) * root->viewBox.width(), root->viewBox.bottom())); + if (root->viewBox_set) { + if (abs(old_value - root->viewBox.width()) < 0.00001) { + root->viewBox.setMax(Geom::Point(root->viewBox.left() + root->width.value, root->viewBox.bottom())); + } + else { + root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.computed / old_computed) * root->viewBox.width(), root->viewBox.bottom())); + } + } root->updateRepr(); } @@ -622,6 +629,7 @@ Inkscape::Util::Quantity SPDocument::getHeight() const void SPDocument::setHeight(const Inkscape::Util::Quantity &height) { gdouble old_computed = root->height.computed; + gdouble old_value = root->height.value; root->height.computed = height.value("px"); /* SVG does not support meters as a unit, so we must translate meters to * cm when writing */ @@ -633,8 +641,14 @@ void SPDocument::setHeight(const Inkscape::Util::Quantity &height) root->height.unit = (SVGLength::Unit) height.unit->svgUnit(); } - if (root->viewBox_set) - root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.computed / old_computed) * root->viewBox.height())); + if (root->viewBox_set) { + if (abs(old_value - root->viewBox.height()) < 0.00001) { + root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + root->height.value)); + } + else { + root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.computed / old_computed) * root->viewBox.height())); + } + } root->updateRepr(); } -- cgit v1.2.3 From d94a93e813b9e4a30f82925670b30de93fc63d38 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Mon, 20 Jan 2014 20:36:09 -0500 Subject: Revert last commit (breaks changing document units). (bzr r12966) --- src/document.cpp | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 8b956d5e7..e56adee68 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -585,7 +585,6 @@ Inkscape::Util::Quantity SPDocument::getWidth() const void SPDocument::setWidth(const Inkscape::Util::Quantity &width) { gdouble old_computed = root->width.computed; - gdouble old_value = root->width.value; root->width.computed = width.value("px"); /* SVG does not support meters as a unit, so we must translate meters to * cm when writing */ @@ -597,14 +596,8 @@ void SPDocument::setWidth(const Inkscape::Util::Quantity &width) root->width.unit = (SVGLength::Unit) width.unit->svgUnit(); } - if (root->viewBox_set) { - if (abs(old_value - root->viewBox.width()) < 0.00001) { - root->viewBox.setMax(Geom::Point(root->viewBox.left() + root->width.value, root->viewBox.bottom())); - } - else { - root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.computed / old_computed) * root->viewBox.width(), root->viewBox.bottom())); - } - } + if (root->viewBox_set) + root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.computed / old_computed) * root->viewBox.width(), root->viewBox.bottom())); root->updateRepr(); } @@ -629,7 +622,6 @@ Inkscape::Util::Quantity SPDocument::getHeight() const void SPDocument::setHeight(const Inkscape::Util::Quantity &height) { gdouble old_computed = root->height.computed; - gdouble old_value = root->height.value; root->height.computed = height.value("px"); /* SVG does not support meters as a unit, so we must translate meters to * cm when writing */ @@ -641,14 +633,8 @@ void SPDocument::setHeight(const Inkscape::Util::Quantity &height) root->height.unit = (SVGLength::Unit) height.unit->svgUnit(); } - if (root->viewBox_set) { - if (abs(old_value - root->viewBox.height()) < 0.00001) { - root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + root->height.value)); - } - else { - root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.computed / old_computed) * root->viewBox.height())); - } - } + if (root->viewBox_set) + root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.computed / old_computed) * root->viewBox.height())); root->updateRepr(); } -- cgit v1.2.3 From 29e005620b05165ffd5ad21c2a9751adac89d34a Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 21 Jan 2014 10:21:10 -0500 Subject: Move dragging undo block from tools-base to canvas. Regarding bug #168695 (bzr r12967) --- src/display/sp-canvas.cpp | 5 +++++ src/display/sp-canvas.h | 1 + src/selection-chemistry.cpp | 5 +++-- src/ui/tools/tool-base.cpp | 7 ------- src/ui/tools/tool-base.h | 1 - 5 files changed, 9 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 455f628bc..ff58cf453 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1545,6 +1545,11 @@ int SPCanvasImpl::emitEvent(SPCanvas *canvas, GdkEvent *event) default: break; } + // Block Undo and Redo while we drag /anything/ + if(event->type == GDK_BUTTON_PRESS) + canvas->is_dragging = true; + else if(event->type == GDK_BUTTON_RELEASE) + canvas->is_dragging = false; // Choose where we send the event diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index b570b739e..72ae4b6bc 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -124,6 +124,7 @@ struct SPCanvas { SPCanvasItem *root; + bool is_dragging; double dx0; double dy0; int x0; diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 1957b9297..3082a2fe4 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -56,6 +56,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-polyline.h" #include "sp-line.h" #include "text-editing.h" +#include "display/sp-canvas.h" #include "ui/tools/text-tool.h" #include "ui/tools/connector-tool.h" #include "sp-path.h" @@ -1084,7 +1085,7 @@ void sp_undo(SPDesktop *desktop, SPDocument *) { // No re/undo while dragging, too dangerous. - if(desktop->getEventContext()->is_dragging) return; + if(desktop->getCanvas()->is_dragging) return; if (!DocumentUndo::undo(sp_desktop_document(desktop))) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing to undo.")); @@ -1095,7 +1096,7 @@ void sp_redo(SPDesktop *desktop, SPDocument *) { // No re/undo while dragging, too dangerous. - if(desktop->getEventContext()->is_dragging) return; + if(desktop->getCanvas()->is_dragging) return; if (!DocumentUndo::redo(sp_desktop_document(desktop))) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing to redo.")); diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 3b51147e0..cc028724a 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -98,7 +98,6 @@ ToolBase::ToolBase() { this->hot_x = 0; this->yp = 0; this->within_tolerance = false; - this->is_dragging = false; this->tolerance = 0; //this->key = 0; this->item_to_select = 0; @@ -979,14 +978,8 @@ gint sp_event_context_root_handler(ToolBase * event_context, gint sp_event_context_virtual_root_handler(ToolBase * event_context, GdkEvent * event) { gint ret = false; if (event_context) { - if(event->type == GDK_BUTTON_PRESS) - event_context->is_dragging = true; - ret = event_context->root_handler(event); set_event_location(event_context->desktop, event); - - if(event->type == GDK_BUTTON_RELEASE) - event_context->is_dragging = false; } return ret; } diff --git a/src/ui/tools/tool-base.h b/src/ui/tools/tool-base.h index ab8bd8caa..43edc4bd7 100644 --- a/src/ui/tools/tool-base.h +++ b/src/ui/tools/tool-base.h @@ -118,7 +118,6 @@ public: gint xp, yp; ///< where drag started gint tolerance; - bool is_dragging; // Is a tool currently dragging something bool within_tolerance; ///< are we still within tolerance of origin -- cgit v1.2.3 From 61737a54a16f2434f26b1ccfa5e1e082464d65c0 Mon Sep 17 00:00:00 2001 From: David Mathog Date: Wed, 22 Jan 2014 00:44:34 +0100 Subject: EMF export: fix handling of transformed rectangular gradients (bug #1263242) Fixed bugs: - https://launchpad.net/bugs/1263242 (bzr r12968) --- src/extension/internal/emf-print.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index 3c27ac1b8..2680718cf 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -814,10 +814,10 @@ Geom::Path PrintEmf::pathv_to_simple_polygon(Geom::PathVector const &pathv, int return(bad); } P1_lead = cit->finalPoint(); - if(Geom::are_near(P1_lead,P1))continue; // duplicate points at the same coordinate + if(Geom::are_near(P1_lead, P1, 1e-5))continue; // duplicate points at the same coordinate v1 = unit_vector(P1 - P1_trail); v2 = unit_vector(P1_lead - P1 ); - if(Geom::are_near(dot(v1,v2),1.0)){ // P1 is within a straight line + if(Geom::are_near(dot(v1,v2), 1.0, 1e-5)){ // P1 is within a straight line P1 = P1_lead; continue; } @@ -867,7 +867,7 @@ Geom::Path PrintEmf::pathv_to_rect(Geom::PathVector const &pathv, bool *is_rect, P1_lead = cit->finalPoint(); v1 = unit_vector(P1 - P1_trail); v2 = unit_vector(P1_lead - P1 ); - if(!Geom::are_near(dot(v1,v2),0.0))break; // P1 is center of a turn that is not 90 degrees + if(!Geom::are_near(dot(v1,v2), 0.0, 1e-5))break; // P1 is center of a turn that is not 90 degrees P1_trail = P1; P1 = P1_lead; vertex_count++; @@ -891,12 +891,12 @@ 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) - if( Geom::are_near(dot(v1,v2), 1.0)){ stat = 1; } - else if(Geom::are_near(dot(v1,v2),-1.0)){ stat = 2; } + 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)){ stat = 3; } - else if(Geom::are_near(dot(v1,v2),-1.0)){ stat = 4; } + 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; } } return(stat); } @@ -1091,7 +1091,6 @@ unsigned int PrintEmf::fill( U_TRIVERTEX ut[2]; U_GRADIENT4 ug4; U_RECTL rcb; - Geom::Affine tf2; U_XFORM tmpTransform; double wRect, hRect; @@ -1107,7 +1106,8 @@ unsigned int PrintEmf::fill( Actual gradientfill records are either this entire rectangle or slices of it as defined by the stops. */ - tf2 = Geom::Rotate(-angle); + Geom::Affine tf2 = Geom::Rotate(-angle); // the rectangle may be drawn skewed to the coordinate system + tf2 *= tf; // the coordinate system of the rectangular path may be rotated tmpTransform.eM11 = tf2[0]; tmpTransform.eM12 = tf2[1]; tmpTransform.eM21 = tf2[2]; -- cgit v1.2.3 From e01eb5907b04fdc194551741be6c6dbf5ee6f7e5 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 21 Jan 2014 22:20:23 -0500 Subject: Improve use tag logic by recording the loaded documents in a list. (bzr r12969) --- src/document.cpp | 1 + src/document.h | 5 +++++ src/uri-references.cpp | 39 +++++++++++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index e56adee68..32a025e87 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -106,6 +106,7 @@ SPDocument::SPDocument() : profileManager(0), // deferred until after other initialization router(new Avoid::Router(Avoid::PolyLineRouting|Avoid::OrthogonalRouting)), _collection_queue(0), + parent_document(NULL), oldSignalsConnected(false), current_persp3d(NULL), current_persp3d_impl(NULL) diff --git a/src/document.h b/src/document.h index cc565e3aa..e804a4980 100644 --- a/src/document.h +++ b/src/document.h @@ -25,6 +25,7 @@ #include "gc-finalized.h" #include "gc-anchored.h" #include +#include #include namespace Avoid { @@ -120,6 +121,10 @@ public: GSList *_collection_queue; + // A list of svg documents being used or shown within this document + boost::ptr_list child_documents; + SPDocument *parent_document; + bool oldSignalsConnected; /** Returns our SPRoot */ diff --git a/src/uri-references.cpp b/src/uri-references.cpp index 718b2d451..adf948c7b 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -58,17 +58,36 @@ void URIReference::attach(const URI &uri) throw(BadURIException) // The path contains references to seperate document files to load. const char *path = uri.getPath(); - if(path) { - if(document != NULL) { - // Calculate the absolute path from an available document - std::string basePath = std::string( document->getBase() ); - std::string absPath = Glib::build_filename(basePath, std::string( path ) ); - path = absPath.c_str(); + if(path && document != NULL) { + // Calculate the absolute path from an available document + std::string basePath = std::string( document->getBase() ); + std::string absPath = Glib::build_filename(basePath, std::string( path ) ); + path = absPath.c_str(); + + // We look at existing children and parents + SPDocument *parent = document; + SPDocument *original = document; + document = NULL; + + while(parent != NULL) { + boost::ptr_list::iterator iter; + for (iter = parent->child_documents.begin(); + iter != parent->child_documents.end(); ++iter) { + if(strcmp(iter->getURI(), path)==0) + document = &*iter; + } + parent = parent->parent_document; + } + // Load a fresh document from the svg source. + if(!document) { + document = SPDocument::createNewDoc(path, FALSE); + if(document) { + document->parent_document = original; + original->child_documents.push_back(document); + } else { + g_warning("Could not load svg file: %s", path); + } } - // TODO: This is inefficient because it will load the same svg file - // many times if it's used many times. A global list of documents would - // be useful for tracking linked items. - document = SPDocument::createNewDoc(path, FALSE); } g_return_if_fail(document != NULL); -- cgit v1.2.3 From 9a0c54cb8bc9b0bfc0c6af95f4b156fd717179a8 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 22 Jan 2014 14:58:15 -0500 Subject: Protect against infinate looping of new included hrefs (bzr r12970) --- src/document.cpp | 10 ++++++---- src/document.h | 8 +++++--- src/extension/implementation/xslt.cpp | 2 +- src/uri-references.cpp | 17 ++++++++++++----- 4 files changed, 24 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 32a025e87..90f35307d 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -315,7 +315,8 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, gchar const *uri, gchar const *base, gchar const *name, - unsigned int keepalive) + unsigned int keepalive, + SPDocument *parent) { SPDocument *document = new SPDocument(); @@ -326,6 +327,7 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, document->rdoc = rdoc; document->rroot = rroot; + document->parent_document = parent; if (document->uri){ g_free(document->uri); @@ -474,7 +476,7 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, * Fetches document from URI, or creates new, if NULL; public document * appears in document list. */ -SPDocument *SPDocument::createNewDoc(gchar const *uri, unsigned int keepalive, bool make_new) +SPDocument *SPDocument::createNewDoc(gchar const *uri, unsigned int keepalive, bool make_new, SPDocument *parent) { SPDocument *doc; Inkscape::XML::Document *rdoc; @@ -519,7 +521,7 @@ SPDocument *SPDocument::createNewDoc(gchar const *uri, unsigned int keepalive, b //# These should be set by now g_assert(name); - doc = createDoc(rdoc, uri, base, name, keepalive); + doc = createDoc(rdoc, uri, base, name, keepalive, parent); g_free(base); g_free(name); @@ -540,7 +542,7 @@ SPDocument *SPDocument::createNewDocFromMem(gchar const *buffer, gint length, un // TODO fixme: destroy document } else { Glib::ustring name = Glib::ustring::compose( _("Memory document %1"), ++doc_mem_count ); - doc = createDoc(rdoc, NULL, NULL, name.c_str(), keepalive); + doc = createDoc(rdoc, NULL, NULL, name.c_str(), keepalive, NULL); } } diff --git a/src/document.h b/src/document.h index e804a4980..06b2b5f6e 100644 --- a/src/document.h +++ b/src/document.h @@ -221,7 +221,8 @@ public: sigc::connection connectResourcesChanged(const gchar *key, SPDocument::ResourcesChangedSignal::slot_type slot); void fitToRect(Geom::Rect const &rect, bool with_margins = false); - static SPDocument *createNewDoc(const gchar *uri, unsigned int keepalive, bool make_new = false); + static SPDocument *createNewDoc(const gchar *uri, unsigned int keepalive, + bool make_new = false, SPDocument *parent=NULL ); static SPDocument *createNewDocFromMem(const gchar *buffer, gint length, unsigned int keepalive); /** @@ -229,8 +230,9 @@ public: */ static SPItem *getItemFromListAtPointBottom(unsigned int dkey, SPGroup *group, const GSList *list, Geom::Point const &p, bool take_insensitive = false); - // ToDo - Merge createDoc with createNewDoc - static SPDocument *createDoc(Inkscape::XML::Document *rdoc, gchar const *uri, gchar const *base, gchar const *name, unsigned int keepalive); + static SPDocument *createDoc(Inkscape::XML::Document *rdoc, gchar const *uri, + gchar const *base, gchar const *name, unsigned int keepalive, + SPDocument *parent); SPDocument *doRef(); SPDocument *doUnref(); diff --git a/src/extension/implementation/xslt.cpp b/src/extension/implementation/xslt.cpp index 9dd9c83ee..bcea06cb5 100644 --- a/src/extension/implementation/xslt.cpp +++ b/src/extension/implementation/xslt.cpp @@ -177,7 +177,7 @@ XSLT::open(Inkscape::Extension::Input */*module*/, gchar const *filename) } g_free(s); - SPDocument * doc = SPDocument::createDoc(rdoc, filename, base, name, true); + SPDocument * doc = SPDocument::createDoc(rdoc, filename, base, name, true, NULL); g_free(base); g_free(name); diff --git a/src/uri-references.cpp b/src/uri-references.cpp index adf948c7b..30e832c04 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -64,25 +64,32 @@ void URIReference::attach(const URI &uri) throw(BadURIException) std::string absPath = Glib::build_filename(basePath, std::string( path ) ); path = absPath.c_str(); - // We look at existing children and parents SPDocument *parent = document; SPDocument *original = document; document = NULL; - while(parent != NULL) { + while(parent != NULL && document == NULL) { + // Check myself and any parents int he chain + if(strcmp(parent->getURI(), path)==0) { + document = parent; + break; + } + // Then check children of those. boost::ptr_list::iterator iter; for (iter = parent->child_documents.begin(); iter != parent->child_documents.end(); ++iter) { - if(strcmp(iter->getURI(), path)==0) + if(strcmp(iter->getURI(), path)==0) { document = &*iter; + break; + } } parent = parent->parent_document; } + // Load a fresh document from the svg source. if(!document) { - document = SPDocument::createNewDoc(path, FALSE); + document = SPDocument::createNewDoc(path, false, false, original); if(document) { - document->parent_document = original; original->child_documents.push_back(document); } else { g_warning("Could not load svg file: %s", path); -- cgit v1.2.3 From 423ea7c0373e77a83c8a9ef62df9a786b4feb7ac Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 22 Jan 2014 17:58:40 -0500 Subject: Move sub-document reference creation code from uri-reference to document.cpp as createChildDoc(path) (bzr r12971) --- src/document.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++--- src/document.h | 10 ++++++---- src/uri-references.cpp | 37 +------------------------------------ 3 files changed, 51 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 90f35307d..f5c799575 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -106,10 +106,10 @@ SPDocument::SPDocument() : profileManager(0), // deferred until after other initialization router(new Avoid::Router(Avoid::PolyLineRouting|Avoid::OrthogonalRouting)), _collection_queue(0), - parent_document(NULL), oldSignalsConnected(false), current_persp3d(NULL), - current_persp3d_impl(NULL) + current_persp3d_impl(NULL), + _parent_document(NULL) { // Penalise libavoid for choosing paths with needless extra segments. // This results in much better looking orthogonal connector paths. @@ -327,7 +327,10 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, document->rdoc = rdoc; document->rroot = rroot; - document->parent_document = parent; + if (parent) { + document->_parent_document = parent; + parent->_child_documents.push_back(document); + } if (document->uri){ g_free(document->uri); @@ -472,6 +475,43 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, return document; } +/** + * Fetches a document and attaches it to the current document as a child href + */ +SPDocument *SPDocument::createChildDoc(gchar const *uri) { + + // Calculate the absolute path from an available document + std::string basePath = std::string( this->getBase() ); + std::string absPath = Glib::build_filename(basePath, std::string( uri ) ); + const char *path = absPath.c_str(); + + SPDocument *parent = this; + SPDocument *document = NULL; + + while(parent != NULL && document == NULL) { + // Check myself and any parents int he chain + if(strcmp(parent->getURI(), path)==0) { + document = parent; + break; + } + // Then check children of those. + boost::ptr_list::iterator iter; + for (iter = parent->_child_documents.begin(); + iter != parent->_child_documents.end(); ++iter) { + if(strcmp(iter->getURI(), path)==0) { + document = &*iter; + break; + } + } + parent = parent->_parent_document; + } + + // Load a fresh document from the svg source. + if(!document) { + document = createNewDoc(path, false, false, this); + } + return document; +} /** * Fetches document from URI, or creates new, if NULL; public document * appears in document list. @@ -605,6 +645,7 @@ void SPDocument::setWidth(const Inkscape::Util::Quantity &width) root->updateRepr(); } + Inkscape::Util::Quantity SPDocument::getHeight() const { g_return_val_if_fail(this->priv != NULL, Inkscape::Util::Quantity(0.0, unit_table.getUnit(""))); diff --git a/src/document.h b/src/document.h index 06b2b5f6e..79381e0c2 100644 --- a/src/document.h +++ b/src/document.h @@ -121,10 +121,6 @@ public: GSList *_collection_queue; - // A list of svg documents being used or shown within this document - boost::ptr_list child_documents; - SPDocument *parent_document; - bool oldSignalsConnected; /** Returns our SPRoot */ @@ -207,6 +203,11 @@ private: Persp3D *current_persp3d; /**< Currently 'active' perspective (to which, e.g., newly created boxes are attached) */ Persp3DImpl *current_persp3d_impl; + // A list of svg documents being used or shown within this document + boost::ptr_list _child_documents; + // Conversely this is a parent document because this is a child. + SPDocument *_parent_document; + public: sigc::connection connectReconstructionStart(ReconstructionStart::slot_type slot); sigc::connection connectReconstructionFinish(ReconstructionFinish::slot_type slot); @@ -224,6 +225,7 @@ public: static SPDocument *createNewDoc(const gchar *uri, unsigned int keepalive, bool make_new = false, SPDocument *parent=NULL ); static SPDocument *createNewDocFromMem(const gchar *buffer, gint length, unsigned int keepalive); + SPDocument *createChildDoc(gchar const *uri); /** * Returns the bottommost item from the list which is at the point, or NULL if none. diff --git a/src/uri-references.cpp b/src/uri-references.cpp index 30e832c04..1684c6ade 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -59,42 +59,7 @@ void URIReference::attach(const URI &uri) throw(BadURIException) // The path contains references to seperate document files to load. const char *path = uri.getPath(); if(path && document != NULL) { - // Calculate the absolute path from an available document - std::string basePath = std::string( document->getBase() ); - std::string absPath = Glib::build_filename(basePath, std::string( path ) ); - path = absPath.c_str(); - - SPDocument *parent = document; - SPDocument *original = document; - document = NULL; - - while(parent != NULL && document == NULL) { - // Check myself and any parents int he chain - if(strcmp(parent->getURI(), path)==0) { - document = parent; - break; - } - // Then check children of those. - boost::ptr_list::iterator iter; - for (iter = parent->child_documents.begin(); - iter != parent->child_documents.end(); ++iter) { - if(strcmp(iter->getURI(), path)==0) { - document = &*iter; - break; - } - } - parent = parent->parent_document; - } - - // Load a fresh document from the svg source. - if(!document) { - document = SPDocument::createNewDoc(path, false, false, original); - if(document) { - original->child_documents.push_back(document); - } else { - g_warning("Could not load svg file: %s", path); - } - } + document = document->createChildDoc(path); } g_return_if_fail(document != NULL); -- cgit v1.2.3 From ae7f7f7449a2da248ff13119e802a104de297c3d Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 22 Jan 2014 18:06:39 -0500 Subject: Improve warnings for missing files. Don't just assert bolocks to the user. (bzr r12972) --- src/uri-references.cpp | 5 ++++- src/xml/repr-io.cpp | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/uri-references.cpp b/src/uri-references.cpp index 1684c6ade..f2df55213 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -61,7 +61,10 @@ void URIReference::attach(const URI &uri) throw(BadURIException) if(path && document != NULL) { document = document->createChildDoc(path); } - g_return_if_fail(document != NULL); + if(!document) { + g_warning("Can't get document for referenced URI: %s", uri.toString()); + return; + } gchar const *fragment = uri.getFragment(); if ( !uri.isRelative() || uri.getQuery() || !fragment ) { diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index 54eff00bc..0319bb5e3 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -334,7 +334,10 @@ Document *sp_repr_read_file (const gchar * filename, const gchar *default_ns) xmlSubstituteEntitiesDefault(1); g_return_val_if_fail (filename != NULL, NULL); - g_return_val_if_fail (Inkscape::IO::file_test( filename, G_FILE_TEST_EXISTS ), NULL); + if (!Inkscape::IO::file_test( filename, G_FILE_TEST_EXISTS )) { + g_warning("Can't open file: %s (doesn't exist)", filename); + return NULL; + } /* fixme: A file can disappear at any time, including between now and when we actually try to * open it. Get rid of the above test once we're sure that we correctly handle * non-existence. */ -- cgit v1.2.3 From f30005bef81c2e1c5e04fe583935269c5b209749 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 22 Jan 2014 21:17:48 -0500 Subject: Don't throw away an existing full path. (bzr r12973) --- src/document.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index f5c799575..499601259 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -481,16 +481,19 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, SPDocument *SPDocument::createChildDoc(gchar const *uri) { // Calculate the absolute path from an available document - std::string basePath = std::string( this->getBase() ); - std::string absPath = Glib::build_filename(basePath, std::string( uri ) ); - const char *path = absPath.c_str(); + if(strncmp(uri, "/", 1)!=0) { + std::string basePath = std::string( this->getBase() ); + std::string absPath = Glib::build_filename(basePath, std::string( uri ) ); + // free uri first? + uri = absPath.c_str(); + } SPDocument *parent = this; SPDocument *document = NULL; while(parent != NULL && document == NULL) { // Check myself and any parents int he chain - if(strcmp(parent->getURI(), path)==0) { + if(strcmp(parent->getURI(), uri)==0) { document = parent; break; } @@ -498,7 +501,7 @@ SPDocument *SPDocument::createChildDoc(gchar const *uri) { boost::ptr_list::iterator iter; for (iter = parent->_child_documents.begin(); iter != parent->_child_documents.end(); ++iter) { - if(strcmp(iter->getURI(), path)==0) { + if(strcmp(iter->getURI(), uri)==0) { document = &*iter; break; } @@ -508,7 +511,7 @@ SPDocument *SPDocument::createChildDoc(gchar const *uri) { // Load a fresh document from the svg source. if(!document) { - document = createNewDoc(path, false, false, this); + document = createNewDoc(uri, false, false, this); } return document; } -- cgit v1.2.3 From 11ae816a74c061c219a4d833b58e6f940a53fff5 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 22 Jan 2014 22:21:57 -0500 Subject: Make sure we're not interfering with right or middle click with undo prevention bug #168695 (bzr r12974) --- 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 ff58cf453..d9640f763 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1546,7 +1546,7 @@ int SPCanvasImpl::emitEvent(SPCanvas *canvas, GdkEvent *event) break; } // Block Undo and Redo while we drag /anything/ - if(event->type == GDK_BUTTON_PRESS) + if(event->type == GDK_BUTTON_PRESS && event->button.button == 1) canvas->is_dragging = true; else if(event->type == GDK_BUTTON_RELEASE) canvas->is_dragging = false; -- cgit v1.2.3 From d9fbd1a23235bc8725574f61e156e0992ecc83bf Mon Sep 17 00:00:00 2001 From: su_v Date: Thu, 23 Jan 2014 22:12:22 +0100 Subject: Fix GTK3 build failure (follow-up to r12971) Fixed bugs: - https://launchpad.net/bugs/1271802 (bzr r12975) --- src/document.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 499601259..b7f5cb097 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -67,6 +67,8 @@ #include "xml/rebase-hrefs.h" #include "libcroco/cr-cascade.h" +#include + using Inkscape::DocumentUndo; using Inkscape::Util::unit_table; -- cgit v1.2.3 From ddb8af8009f151c7107daf0c2127f0ba2d882649 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 24 Jan 2014 20:05:26 -0500 Subject: Move absolute path generator to URI and use std::strings (bzr r12977) --- src/document.cpp | 21 ++++++--------------- src/document.h | 2 +- src/uri-references.cpp | 8 +++++--- src/uri.cpp | 13 +++++++++++++ src/uri.h | 3 +++ 5 files changed, 28 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index b7f5cb097..e456f2b81 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -67,8 +67,6 @@ #include "xml/rebase-hrefs.h" #include "libcroco/cr-cascade.h" -#include - using Inkscape::DocumentUndo; using Inkscape::Util::unit_table; @@ -480,22 +478,14 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, /** * Fetches a document and attaches it to the current document as a child href */ -SPDocument *SPDocument::createChildDoc(gchar const *uri) { - - // Calculate the absolute path from an available document - if(strncmp(uri, "/", 1)!=0) { - std::string basePath = std::string( this->getBase() ); - std::string absPath = Glib::build_filename(basePath, std::string( uri ) ); - // free uri first? - uri = absPath.c_str(); - } - +SPDocument *SPDocument::createChildDoc(std::string const uri) +{ SPDocument *parent = this; SPDocument *document = NULL; while(parent != NULL && document == NULL) { // Check myself and any parents int he chain - if(strcmp(parent->getURI(), uri)==0) { + if(uri.compare(parent->getURI())==0) { document = parent; break; } @@ -503,7 +493,7 @@ SPDocument *SPDocument::createChildDoc(gchar const *uri) { boost::ptr_list::iterator iter; for (iter = parent->_child_documents.begin(); iter != parent->_child_documents.end(); ++iter) { - if(strcmp(iter->getURI(), uri)==0) { + if(uri.compare(iter->getURI())==0) { document = &*iter; break; } @@ -513,7 +503,8 @@ SPDocument *SPDocument::createChildDoc(gchar const *uri) { // Load a fresh document from the svg source. if(!document) { - document = createNewDoc(uri, false, false, this); + const char *path = g_strdup(uri.c_str()); + document = createNewDoc(path, false, false, this); } return document; } diff --git a/src/document.h b/src/document.h index 79381e0c2..110db11c6 100644 --- a/src/document.h +++ b/src/document.h @@ -225,7 +225,7 @@ public: static SPDocument *createNewDoc(const gchar *uri, unsigned int keepalive, bool make_new = false, SPDocument *parent=NULL ); static SPDocument *createNewDocFromMem(const gchar *buffer, gint length, unsigned int keepalive); - SPDocument *createChildDoc(gchar const *uri); + SPDocument *createChildDoc(std::string const uri); /** * Returns the bottommost item from the list which is at the point, or NULL if none. diff --git a/src/uri-references.cpp b/src/uri-references.cpp index f2df55213..dc0101024 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -57,9 +57,11 @@ void URIReference::attach(const URI &uri) throw(BadURIException) } // The path contains references to seperate document files to load. - const char *path = uri.getPath(); - if(path && document != NULL) { - document = document->createChildDoc(path); + if(document && uri.getPath()) { + std::string base = std::string(g_strdup(document->getBase())); + std::string path = uri.getFullPath(base); + if(!path.empty()) + document = document->createChildDoc(path); } if(!document) { g_warning("Can't get document for referenced URI: %s", uri.toString()); diff --git a/src/uri.cpp b/src/uri.cpp index de6a454ec..8d0e49139 100644 --- a/src/uri.cpp +++ b/src/uri.cpp @@ -10,7 +10,9 @@ #include #include "uri.h" +#include #include +#include namespace Inkscape { @@ -134,6 +136,17 @@ gchar *URI::to_native_filename(gchar const* uri) throw(BadURIException) return filename; } +const std::string URI::getFullPath(std::string const base) const { + std::string path = std::string(_impl->getPath()); + // Calculate the absolute path from an available base + if(!path.empty() && !base.empty() && path.compare(0, 1, "/") != 0) { + path = Glib::build_filename(base, path); + } + // TODO: Check existance of file here + return path; +} + + /* TODO !!! proper error handling */ gchar *URI::toNativeFilename() const throw(BadURIException) { gchar *uriString = toString(); diff --git a/src/uri.h b/src/uri.h index adcc76d6b..74820cb29 100644 --- a/src/uri.h +++ b/src/uri.h @@ -15,6 +15,7 @@ #include #include #include "bad-uri-exception.h" +#include namespace Inkscape { @@ -101,6 +102,8 @@ public: static gchar *to_native_filename(gchar const* uri) throw(BadURIException); + const std::string getFullPath(std::string const base) const; + gchar *toNativeFilename() const throw(BadURIException); /** -- cgit v1.2.3 From 24b5b970fd4e6fadce881db84aa9f40bf81183d8 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 24 Jan 2014 20:05:47 -0500 Subject: A partial refactor of sp-image.cpp, expect more. (bzr r12978) --- src/sp-image.cpp | 89 +++++++++++++++++++++----------------------------------- src/sp-image.h | 5 ++++ 2 files changed, 38 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index b08d6f9b0..f1ea737ff 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -76,7 +76,6 @@ static void sp_image_set_curve(SPImage *image); -gchar const *sp_image_repr_read_filename(gchar const *href, gchar const *absref, gchar const *base ); static void sp_image_update_arenaitem (SPImage *img, Inkscape::DrawingImage *ai); static void sp_image_update_canvas_image (SPImage *image); @@ -170,8 +169,7 @@ void SPImage::release() { this->href = NULL; } - delete this->pixbuf; - this->pixbuf = NULL; + this->clear_image(); #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) if (this->color_profile) { @@ -329,29 +327,31 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { SPItem::update(ctx, flags); if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) { - delete this->pixbuf; - this->pixbuf = NULL; + this->clear_image(); if (this->href) { Inkscape::Pixbuf *pixbuf = NULL; + gchar const* uri = this->getRepr()->attribute("xlink:href"); + + if(!uri) { + g_warning("Image tag has no valid href: %s", this->getId()); - gchar const* filename = sp_image_repr_read_filename ( - this->getRepr()->attribute("xlink:href"), - this->getRepr()->attribute("sodipodi:absref"), - doc->getBase()); - - Inkscape::Pixbuf::create_from_data_uri(filename); - if (strncmp (filename,"data:", 5) == 0) { - filename += 5; - pixbuf = Inkscape::Pixbuf::create_from_data_uri(filename); - } else if(filename && g_str_has_suffix(filename, ".svg")) { - // TODO: We want to deal with svg images properly. This - // space allows us to do so later. - g_warning("Including svg images tags is not yet supported."); - } else if (filename) { - pixbuf = Inkscape::Pixbuf::create_from_file(filename); + } else if (strncmp (uri, "data:", 5) == 0) { + uri += 5; + pixbuf = Inkscape::Pixbuf::create_from_data_uri(uri); + + } else if(g_str_has_suffix(uri, ".svg")) { + SPDocument *doc = this->document->createChildDoc(uri); + if(doc) { + this->child = SP_ITEM(doc); + g_warning("Loaded document: %s", uri); + } else { + g_warning("Could not load svg for image tag: %s",this->getId()); + } + } else { + pixbuf = Inkscape::Pixbuf::create_from_file(uri); } - if(!pixbuf) { + if(!pixbuf && !this->child) { /* Nope: We do not find any valid pixmap file :-( */ pixbuf = new Inkscape::Pixbuf( gdk_pixbuf_new_from_xpm_data((const gchar **) brokenimage_xpm)); @@ -527,6 +527,18 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { sp_image_update_canvas_image ((SPImage *) this); } +// Remove references to image or child objects. +void SPImage::clear_image() { + if(this->pixbuf) { + delete this->pixbuf; + this->pixbuf = NULL; + } + if(this->child) { + this->detach(this->child); + this->child = NULL; + } +} + void SPImage::modified(unsigned int flags) { // SPItem::onModified(flags); @@ -667,41 +679,6 @@ Inkscape::DrawingItem* SPImage::show(Inkscape::Drawing &drawing, unsigned int /* return ai; } -gchar const *sp_image_repr_read_filename(gchar const *href, gchar const *absref, gchar const *base) -{ - gchar const *filename = href; - - if (filename != NULL) { - if (strncmp (filename,"file:",5) == 0) { - filename = g_filename_from_uri(filename, NULL, NULL); - } else if (strncmp (filename,"data:",5) == 0) { - /* data URI - embedded image */ - return filename; - } else if (!g_path_is_absolute (filename)) { - /* try to load from relative pos combined with document base*/ - const gchar *docbase = base; - if (!docbase) docbase = "."; - filename = g_build_filename(docbase, filename, NULL); - } - } - - if (filename && g_file_test(filename, G_FILE_TEST_EXISTS) ) { - return filename; - } - - /* at last try to load from sp absolute path name */ - if (absref != NULL && g_file_test(absref, G_FILE_TEST_EXISTS)) { - // using absref is outside of SVG rules, so we must at least warn the user - if ( base != NULL && href != NULL ) { - g_warning (" did not resolve to a valid image file (base dir is %s), now trying sodipodi:absref=\"%s\"", href, base, absref); - } else { - g_warning ("xlink:href did not resolve to a valid image file, now trying sodipodi:absref=\"%s\"", absref); - } - return absref; - } - return NULL; -} - /* We assert that realpixbuf is either NULL or identical size to pixbuf */ static void sp_image_update_arenaitem (SPImage *image, Inkscape::DrawingImage *ai) diff --git a/src/sp-image.h b/src/sp-image.h index 3b7208487..ad4fd4d54 100644 --- a/src/sp-image.h +++ b/src/sp-image.h @@ -53,7 +53,10 @@ public: gchar *color_profile; #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + // When image is a raster image, we use pixbuf Inkscape::Pixbuf *pixbuf; + // When it's an svg file, we use an SPItem similar to sp-use + SPItem *child; virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); @@ -69,6 +72,8 @@ public: virtual Inkscape::DrawingItem* show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; virtual Geom::Affine set_transform(Geom::Affine const &transform); +private: + void clear_image(); }; /* Return duplicate of curve or NULL */ -- cgit v1.2.3 From 7455f1a259ce28ee56866b5cde06e79be4cfaf97 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sun, 26 Jan 2014 12:19:47 -0500 Subject: Check file existance and clean up memory issues thanks to KK and Johan (bzr r12979) --- src/document.cpp | 10 +++++----- src/document.h | 2 +- src/uri-references.cpp | 4 +++- src/uri.cpp | 17 ++++++++++++++--- 4 files changed, 23 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index e456f2b81..634462001 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -478,22 +478,22 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, /** * Fetches a document and attaches it to the current document as a child href */ -SPDocument *SPDocument::createChildDoc(std::string const uri) +SPDocument *SPDocument::createChildDoc(std::string const &uri) { SPDocument *parent = this; SPDocument *document = NULL; while(parent != NULL && document == NULL) { // Check myself and any parents int he chain - if(uri.compare(parent->getURI())==0) { + if(uri == parent->getURI()) { document = parent; break; } // Then check children of those. boost::ptr_list::iterator iter; for (iter = parent->_child_documents.begin(); - iter != parent->_child_documents.end(); ++iter) { - if(uri.compare(iter->getURI())==0) { + iter != parent->_child_documents.end(); ++iter) { + if(uri == iter->getURI()) { document = &*iter; break; } @@ -503,7 +503,7 @@ SPDocument *SPDocument::createChildDoc(std::string const uri) // Load a fresh document from the svg source. if(!document) { - const char *path = g_strdup(uri.c_str()); + const char *path = uri.c_str(); document = createNewDoc(path, false, false, this); } return document; diff --git a/src/document.h b/src/document.h index 110db11c6..e5567d3b6 100644 --- a/src/document.h +++ b/src/document.h @@ -225,7 +225,7 @@ public: static SPDocument *createNewDoc(const gchar *uri, unsigned int keepalive, bool make_new = false, SPDocument *parent=NULL ); static SPDocument *createNewDocFromMem(const gchar *buffer, gint length, unsigned int keepalive); - SPDocument *createChildDoc(std::string const uri); + SPDocument *createChildDoc(std::string const &uri); /** * Returns the bottommost item from the list which is at the point, or NULL if none. diff --git a/src/uri-references.cpp b/src/uri-references.cpp index dc0101024..abe16ec9d 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -58,10 +58,12 @@ void URIReference::attach(const URI &uri) throw(BadURIException) // The path contains references to seperate document files to load. if(document && uri.getPath()) { - std::string base = std::string(g_strdup(document->getBase())); + std::string base = std::string(document->getBase()); std::string path = uri.getFullPath(base); if(!path.empty()) document = document->createChildDoc(path); + else + document = NULL; } if(!document) { g_warning("Can't get document for referenced URI: %s", uri.toString()); diff --git a/src/uri.cpp b/src/uri.cpp index 8d0e49139..89f6f33e4 100644 --- a/src/uri.cpp +++ b/src/uri.cpp @@ -135,14 +135,25 @@ gchar *URI::to_native_filename(gchar const* uri) throw(BadURIException) filename = tmp.toNativeFilename(); return filename; } - +/* + * Returns the absolute path to an existing file referenced in this URI, + * if the uri is data, the path is empty or the file doesn't exist, then + * an empty string is returned. + * + * 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 { std::string path = std::string(_impl->getPath()); // Calculate the absolute path from an available base - if(!path.empty() && !base.empty() && path.compare(0, 1, "/") != 0) { + if(!base.empty() && !path.empty() && path[0] != '/') { path = Glib::build_filename(base, path); } - // TODO: Check existance of file here + // Check the existance of the file + if(! g_file_test(path.c_str(), G_FILE_TEST_EXISTS) + || g_file_test(path.c_str(), G_FILE_TEST_IS_DIR) ) { + path.clear(); + } return path; } -- cgit v1.2.3 From 99a8b0ae7da4f776f7ec85862ab52c29a4abb164 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Sun, 26 Jan 2014 15:09:05 -0500 Subject: sbasis-to-bezier : add support for case where Bezier control arm length is zero (Bug 1272119) Fixed bugs: - https://launchpad.net/bugs/1272119 (bzr r12980) --- src/2geom/sbasis-to-bezier.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/2geom/sbasis-to-bezier.cpp b/src/2geom/sbasis-to-bezier.cpp index bd88f93c0..0525be04b 100644 --- a/src/2geom/sbasis-to-bezier.cpp +++ b/src/2geom/sbasis-to-bezier.cpp @@ -242,24 +242,38 @@ void sbasis_to_cubic_bezier (std::vector & bz, D2 const& sb) // calculate Bezier control arms - if (std::abs(xprime[1]*yprime[0] - yprime[1]*xprime[0]) > 1.e-5) { // general case : fit mid fxn value + if ((std::abs(xprime[0]) < EPSILON) && (std::abs(yprime[0]) < EPSILON) + && ((std::abs(xprime[1]) > EPSILON) || (std::abs(yprime[1]) > EPSILON))) { // degenerate handle at 0 : use distance of closest approach + numer = midx*xprime[1] + midy*yprime[1]; + denom = 3.0*(xprime[1]*xprime[1] + yprime[1]*yprime[1]); + delx[0] = 0; + dely[0] = 0; + delx[1] = -xprime[1]*numer/denom; + dely[1] = -yprime[1]*numer/denom; + } else if ((std::abs(xprime[1]) < EPSILON) && (std::abs(yprime[1]) < EPSILON) + && ((std::abs(xprime[0]) > EPSILON) || (std::abs(yprime[0]) > EPSILON))) { // degenerate handle at 1 : ditto + numer = midx*xprime[0] + midy*yprime[0]; + denom = 3.0*(xprime[0]*xprime[0] + yprime[0]*yprime[0]); + delx[0] = xprime[0]*numer/denom; + dely[0] = yprime[0]*numer/denom; + delx[1] = 0; + dely[1] = 0; + } else if (std::abs(xprime[1]*yprime[0] - yprime[1]*xprime[0]) > EPSILON) { // general case : fit mid fxn value denom = xprime[1]*yprime[0] - yprime[1]*xprime[0]; for (int i = 0; i < 2; ++i) { numer = xprime[1 - i]*midy - yprime[1 - i]*midx; delx[i] = xprime[i]*numer/denom/3; dely[i] = yprime[i]*numer/denom/3; } - } - else if ((xprime[0]*xprime[1] < 0) || (yprime[0]*yprime[1] < 0)) { // symmetric case : use distance of closest approach + } else if ((xprime[0]*xprime[1] < 0) || (yprime[0]*yprime[1] < 0)) { // symmetric case : use distance of closest approach numer = midx*xprime[0] + midy*yprime[0]; denom = 6.0*(xprime[0]*xprime[0] + yprime[0]*yprime[0]); delx[0] = xprime[0]*numer/denom; dely[0] = yprime[0]*numer/denom; delx[1] = -delx[0]; dely[1] = -dely[0]; - } - else { // anti-symmetric case : fit mid slope - // calculate slope at t = 0.5 + } else { // anti-symmetric case : fit mid slope + // calculate slope at t = 0.5 midx = 0; div = 1; for (size_t i = 0; i < sb[X].size(); ++i) { @@ -279,8 +293,7 @@ void sbasis_to_cubic_bezier (std::vector & bz, D2 const& sb) delx[i] = xprime[0]*numer/denom; dely[i] = yprime[0]*numer/denom; } - } - else { // linear case + } else { // linear case for (int i = 0; i < 2; ++i) { delx[i] = (bz[3][X] - bz[0][X])/3; dely[i] = (bz[3][Y] - bz[0][Y])/3; -- cgit v1.2.3 From 8da52916bd86c3c19749b3062dcdbda63de3b554 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Mon, 27 Jan 2014 08:11:24 -0500 Subject: Protect export options from blank filenames, png, pdf, emf and wmf. This should fix Bug #941103 Fixed bugs: - https://launchpad.net/bugs/941103 (bzr r12981) --- src/main.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 079944af6..868f389a8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1515,7 +1515,7 @@ static int sp_do_export_png(SPDocument *doc) // set filename and dpi from options, if not yet set from the hints if (filename.empty()) { - if (!sp_export_png) { + if (!sp_export_png || sp_export_png[0] == '\0') { g_warning ("No export filename given and no filename hint. Nothing exported."); return 1; } @@ -1771,6 +1771,11 @@ static int do_export_ps_pdf(SPDocument* doc, gchar const* uri, char const* mime) } } + if(!uri || uri[0] == '\0') { + g_warning ("No export filename given. Nothing exported."); + return 0; + } + //check if specified directory exists if (!Inkscape::IO::file_directory_exists(uri)) { g_warning("File path \"%s\" includes directory that doesn't exist.\n", uri); @@ -1837,6 +1842,10 @@ static int do_export_win_metafile_common(SPDocument* doc, gchar const* uri, char static int do_export_emf(SPDocument* doc, gchar const* uri, char const* mime) { + if(!uri || uri[0] == '\0') { + g_warning("No filename provided for emf export."); + return 0; + } return do_export_win_metafile_common(doc, uri, mime); } @@ -1850,6 +1859,10 @@ static int do_export_emf(SPDocument* doc, gchar const* uri, char const* mime) static int do_export_wmf(SPDocument* doc, gchar const* uri, char const* mime) { + if(!uri || uri[0] == '\0') { + g_warning("No filename provided for wmf export."); + return 0; + } return do_export_win_metafile_common(doc, uri, mime); } -- cgit v1.2.3 From fd1ceb05805f20402606fd9fae1a048e0bca8e78 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Mon, 27 Jan 2014 13:19:30 -0500 Subject: Protect pdf and png exports from failure and output reasonalbe warnings. (bzr r12982) --- src/helper/png-write.cpp | 2 +- src/main.cpp | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/helper/png-write.cpp b/src/helper/png-write.cpp index b8b815b4c..a16fe8e12 100644 --- a/src/helper/png-write.cpp +++ b/src/helper/png-write.cpp @@ -142,7 +142,7 @@ sp_png_write_rgba_striped(SPDocument *doc, Inkscape::IO::dump_fopen_call(filename, "M"); fp = Inkscape::IO::fopen_utf8name(filename, "wb"); - g_return_val_if_fail(fp != NULL, false); + if(fp == NULL) return false; /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, diff --git a/src/main.cpp b/src/main.cpp index 868f389a8..25f813c2b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1632,10 +1632,13 @@ static int sp_do_export_png(SPDocument *doc) g_print("Area %g:%g:%g:%g exported to %lu x %lu pixels (%g dpi)\n", area[Geom::X][0], area[Geom::Y][0], area[Geom::X][1], area[Geom::Y][1], width, height, dpi); - g_print("Bitmap saved as: %s\n", filename.c_str()); - if ((width >= 1) && (height >= 1) && (width <= PNG_UINT_31_MAX) && (height <= PNG_UINT_31_MAX)) { - sp_export_png_file(doc, path.c_str(), area, width, height, dpi, dpi, bgcolor, NULL, NULL, true, sp_export_id_only ? items : NULL); + if( sp_export_png_file(doc, path.c_str(), area, width, height, dpi, + dpi, bgcolor, NULL, NULL, true, sp_export_id_only ? items : NULL) == 1 ) { + g_print("Bitmap saved as: %s\n", filename.c_str()); + } else { + g_warning("Bitmap failed to save to: %s", filename.c_str()); + } } else { g_warning("Calculated bitmap dimensions %lu %lu are out of range (1 - %lu). Nothing exported.", width, height, (unsigned long int)PNG_UINT_31_MAX); } @@ -1794,7 +1797,11 @@ static int do_export_ps_pdf(SPDocument* doc, gchar const* uri, char const* mime) ? "PostScript level 3" : "PostScript level 2"); } - (*i)->save(doc, uri); + try { + (*i)->save(doc, uri); + } catch(...) { + g_warning("Failed to save pdf to: %s", uri); + } return 0; } -- cgit v1.2.3